我以前使用CShell(csh),它允许你创建一个带参数的别名.符号是这样的
alias junk="mv \\!* ~/.Trash"
Run Code Online (Sandbox Code Playgroud)
在Bash中,这似乎不起作用.鉴于Bash有许多有用的功能,我会假设这个功能已经实现,但我想知道如何.
aru*_*mar 1973
Bash别名不直接接受参数.您必须创建一个函数和别名.
alias
不接受参数,但函数可以像别名一样调用.例如:
myfunction() {
#do things with parameters like $1 such as
mv "$1" "$1.bak"
cp "$2" "$1"
}
myfunction old.conf new.conf #calls `myfunction`
Run Code Online (Sandbox Code Playgroud)
顺便说一句,您.bashrc
和其他文件中定义的Bash函数可作为shell中的命令使用.因此,例如,您可以像这样调用早期的函数
$ myfunction original.conf my.conf
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 196
改进上面的答案,您可以像使用别名一样获得单行语法,这对于shell或.bashrc文件中的ad-hoc定义更方便:
bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }
bash$ myfunction original.conf my.conf
Run Code Online (Sandbox Code Playgroud)
不要忘记关闭右括号前的分号.同样,对于实际问题:
csh% alias junk="mv \\!* ~/.Trash"
bash$ junk() { mv "$@" ~/.Trash/; }
Run Code Online (Sandbox Code Playgroud)
要么:
bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }
Run Code Online (Sandbox Code Playgroud)
Eva*_*ois 110
这个问题简直被问到了错误.您不创建带参数的别名,因为alias
只为已存在的内容添加第二个名称.OP想要的功能是function
创建新功能的命令.您不需要为函数设置别名,因为函数已有名称.
我想你想要这样的东西:
function trash() { mv "$@" ~/.Trash; }
Run Code Online (Sandbox Code Playgroud)
而已!您可以使用参数$ 1,$ 2,$ 3等,或者只需将它们全部填入$ @
Tom*_*ale 97
使用函数比使用别名将参数放在命令中间更容易,更易读.
$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after
Run Code Online (Sandbox Code Playgroud)
如果您继续阅读,您将学习关于shell参数处理不需要了解的内容.知识很危险.只要得到你想要的结果,在黑暗面永远控制你的命运之前.
bash
别名确实接受参数,但仅限于结尾:
$ alias speak=echo
$ speak hello world
hello world
Run Code Online (Sandbox Code Playgroud)
将参数置于命令通过的中间alias
确实是可能的,但它变得丑陋.
如果您喜欢规避限制并做其他人认为不可能的事情,那么这就是配方.如果你的头发被弄得疲惫不堪,你的脸最终会被煤烟疯狂科学家风格覆盖,请不要怪我.
解决方法是将alias
仅在最后接受的参数传递给将在中间插入它们然后执行命令的包装器.
如果你真的反对使用函数本身,你可以使用:
$ alias wrap_args='f(){ echo before "$@" after; unset -f f; }; f'
$ wrap_args x y z
before x y z after
Run Code Online (Sandbox Code Playgroud)
如果您只想要第一个参数$@
,$1
则可以替换为.
解释1
这会创建一个临时函数f
,它传递参数(注意f
在最后调用).在unset -f
执行别名时删除函数定义,以便之后不会挂起.
您还可以使用子shell:
$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'
Run Code Online (Sandbox Code Playgroud)
解释2
别名构建如下命令:
sh -c 'echo before "$@" after' _
Run Code Online (Sandbox Code Playgroud)
评论:
占位符_
是必需的,但它可以是任何东西.它被设置为sh
's $0
,并且是必需的,以便第一个用户给定的参数不被消耗.示范:
sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
Consumed: alcohol Printing: drunken babble
Run Code Online (Sandbox Code Playgroud)单引号内的单引号是必需的.这是一个不使用双引号的例子:
$ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
Consumed: -bash Printing:
Run Code Online (Sandbox Code Playgroud)
这里的交互shell的值$0
和$@
被替换成引述双前,它被传递给sh
.这是证据:
echo "Consumed: $0 Printing: $@"
Consumed: -bash Printing:
Run Code Online (Sandbox Code Playgroud)
单引号确保这些变量不被交互式shell解释,并按字面顺序传递给sh -c
.
您可以使用双引号\$@
,但最佳做法是引用您的参数(因为它们可能包含空格),\"\$@\"
看起来更加丑陋,但可能会帮助您赢得混淆比赛,其中疲惫的头发是进入的先决条件.
Iva*_*van 26
一旦我做了一些有趣的项目,我仍然在使用它。当我通过cp
命令复制文件时,它显示了一些动画,cp
因为没有显示任何内容,这有点令人沮丧。所以我做了这个别名
alias cp="~/SCR/spiner cp"
Run Code Online (Sandbox Code Playgroud)
这是微调脚本
#!/bin/bash
#Set timer
T=$(date +%s)
#Add some color
. ~/SCR/color
#Animation sprites
sprite=( "(* ) ( *)" " (* )( *) " " ( *)(* ) " "( *) (* )" "(* ) ( *)" )
#Print empty line and hide cursor
printf "\n${COF}"
#Exit function
function bye { printf "${CON}"; [ -e /proc/$pid ] && kill -9 $pid; exit; }; trap bye INT
#Run our command and get its pid
"$@" & pid=$!
#Waiting animation
i=0; while [ -e /proc/$pid ]; do sleep 0.1
printf "\r${GRN}Please wait... ${YLW}${sprite[$i]}${DEF}"
((i++)); [[ $i = ${#sprite[@]} ]] && i=0
done
#Print time and exit
T=$(($(date +%s)-$T))
printf "\n\nTime taken: $(date -u -d @${T} +'%T')\n"
bye
Run Code Online (Sandbox Code Playgroud)
它看起来像这样
循环动画)
这是上面提到的颜色脚本的链接。和新的动画循环)
Bil*_*leh 17
Bash 别名绝对接受参数。我刚刚添加了一个别名来创建一个新的 React 应用程序,它接受应用程序名称作为参数。这是我的过程:
在 nano 中打开 bash_profile 进行编辑
nano /.bash_profile
Run Code Online (Sandbox Code Playgroud)
添加别名,每行一个:
alias gita='git add .'
alias gitc='git commit -m "$@"'
alias gitpom='git push origin master'
alias creact='npx create-react-app "$@"'
Run Code Online (Sandbox Code Playgroud)
注意:“$@”接受传入的参数,如“creact my-new-app”
保存并退出纳米编辑器
ctrl+o 写入(按回车键);ctrl+x 退出
告诉终端使用 .bash_profile 中的新别名
source /.bash_profile
Run Code Online (Sandbox Code Playgroud)
就是这样!您现在可以使用新别名
小智 13
尊重所有那些说你不能在别名中间插入参数的人,我刚刚测试了它并发现它确实有效。
alias mycommand = "python3 "$1" script.py --folderoutput RESULTS/"
Run Code Online (Sandbox Code Playgroud)
然后,当我运行 mycommand foobar 时,它的工作方式与我手写命令时完全一样。
ali*_*ind 10
以下是我在我的函数中的三个示例~/.bashrc
,它们实际上是接受参数的别名:
#Utility required by all below functions.
#https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"
Run Code Online (Sandbox Code Playgroud)
.
:<<COMMENT
Alias function for recursive deletion, with are-you-sure prompt.
Example:
srf /home/myusername/django_files/rest_tutorial/rest_venv/
Parameter is required, and must be at least one non-whitespace character.
Short description: Stored in SRF_DESC
With the following setting, this is *not* added to the history:
export HISTIGNORE="*rm -r*:srf *"
- https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
See:
- y/n prompt: https://stackoverflow.com/a/3232082/2736496
- Alias w/param: https://stackoverflow.com/a/7131683/2736496
COMMENT
#SRF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
SRF_DESC="srf [path]: Recursive deletion, with y/n prompt\n"
srf() {
#Exit if no parameter is provided (if it's the empty string)
param=$(echo "$1" | trim)
echo "$param"
if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html
then
echo "Required parameter missing. Cancelled"; return
fi
#Actual line-breaks required in order to expand the variable.
#- https://stackoverflow.com/a/4296147/2736496
read -r -p "About to
sudo rm -rf \"$param\"
Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y)$ ]]
then
sudo rm -rf "$param"
else
echo "Cancelled."
fi
}
Run Code Online (Sandbox Code Playgroud)
.
:<<COMMENT
Delete item from history based on its line number. No prompt.
Short description: Stored in HX_DESC
Examples
hx 112
hx 3
See:
- https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HX_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HX_DESC="hx [linenum]: Delete history item at line number\n"
hx() {
history -d "$1"
}
Run Code Online (Sandbox Code Playgroud)
.
:<<COMMENT
Deletes all lines from the history that match a search string, with a
prompt. The history file is then reloaded into memory.
Short description: Stored in HXF_DESC
Examples
hxf "rm -rf"
hxf ^source
Parameter is required, and must be at least one non-whitespace character.
With the following setting, this is *not* added to the history:
export HISTIGNORE="*hxf *"
- https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
See:
- https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HXF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HXF_DESC="hxf [searchterm]: Delete all history items matching search term, with y/n prompt\n"
hxf() {
#Exit if no parameter is provided (if it's the empty string)
param=$(echo "$1" | trim)
echo "$param"
if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html
then
echo "Required parameter missing. Cancelled"; return
fi
read -r -p "About to delete all items from history that match \"$param\". Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y)$ ]]
then
#Delete all matched items from the file, and duplicate it to a temp
#location.
grep -v "$param" "$HISTFILE" > /tmp/history
#Clear all items in the current sessions history (in memory). This
#empties out $HISTFILE.
history -c
#Overwrite the actual history file with the temp one.
mv /tmp/history "$HISTFILE"
#Now reload it.
history -r "$HISTFILE" #Alternative: exec bash
else
echo "Cancelled."
fi
}
Run Code Online (Sandbox Code Playgroud)
参考文献:
您要做的就是在别名中创建一个函数:
$ alias mkcd='function _mkcd(){mkdir "$1"; cd "$1"}; _mkcd'
Run Code Online (Sandbox Code Playgroud)
您必须在“ $ 1”周围加上双引号,因为单引号将不起作用。
我将发布我的(希望是好的)解决方案(对于未来的读者,最重要的是编辑)。
所以 - 请编辑和改进/删除这篇文章中的任何内容。
在终端中:
$ alias <name_of_your_alias>_$argname="<command> $argname"
Run Code Online (Sandbox Code Playgroud)
并使用它(注意“_”后面的空格:
$<name_of_your_alias>_ $argname
Run Code Online (Sandbox Code Playgroud)
例如,名为以下cat
文件的别名hello.txt
:
CAT_FILE_
)$f
(是$argname
,在本例中是一个文件)$ alias CAT_FILE_$f="cat $f"
$ echo " " >> hello.txt
$ echo "hello there!" >> hello.txt
$ echo " " >> hello.txt
$ cat hello.txt
hello there!
Run Code Online (Sandbox Code Playgroud)
测试(注意“_”后面的空格):
CAT_FILE_ hello.txt
Run Code Online (Sandbox Code Playgroud)
注意:如果想法不明显,除了别名之外的任何东西都使用别名是个坏主意,第一个是"别名中的函数",第二个是"难以读取的重定向/源".此外,还有一些缺陷(我认为这很明显,但万一你会感到困惑:我并不是说它们实际上被用到了......任何地方!)
.................................................. .................................................. ............................................
我之前已经回答了这个问题,过去一直如此:
alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'
Run Code Online (Sandbox Code Playgroud)
这是好的和好的,除非你一直避免使用功能.在这种情况下,您可以利用bash的重定向文本的巨大能力:
alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'
Run Code Online (Sandbox Code Playgroud)
它们的长度大约相同或者取一些字符.
的真正起脚的时间差,顶部作为"函数法"和底部作为"重定向源"的方法.为证明这一理论,时机不言而喻:
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.004s sys 0m0.008s # <--time spent in foo
real 0m0.000s user 0m0.000s sys 0m0.000s # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.000s sys 0m0.012s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.012s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.008s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
Run Code Online (Sandbox Code Playgroud)
这是大约200个结果的底部,以随机间隔完成.似乎函数创建/销毁比重定向花费更多时间.希望这将有助于未来的访问者提出这个问题(不想保留给自己).
如果您正在寻找一种将所有参数应用于一个函数的通用方法,而不仅仅是一个或两个或一些其他硬编码量,则可以通过以下方式实现:
#!/usr/bin/env bash
# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
java -jar myjar.jar "$@";
}
alias runjar=runjar_fn;
Run Code Online (Sandbox Code Playgroud)
因此,在上面的示例中,我将运行时的所有参数传递runjar
给别名。
例如,如果我这样做runjar hi there
,它将最终真正运行java -jar myjar.jar hi there
。如果我这样做runjar one two three
,它将运行java -jar myjar.jar one two three
。
我喜欢这种$@
基于解决方案的方法,因为它适用于任意数量的参数。
有合法的技术原因需要一个通用的解决方案来解决 bash 别名没有采取重新定位任意参数的机制的问题。一个原因是,如果您希望执行的命令会因执行函数而导致的环境变化受到不利影响。在所有其他情况下,应使用函数。
最近促使我尝试解决此问题的原因是我想创建一些用于打印变量和函数定义的缩写命令。所以我为此编写了一些函数。但是,某些变量会(或可能会)被函数调用本身改变。其中有:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
我一直在使用(在函数中)打印变量 defns 的基本命令。在 set 命令输出的表单中是:
sv () { set | grep --color=never -- "^$1=.*"; }
Run Code Online (Sandbox Code Playgroud)
例如:
> V=voodoo
sv V
V=voodoo
Run Code Online (Sandbox Code Playgroud)
问题:这不会打印上述变量的定义,因为它们在当前上下文中,例如,如果在交互式 shell 提示中(或不在任何函数调用中),则未定义 FUNCNAME。但是我的函数告诉我错误的信息:
> sv FUNCNAME
FUNCNAME=([0]="sv")
Run Code Online (Sandbox Code Playgroud)
我想出的一个解决方案已被其他人在有关此主题的其他帖子中提到。对于这个打印变量 defns. 的特定命令,它只需要一个参数,我这样做了:
alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'
Run Code Online (Sandbox Code Playgroud)
这给出了正确的输出(无)和结果状态(假):
> asv FUNCNAME
> echo $?
1
Run Code Online (Sandbox Code Playgroud)
但是,我仍然觉得有必要找到一种适用于任意数量参数的解决方案。
将任意参数传递给 Bash 别名命令的通用解决方案:
# (I put this code in a file "alias-arg.sh"):
# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }
# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
# Set up cmd to be execed after f() finishes:
#
trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# (^This is the actually execed command^)
#
# f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
f () {
declare -ag CMD_ARGV=("$@"); # array to give args to cmd
kill -SIGUSR1 $$; # this causes cmd to be run
trap SIGUSR1; # unset the trap for SIGUSR1
unset CMD_ARGV; # clean up env...
unset f; # incl. this function!
};
f' # Finally, exec f, which will receive the args following "ac2".
Run Code Online (Sandbox Code Playgroud)
例如:
> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true
Run Code Online (Sandbox Code Playgroud)
这个解决方案的一个好处是,用于处理命令的位置参数(参数)的所有特殊技巧在编写被捕获的命令时都将起作用。唯一的区别是必须使用数组语法。
例如,
如果您想要“$@”,请使用“${CMD_ARGV[@]}”。
如果您想要“$#”,请使用“${#CMD_ARGV[@]}”。
等等。
小智 5
要对有关创建别名以将文件移动到垃圾箱文件夹而不是删除它们的问题给出具体答案:
alias rm="mv "$1" -t ~/.Trash/"
Run Code Online (Sandbox Code Playgroud)
当然,您必须先创建 dir ~/.Trash 。
然后只需给出以下命令:
$rm <filename>
$rm <dirname>
Run Code Online (Sandbox Code Playgroud)
小智 5
句法:
alias shortName="your custom command here"
Run Code Online (Sandbox Code Playgroud)
例子:
alias tlogs='_t_logs() { tail -f ../path/$1/to/project/logs.txt ;}; _t_logs'
Run Code Online (Sandbox Code Playgroud)
小智 5
使用子命令的解决方案:
d () {
if [ $# -eq 0 ] ; then
docker
return 0
fi
CMD=$1
shift
case $CMD in
p)
docker ps --all $@
;;
r)
docker run --interactive --tty $@
;;
rma)
docker container prune
docker image prune --filter "dangling=true"
;;
*)
docker $CMD $@
;;
esac
return $?
}
Run Code Online (Sandbox Code Playgroud)
使用:
$ d r my_image ...
Run Code Online (Sandbox Code Playgroud)
称为:
docker run --interactive --tty my_image ...
Run Code Online (Sandbox Code Playgroud)
您可以在别名中创建匿名函数:
alias mkcd='(){mkdir "$1";cd "$1";}'
Run Code Online (Sandbox Code Playgroud)
您需要"
周围$1
来处理其中包含空格的名称。外部避免了转义和'
的需要。您还可以将 all与一堆转义一起使用:"
$
"
alias mkcd="(){mkdir \"\$1\";cd \"\$1\";}"
Run Code Online (Sandbox Code Playgroud)
我认为这比创建命名函数的多个其他答案更清晰。
其中任何一个都有相同的用法。随后mkcd foo
将mkdir "foo"
cd "foo"
归档时间: |
|
查看次数: |
476402 次 |
最近记录: |