如何创建参数位于中间的别名?

发布于 2024-12-01 09:28:09 字数 474 浏览 2 评论 0原文

我试图定义一个别名,其中参数插入中间,而不是附加到末尾。

我尝试这样定义它:

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

Is it possible to do this using an alias or do我需要定义一个函数吗?

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 $1 */log/*.log"

where $1 is the first argument to grep_logs, such that:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

久隐师 2024-12-08 09:28:09

尝试在 ~/.profile 中定义一个函数。

function greplogs(){
    grep "$1" */logs/*.log
}

Try defining a function in ~/.profile.

function greplogs(){
    grep "$1" */logs/*.log
}
无人问我粥可暖 2024-12-08 09:28:09

只是为了回答问题,尽管函数解决方案更加清晰:

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.

Just for the sake of answering the question, although the function solution is much cleaner:

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.
一枫情书 2024-12-08 09:28:09

扩展 @erjoalgo 的答案,这是迄今为止唯一真正回答问题的答案:

##alias参数
Shell 别名do接受参数,但仅在末尾

$ alias speak=echo
$ speak hello world
hello world

通过alias将参数放入命令的中间是确实有可能,但它会变得很难看。

孩子们,不要在家里尝试这个!

如果您喜欢规避限制并做别人认为不可能的事情,那么这里就是秘诀。如果你的头发变得凌乱,你的脸最终被煤烟覆盖,就像疯狂科学家那样,请不要责怪我。

解决方法是将 alias 仅在末尾接受的参数传递给包装器,该包装器会将它们插入到中间,然后执行您的命令。

###Solution 1

如果您确实反对使用函数本身,您可以使用:

$ 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 在执行别名时删除函数定义,这样它就不会在执行后挂起。

###解决方案 2

您还可以使用子 shell:

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

解释 2

别名构建如下命令:

sh -c 'echo before "$@" after' _

注释:

  • 占位符 _ 是必需的,但也可以是任何事物。它被设置为 sh$0,并且是必需的,以便用户给定的第一个参数不会被消耗。演示:

     sh -c 'echo 消耗:“$0” 打印:“$@”' 酒精醉酒胡言乱语
     消耗:酒精 印刷:醉酒胡言乱语
    
  • 单引号内的双引号是必需的。这是一个不使用双引号的示例:

     $ sh -c "echo Consumed: $0 Printing: $@" 酒精醉酒胡言乱语
     消耗:-bash 打印:
    

    这里,交互式 shell 的 $0$@ 的值在传递给 sh 之前被替换为双引号。证据如下:

     echo "消耗: $0 打印: $@"
     消耗:-bash 打印:
    

    单引号确保这些变量不会被交互式 shell 解释,而是按字面意思传递给 sh -c

    您可以使用双引号和 \$@,但最佳实践是引用您的参数(因为它们可能包含空格)和 \"\$@\" 看起来更难看,但可能会帮助你赢得一场混淆比赛,其中凌乱的头发是参赛的先决条件。


Expanding upon @erjoalgo's answer which so far is the only one which actually answers the question:

##alias arguments
Shell aliases do accept arguments, but only at the end:

$ alias speak=echo
$ speak hello world
hello world

Putting arguments into the middle of command via alias is indeed possible but it gets ugly.

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 alias accepts only at the end to a wrapper that will insert them in the middle and then execute your command.

###Solution 1

If you're really against using a function per se, you can use:

$ alias wrap_args='f(){ echo before "$@" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

You can replace $@ with $1 if you only want the first argument.

Explanation 1

This creates a temporary function f, which is passed the arguments (note that f is called at the very end). The unset -f removes the function definition as the alias is executed so it doesn't hang around afterwards.

###Solution 2

You can also use a subshell:

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

Explanation 2

The alias builds a command like:

sh -c 'echo before "$@" after' _

Comments:

  • The placeholder _ is required, but it could be anything. It gets set to sh's $0, and is required so that the first of the user-given arguments don't get consumed. Demonstration:

     sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
     Consumed: alcohol Printing: drunken babble
    
  • The double-quotes inside single-quotes are required. Here's an example of it not working with double quotes:

     $ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
     Consumed: -bash Printing:
    

    Here the values of the interactive shell's $0 and $@ are replaced into the double quoted before it is passed to sh. Here's proof:

     echo "Consumed: $0 Printing: $@"
     Consumed: -bash Printing:
    

    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.

メ斷腸人バ 2024-12-08 09:28:09

不完全是您正在寻找的答案,但如果不想将模式指定为第一个参数,请使用 -e 参数

alias grep_logs="grep */log/*.log -e"

Not quite the answer you're looking for but use the -e argument if don't want to specify the pattern as the first argument

alias grep_logs="grep */log/*.log -e"
贪恋 2024-12-08 09:28:09

问题是别名不支持位置参数的概念。如果他们这样做了,我们就不需要函数了。所以是的,使用函数,因为函数正是为此目的而创建的。

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.

孤单情人 2024-12-08 09:28:09

尝试使用一个函数,然后给它起别名:

function func_grep_logs {
    grep $1 */log/*.log
}

then

alias grep_logs="func_grep_logs"

Try using a function and then aliasing it:

function func_grep_logs {
    grep $1 */log/*.log
}

then

alias grep_logs="func_grep_logs"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文