【问题标题】:How do I create an alias where the arguments go in the middle? [duplicate]如何创建参数位于中间的别名? [复制]
【发布时间】:2011-11-03 03:24:30
【问题描述】:

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

我试着这样定义它:

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

是否可以使用别名来做到这一点,还是需要定义一个函数?

【问题讨论】:

  • 可以做一个超级简单的python脚本来自动化它,你试过吗? (提示:你必须使用 sys.argv)
  • 写一个函数,而不是别名。

标签: bash unix shell alias sh


【解决方案1】:

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

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

【讨论】:

  • 如果你想传递多个参数,你可以使用${@:1}而不是"$1",它会在那里插入所有参数。对于需要中间有参数的别名的人可能有用。
  • 请注意,您不需要使用function,您可以使用greplogs() { 开头。此外,如果您确实使用function,它将在 ksh 中中断。
  • 如何调用传递参数的函数?
  • @Pijusn 为什么不$@?尽管显然${@:2} 对于跳过第一个参数很有用。
  • @piojo 你是对的,他们是平等的(AFAIK)。不知道为什么我不只是建议$@。 :)
【解决方案2】:

只是为了回答问题,虽然函数解决方案更干净:

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.

【讨论】:

    【解决方案3】:

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

    ##alias 参数 Shell 别名 do 接受参数,但仅在 end:

    $ alias speak=echo
    $ speak hello world
    hello world
    

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

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

    如果您喜欢规避限制并按照别人说的去做是不可能的,这就是秘诀。如果你的头发变得蓬乱并且你的脸最终被煤烟疯狂科学家风格覆盖,请不要责怪我。

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

    ###解决方案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 Consumed: "$0" Printing: "$@"' alcohol drunken babble
       Consumed: alcohol Printing: drunken babble
      
    • 单引号内的双引号是必需的。这是一个不使用双引号的示例:

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

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

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

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

      您可以使用双引号和\$@,但最佳做法是引用您的论点(因为它们可能包含空格),而\"\$@\" 看起来更难看,但可能会帮助您赢得一场混淆头发的混淆竞赛进入的先决条件。

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

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

          然后

          alias grep_logs="func_grep_logs"
          

          【讨论】:

          • 为什么不grep "$1" */log/*.log
          • 那么别名到底有什么好处呢?正确的答案是别名是错误的答案,而函数是替代方法。
          • 声明中函数名后没有()?
          猜你喜欢
          • 2012-07-13
          • 2015-01-07
          • 1970-01-01
          • 1970-01-01
          • 2012-12-31
          • 2010-12-21
          • 2018-05-12
          • 2013-11-07
          • 2020-10-07
          相关资源
          最近更新 更多