在Bash中传递参数给别名

140

以下是需要实现的功能:

我想要运行以下操作:

mongodb bin/mongod

我的bash_profile文件中有以下内容:

alias = "./path/to/mongodb/$1"
6个回答

249

别名将扩展为它所代表的字符串。别名后面的任何内容都会在其扩展后出现,无需作为显式参数传递或能够传递(例如$1)。

$ alias foo='/path/to/bar'
$ foo some args

将会被扩展为

$ /path/to/bar some args

如果您想使用显式参数,您需要使用一个函数。
$ foo () { /path/to/bar "$@" fixed args; }
$ foo abc 123

将被执行,就像你已经完成了一样。

$ /path/to/bar abc 123 fixed args

取消别名的方法如下:
unalias foo

取消定义一个函数:
unset -f foo

查看每个已定义的别名、关键字、函数、内置命令或可执行文件的类型和定义:

type -a foo

或者仅输入类型(为了最高优先级出现):
type -t foo

11
只是想从我的 .bashrc 中添加一个例子 mkcd () { mkdir "$@" && cd "$@"; } 在这里我创建了一个目录并进入其中。 - Vova Lando
4
如果你指的是我的回答中的颜色,那是由语法高亮自动完成的。 - Dennis Williamson
1
@shinobi:unset -f foo - Dennis Williamson
如果我想要得到这样的输出:“´$ /path/to/bar/abc/123 fixed args´”,该怎么做呢?我该如何实现? - Mymozaaa
@Mymozaaa:不清楚您想要做什么。您是否想将可执行文件的dirname和filename作为参数传递? - Dennis Williamson
显示剩余5条评论

27

使用别名中的参数,我使用以下方法:

alias myalias='function __myalias() { echo "Hello $*"; unset -f __myalias; }; __myalias'

它是一个自毁函数嵌套在别名中,因此它几乎是最好的两个世界,并且不会占用您定义中的额外行...这让我很讨厌,哦对了,如果您需要返回值,则必须在调用unset之前存储它,然后在那个自毁函数中使用“return”关键字返回值:

alias myalias='function __myalias() { echo "Hello $*"; myresult=$?; unset -f __myalias; return $myresult; }; __myalias'

所以...

如果你需要在其中有那个变量,你可以这样做。

alias mongodb='function __mongodb() { ./path/to/mongodb/$1; unset -f __mongodb; }; __mongodb'

当然...

alias mongodb='./path/to/mongodb/'

实际上,即使没有参数,也可以执行同样的操作,但是如果你想要或需要一些参数(例如,你需要$2而不是$1),你就需要使用像这样的包装器。如果代码超过一行,你可能会考虑直接编写一个函数,因为随着代码变得越来越长,它会变得更加难以阅读和维护。函数非常好用,因为你可以获得所有函数提供的好处(在bash手册中查看完成、陷阱、绑定等好东西)。

希望这能帮到你 :)


2
~$ alias myalias='function __myalias() { echo "Hello $*"; unset -f __myalias; } __myalias' ~$ myalias -bash:`__myalias' 附近有语法错误的标记 - JeeBee
这太糟糕了!你每次都要重新定义函数吗?(我甚至懒得检查你是否有语法错误)。 - gniourf_gniourf
1
他们不必完全按照那种方式去做,那只是一个例子而已。是的,它每次都被重新定义,这使得它保持在一行内,否则,它就不会是一个一次性的了,这就像抱怨“别名”每次都会扩展到其分配的内容一样,有什么区别吗?而且没有必要情绪激动。 - osirisgothra
JeeBee:这个行编辑器把我的行连在一起了,所以我加了那个分号来纠正它。 - osirisgothra

23

通常当我想在Bash中传递参数给别名时,我使用别名和函数的组合,例如:

function __t2d {                                                                
         if [ "$1x" != 'x' ]; then                                              
            date -d "@$1"                                                       
         fi                                                                     
} 

alias t2d='__t2d'                                                               

19
“[ -n "$1" ]” 表示判断变量 $1 是否非空。在现代的Shell中,使用“x”来进行这种判断是过时且不必要的。 - Dennis Williamson
4
你可以称呼我为老派。原始问题涉及别名和它们的参数。我认为你的评论对谈话没有任何实质性的贡献。 - leed25d
21
虽然这是非常有用的信息,但不建议使用 x,因为它会让新手感到困惑。有些傲慢的程序员似乎因此而感到高兴。我们应该在这里提供帮助,无论某件事情是否传统并不能成为让人困惑的借口。 - osirisgothra
4
告诉新手不要这么做是非常有用的信息,因为这样完全没有意义。他们想要的只是一个函数。制作一个函数然后将其重命名为另一个名称真的完全没有意义。 - remmy
9
如果您将__t2d定义为函数,为什么还要取别名呢?为什么不把函数命名为t2d并跳过取别名的步骤呢? - Mark E. Haase
显示剩余4条评论

14

这是一种可以避免使用函数的解决方案:

alias addone='{ num=$(cat -); echo "input: $num"; echo "result:$(($num+1))"; }<<<'

测试结果

addone 200
input: 200
result:201

它对我来说完美地运行了。我想将颜色编号(从31到37)传递给我的别名中的PS命令。我做了这样的事情: alias psany='{ PS1="\e[0;$(cat -)m> \e[m";}<<<' 用法:psany 32 - zviad
这应该更高!在我的使用情况中,使用函数不可行,因为我希望如果脚本未被源化,则return失败。将别名包装在函数中意味着return始终成功执行。感谢您提供的解决方案。如果您提供一个钱包地址,我会用BCH给您小费。 - Lubo Kanev

5
在 csh (与 bash 相反)中,您可以完全按照您想要的方式操作。
alias print 'lpr \!^ -Pps5'
print memo.txt

符号\!^会将参数插入命令的此处。

!字符前面加上\,以防其被解释为历史命令。

您也可以传递多个参数:

alias print 'lpr \!* -Pps5'
print part1.ps glossary.ps figure.ps

(以下示例摘自http://unixhelp.ed.ac.uk/shell/alias_csh2.1.html。)


只是补充一下,在csh中还有更酷的东西:"!$"指的是最后一个参数,"!:1"指的是第一个参数(与"!^"相同),"!:2"指的是第二个参数...甚至还有可选参数!"!:1*"打印出从第1个参数开始到最后一个参数的所有参数,其中即使第1个参数是可选的。如果该参数不存在,则变量将被赋予空值。 - Kiteloopdesign

-3
为了简化leed25d的回答,可以使用别名和函数的组合。例如:
function __GetIt {
    cp ./path/to/stuff/$* .
}

alias GetIt='__GetIt'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接