我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
当前回答
我会发布我的(希望是好的)解决方案(对于未来的读者,最重要的是编辑)。所以,请编辑并改进/删除本文中的任何内容。
在终端中:
$ alias <name_of_your_alias>_$argname="<command> $argname"
并使用它(注意“_”后面的空格:
$<name_of_your_alias>_ $argname
例如,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!
测试(注意“_”后面的空格):
CAT_FILE_ hello.txt
其他回答
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`
顺便说一句,.bashrc和其他文件中定义的Bash函数可以作为shell中的命令使用。例如,您可以这样调用前面的函数
$ myfunction original.conf my.conf
完善上面的答案,您可以获得与别名类似的单行语法,这对于shell或.bashrc文件中的特殊定义更为方便:
bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }
bash$ myfunction original.conf my.conf
不要忘记右右括号前的分号。同样,对于实际问题:
csh% alias junk="mv \\!* ~/.Trash"
bash$ junk() { mv "$@" ~/.Trash/; }
Or:
bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }
实际上,函数几乎总是答案,正如手册页中的这句话所证实的:“对于几乎所有的目的,别名都被shell函数所取代。”
为了完整性,并且因为这可能是有用的(稍微更轻量级的语法),可以注意到,当参数跟随别名时,仍然可以使用它们(尽管这不能满足OP的要求)。这可能最容易用一个例子来演示:
alias ssh_disc='ssh -O stop'
允许我键入smth,如ssh_disc myhost,它按预期扩展为:ssh-O stop myhost
这对于接受复杂参数的命令很有用(我的记忆不再是以前的样子了…)
有正当的技术理由想要一个通用的解决方案来解决bash别名不具有重新定位任意参数的机制的问题。其中一个原因是,您希望执行的命令是否会受到执行函数所导致的环境更改的不利影响。在所有其他情况下,应使用函数。
最近迫使我尝试解决这个问题的是,我想创建一些简短的命令来打印变量和函数的定义。所以我为此写了一些函数。但是,有些变量是(或可能)由函数调用本身更改的。其中包括:
函数名称BASH_源巴什利诺BASH_ARGCBASH_ARGV
我一直在使用的基本命令(在函数中)来打印变量defns。set命令输出的形式为:
sv () { set | grep --color=never -- "^$1=.*"; }
例如。:
> V=voodoo
sv V
V=voodoo
问题:这不会打印上面提到的变量的定义,因为它们在当前上下文中,例如,如果在交互式shell提示符中(或不在任何函数调用中),FUNCNAME没有定义。但我的函数告诉我错误的信息:
> sv FUNCNAME
FUNCNAME=([0]="sv")
我提出的一个解决方案已经在其他关于这个主题的帖子中被提及。对于打印变量defns.的特定命令。,这只需要一个论点,我这样做了:
alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'
给出正确的输出(无)和结果状态(假):
> asv FUNCNAME
> echo $?
1
然而,我仍然觉得有必要找到一个适用于任意数量的论点的解决方案。
向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".
例如。:
> . 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
这个解决方案的一个优点是,在编写被捕获的命令时,所有用于处理命令的位置参数(参数)的特殊技巧都将发挥作用。唯一的区别是必须使用数组语法。
例如。,
如果需要“$@”,请使用“${CMD_ARGV[@]}”。
如果需要“$#”,请使用“${#CMD_ARGV[@]}”。
Etc.
如果您正在寻找一种通用方法来将所有参数应用于函数,而不仅仅是一个或两个或其他硬编码金额,您可以这样做:
#!/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;
因此,在上面的示例中,我将运行runjar时的所有参数传递给别名。
例如,如果我在那里运行了jar-hi,它最终会在那里运行java-jarmyjar.jar hi。如果我运行jar一二三,它将运行java-jarmyjar.jar一二三。
我喜欢这个基于$@的解决方案,因为它可以处理任意数量的参数。