我正在尝试定义一个别名,其中参数插入到中间,而不是附加到末尾。
我尝试像这样定义:
alias grep_logs="grep $1 */log/*.log"
其中$ 1是grep_logs的第一个参数,例如:
grep_logs foo
将执行以下命令:
grep foo */log/*.log
但是,它运行命令:
grep foo */log/*.log foo
导致错误:
grep: foo: No such file or directory
是否可以使用别名执行此操作,还是需要定义函数?
答案 0 :(得分:32)
尝试在〜/ .profile中定义一个函数。
function greplogs(){
grep "$1" */logs/*.log
}
答案 1 :(得分:15)
只是为了回答这个问题,虽然功能解决方案更清晰:
alias sstatus='bash -xc '\''sudo service $0 status'\'''
alias sstart='bash -xc '\''sudo service $0 start'\'''
alias sstop='bash -xc '\''sudo service $0 stop'\'''
$sstatus cups
+ sudo service cups status
Status of Common Unix Printing System: cupsd is running.
答案 2 :(得分:3)
扩展@erjoalgo's answer到目前为止唯一一个实际回答问题的人:
alias
参数Shell别名执行接受参数,但仅限于结束:
$ alias speak=echo
$ speak hello world
hello world
通过alias
将参数放入命令的中间确实是可能的,但它很难看。
如果您喜欢规避限制并做其他人认为不可能的事情,那么这就是食谱。如果你的头发被弄得疲惫不堪,你的脸最终会被烟灰色的科学家风格所覆盖,请不要怪我。
解决方法是将alias
仅在末尾接受的参数传递给将在中间插入它们然后执行命令的包装器。
如果你真的反对使用函数本身,你可以使用:
$ alias wrap_args='f(){ echo before "$@" after; unset -f f; }; f'
$ wrap_args x y z
before x y z after
如果您只想要第一个参数,则可以将$@
替换为$1
。
解释1
这会创建一个临时函数f
,它会传递参数(注意最后调用f
)。 unset -f
在执行别名时删除了函数定义,因此它不会在之后挂起。
您还可以使用子shell:
$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'
解释2
别名构建如下命令:
sh -c 'echo before "$@" after' _
评论:
占位符_
是必需的,但它可以是任何内容。它被设置为sh
的{{1}},并且是必需的,以便第一个用户给定的参数不被消耗。示范:
$0
单引号内的单引号是必需的。这是一个不使用双引号的例子:
sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
Consumed: alcohol Printing: drunken babble
此处交互式shell $ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
Consumed: -bash Printing:
和$0
的值在传递给$@
之前被替换为双引号。这是证据:
sh
单引号确保交互式shell不解释这些变量,并按字面意思传递给echo "Consumed: $0 Printing: $@"
Consumed: -bash Printing:
。
您可以使用双引号和sh -c
,但最佳做法是引用您的参数(因为它们可能包含空格),\$@
看起来更加丑陋,但可能会帮助您赢得混淆比赛那些疲惫的头发是入门的先决条件。
答案 3 :(得分:2)
如果您不想将模式指定为第一个参数
,请使用-e
参数。
alias grep_logs="grep */log/*.log -e"
答案 4 :(得分:2)
问题是别名不支持位置参数的概念。如果他们这样做了,我们就不需要功能了。所以,是的,使用一个函数,因为函数是为此目的而制作的。
答案 5 :(得分:1)
尝试使用函数然后别名:
function func_grep_logs {
grep $1 */log/*.log
}
然后
alias grep_logs="func_grep_logs"