如何使用“bash -c”命令使用位置参数?

时间:2016-08-10 07:30:04

标签: bash

使用命令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命令的第一个位置参数有什么缺点吗?

2 个答案:

答案 0 :(得分:18)

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字符串中的命令。

答案 1 :(得分:8)

参数$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操作数读取命令。从剩余的参数操作数依次设置特殊参数0(参见特殊参数)的值,从 command_name 操作数的值和位置参数($ 1,$ 2等)依次设置。

所以,请使用:

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