Bash metaprogramming



我有一个脚本,将命令(对于脚本而不是bash)作为参数。

它处理以下的两个调用:

$ ./my_script -f 'cmd1','cmd2','cmd3' #etc
$ ./my_script -f 'cnd1' -f 'cmd2' -f'cmd3' #etc

脚本的常见用例将使它命令同一家族,但具有不同的参数或标志:

$ ./my_script -f 'cmd arg1','cmd arg2','cmd arg3'

我希望能够简洁地键入它,本质上是{"'cmd "} {arg1,arg2,arg3,...}的笛卡尔产品,每个产品都以"'"`'

我知道Bash可以制作笛卡尔产品,实际上:

$ echo "-f 'cmd "{arg1,arg2,arg3}"'"

以第二种形式输出我的调用的第二部分:

 -f 'cmd arg1' -f 'cmd arg2' -f 'cmd arg3'

但是,如果在这样的调用中使用:

$ ./my_script "-f 'cmd "{1,2,3}"'"

脚本当然将其视为3个参数,上面有空间。如果我在子壳中呼应笛卡尔产品部分,则如下:

$ ./my_script $(echo "-f 'cmd "{1,2,3}"'")

然后它将在每个空间上拆分,忽略单引号。

使用红宝石单线来说明脚本在每种情况下如何接收参数:

$ ruby -e  'puts ARGV.each_with_index.map {|a,i| (i+1).to_s+" : "+a}' --  "-f 'cmd "{1,2,3}"'"
1 : -f 'cmd 1'
2 : -f 'cmd 2'
3 : -f 'cmd 3'
$ ruby -e  'puts ARGV.each_with_index.map {|a,i| (i+1).to_s+" : "+a}' --  $(echo "-f 'cmd "{1,2,3}"'")                                                                                                                            
1 : -f
2 : 'cmd
3 : 1'
4 : -f
5 : 'cmd
6 : 2'
7 : -f
8 : 'cmd
9 : 3'

所以我的问题是,我可以让Bash评估echo命令的输出,就好像用户输入了吗?(过程引号和所有内容?)

更新

我应该提到脚本会采用其他可能具有空格的参数,因此实际上我正在寻找某种 partial ,本地化的eval(如果有这样的事情),否则,我必须逃脱其他引号,以使其能够通过eval

(如果没有,我只会将笛卡尔产品能力添加到脚本中,但是我想确保没有一种优雅的方式从外部进行。)

那是您需要额外的 eval的步骤

这类似于您的Ruby脚本(无需计数):

f() {
  for arg
  do
    echo "[$arg]"
  done
}

这就是您的方式:

eval f "-f 'cmd "{1,2,3}"'"

输出是预期的:

[-f]
[cmd 1]
[-f]
[cmd 2]
[-f]
[cmd 3]

相关内容

  • 没有找到相关文章

最新更新