【问题标题】:How to use positional parameters with "bash -c" command?如何通过“bash -c”命令使用位置参数?
【发布时间】:2018-10-25 17:34:51
【问题描述】:

我想知道使用命令bash -c时使用位置参数的最佳方式。

手册页指出-c 选项:

如果command_string后面有参数,则将它们分配给位置参数,从$0开始。

所以我猜下面的形式是正确的:

$ bash -c 'printf "%s %s %s\n" $0 $1 $2' param1 param2 param3
param1 param2 param3

但是I saw the following form,我想知道为什么会更好

$ bash -c 'printf "%s %s %s\n" $1 $2' _ param1 param2
param1 param2 

在这种情况下,字符 _ 将替换 $0

我知道对于许多解释器$0 具有特殊含义(命令名、所有位置参数...),但在这种情况下,手册页非常清楚。

那么,第一种形式有什么问题吗?使用$0 作为bash -c 命令的第一个位置参数有什么缺点吗?

【问题讨论】:

    标签: bash


    【解决方案1】:
    bash -c 'printf "%s %s %s\n" $0 $1 $2' param1 param2 param3
    

    上述方法有效,但许多人会认为这是一个坏习惯。如果您要将代码从-c 字符串复制到脚本,它会失败。同样,如果您要将代码从脚本复制到 -c 字符串,它会失败。

    相比之下,在以下形式中,$1-c 字符串中的含义与在脚本或 shell 函数中的含义相同:

    bash -c 'printf "%s %s %s\n" $1 $2 $3' _ param1 param2 param3
    

    编程风格的一致性减少了错误。

    shell 对待$0 的方式不同

    通常使用$@$* 来指代脚本的所有参数。请注意,这些变量包括$0

    $ bash -c 'echo "$*"' param1 param2 param3
    param2 param3
    $ bash -c 'echo "$@"' param1 param2 param3
    param2 param3
    

    $0是程序名

    在常规脚本中,$0 是脚本的名称。因此,在使用bash -c 时,有些人更喜欢为$0 参数使用一些有意义的名称,例如:

    bash -c 'printf "%s %s %s\n" $1 $2 $3' bash param1 param2 param3
    

    或者:

    bash -c 'printf "%s %s %s\n" $1 $2 $3' printer param1 param2 param3
    

    如果-c 字符串产生错误,这种方法具有明显的优势。例如,考虑这个脚本:

    $ cat script.sh
    #!/bin/bash
    bash -c 'grepp misspelling "$1"' BadPgm file.txt
    

    如果我们运行脚本,会产生以下输出:

    $ ./script.sh 
    BadPgm: grepp: command not found
    

    这将错误源标识为bash -c 字符串中的命令。

    【讨论】:

    • 我明白你的意思。在我看来-c 选项有一个错误,应该使用从$1 开始的位置参数,但我注意到zsh 的行为与bash 相同。可能有什么原因……
    • @oliv 我刚刚更新了一个部分的答案,讨论为什么很多人喜欢$0 的行为方式。
    【解决方案2】:

    参数$0的特殊之处在于它不参与shift(例如)。

    这按预期工作:

    $ bash -c 'shift; printf "%s %s %s\n" $1 $2 $3' _ par1 par2 par3 par4
    par2 par3 par4
    

    这不是:

    $ bash -c 'shift; printf "%s %s %s\n" $0 $1 $2' par1 par2 par3 par4
    par1 par3 par4
    

    这是defined in POSIX(简体):

    sh -c command_string [command_name [argument...]]

    应支持以下附加选项:

    -c

    从 command_string 操作数读取命令。根据 command_name 操作数的值设置特殊参数 0 的值(请参阅特殊参数),并从其余参数操作数依次设置位置参数($1、$2 等)。

    所以,使用这个:

    sh -c 'commands' command_name arg1 arg2 arg3 ....
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-17
      • 2014-06-21
      • 1970-01-01
      • 2021-02-06
      • 2011-02-12
      • 1970-01-01
      • 2011-07-14
      • 2023-04-03
      相关资源
      最近更新 更多