bash 如何创建参数在中间的别名?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7181620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create an alias where the arguments go in the middle?
提问by sferik
I'm trying to define an alias where the arguments are inserted in the middle, instead of appended to the end.
我试图定义一个别名,其中参数插入在中间,而不是附加到末尾。
I tried defining it like this:
我试着这样定义它:
alias grep_logs="grep */log/*.log"
where $1 is the first argument to grep_logs, such that:
其中 $1 是 grep_logs 的第一个参数,例如:
grep_logs foo
would execute the following command:
将执行以下命令:
grep foo */log/*.log
but instead, it runs the command:
相反,它运行命令:
grep foo */log/*.log foo
which results in the error:
这导致错误:
grep: foo: No such file or directory
Is it possible to do this using an alias or do I need to define a function?
是否可以使用别名来做到这一点,或者我是否需要定义一个函数?
回答by Hyman
Try defining a function in ~/.profile.
尝试在 ~/.profile 中定义一个函数。
function greplogs(){
grep "" */logs/*.log
}
回答by ealfonso
Just for the sake of answering the question, although the function solution is much cleaner:
只是为了回答问题,虽然功能解决方案更清晰:
alias sstatus='bash -xc '\''sudo service $ alias speak=echo
$ speak hello world
hello world
status'\'''
alias sstart='bash -xc '\''sudo service $ alias wrap_args='f(){ echo before "$@" after; unset -f f; }; f'
$ wrap_args x y z
before x y z after
start'\'''
alias sstop='bash -xc '\''sudo service $ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'
stop'\'''
$sstatus cups
+ sudo service cups status
Status of Common Unix Printing System: cupsd is running.
回答by Tom Hale
Expanding upon @erjoalgo's answerwhich so far is the only one which actually answers the question:
扩展@erjoalgo 的答案,到目前为止,这是唯一一个真正回答问题的答案:
aliasarguments
alias争论
Shell aliases doaccept arguments, but only at the end:
Shell 别名确实接受参数,但仅在最后:
sh -c 'echo before "$@" after' _
Putting arguments into the middleof command via aliasis indeed possible but it gets ugly.
将参数放入命令中间alias确实是可能的,但它变得丑陋。
Don't try this at home, kiddies!
不要在家里尝试这个,孩子们!
If you like circumventing limitations and doing what others say is impossible, here's the recipe. Just don't blame me if your hair gets frazzled and your face ends up covered in soot mad-scientist-style.
如果您喜欢规避限制并做其他人说不可能的事情,那么这里有一个秘诀。如果你的头发变得疲惫不堪,你的脸最终被煤烟疯狂科学家式覆盖,请不要责怪我。
The workaround is to pass the arguments that aliasaccepts only at the end to a wrapper that will insert them in the middle and then execute your command.
解决方法是将alias仅在最后接受的参数传递给包装器,该包装器将它们插入中间,然后执行您的命令。
Solution 1
方案一
If you're really against using a function per se, you can use:
如果你真的反对使用函数本身,你可以使用:
sh -c 'echo Consumed: "$ sh -c "echo Consumed: echo "Consumed: sh -c 'echo Consumed: "$ sh -c "echo Consumed: echo "Consumed: alias grep_logs="grep */log/*.log -e"
Printing: $@"
Consumed: -bash Printing:
Printing: $@" alcohol drunken babble
Consumed: -bash Printing:
" Printing: "$@"' alcohol drunken babble
Consumed: alcohol Printing: drunken babble
Printing: $@"
Consumed: -bash Printing:
Printing: $@" alcohol drunken babble
Consumed: -bash Printing:
" Printing: "$@"' alcohol drunken babble
Consumed: alcohol Printing: drunken babble
You can replace $@with $1if you only want the first argument.
如果您只想要第一个参数$@,$1则可以替换为。
Explanation 1
说明 1
This creates a temporary function f, which is passed the arguments (note that fis called at the very end). The unset -fremoves the function definition as the alias is executed so it doesn't hang around afterwards.
这将创建一个临时函数f,该函数被传递参数(注意f在最后调用)。在unset -f执行别名时删除函数定义,因此它之后不会挂起。
Solution 2
解决方案2
You can also use a subshell:
您还可以使用子shell:
function func_grep_logs {
grep */log/*.log
}
Explanation 2
说明二
The alias builds a command like:
别名构建一个命令,如:
alias grep_logs="func_grep_logs"
Comments:
注释:
The placeholder
##代码##_is required, but it could be anything. It gets set tosh's$0, and is required so that the first of the user-given arguments don't get consumed. Demonstration:The single-quotes inside single-quotes are required. Here's an example of it not working with double quotes:
##代码##Here the values of the interactive shell's
##代码##$0and$@are replaced into the double quoted beforeit is passed tosh. Here's proof:The single quotes ensure that these variables are not interpreted by interactive shell, and are passed literally to
sh -c.You could use double-quotes and
\$@, but best practice is to quote your arguments (as they may contain spaces), and\"\$@\"looks even uglier, but may help you win an obfuscation contest where frazzled hair is a prerequisite for entry.
占位符
##代码##_是必需的,但它可以是任何东西。它被设置为sh's$0,并且是必需的,以便不会消耗用户给定的第一个参数。示范:单引号内的单引号是必需的。这是它不适用于双引号的示例:
##代码##这里交互式 shell 的
##代码##$0和的值在传递给之前$@被替换为双引号。这里有证据:sh单引号确保这些变量不被交互式 shell 解释,并按字面传递给
sh -c.您可以使用双引号 and
\$@,但最佳做法是引用您的论点(因为它们可能包含空格),\"\$@\"看起来更难看,但可能会帮助您赢得一场混淆比赛,在这种比赛中,卷曲的头发是参赛的先决条件。
回答by Dunes
Not quite the answer you're looking for but use the -eargument if don't want to specify the pattern as the first argument
不是您正在寻找的答案,但-e如果不想将模式指定为第一个参数,请使用该参数
回答by Jens
The issue is that aliases don't support the concept of positional parameters. If they did, we wouldn't need functions. So yes, use a function because functions are made exactly for this purpose.
问题是别名不支持位置参数的概念。如果他们这样做了,我们就不需要函数了。所以是的,使用函数,因为函数正是为此目的而制作的。
回答by Femi
Try using a function and then aliasing it:
尝试使用一个函数,然后给它取别名:
##代码##then
然后
##代码##
