包含多个参数的变量,在Bash中带引号

hib*_*bou 32 variables bash quotes escaping

我生成一个包含所有args的bash变量,这些args包含空格.当我用这些args启动命令时 - 例如.ls $ args - 引号未正确解释.这是一个示例 - 还创建和擦除所需的文件.

#!/bin/bash
f1="file n1"
f2="file n2"
# create files
touch "$f1" "$f2"
# concatenate arguments
args="\"$f1\" \"$f2\""
# Print arguments, then launch 'ls' command
echo "arguments :" $args
ls $args
# delete files
rm "$f1" "$f2"
Run Code Online (Sandbox Code Playgroud)

有了这个,我对"file,n1","file and n2"有一些"没有这样的文件"错误

mar*_*ton 51

您可以考虑为args 使用数组,如下所示:

args=( "$f1" "$f2" )
ls "${args[@]}"
Run Code Online (Sandbox Code Playgroud)

(你目前遇到的问题是,一旦发生插值,文件名间和文件名间空间就没有区别.)

  • @ ArranCudbard-Bell:从理智编程语言的角度来看,大多数shell语法都很奇怪且不透明.但它确实如此. (4认同)
  • 这仅适用于支持数组的Bash之类的shell.下面描述的`eval`适用于所有Unix shell. (3认同)

Arr*_*ell 33

使用eval它将首先评估任何扩展和引用,然后执行结果字符串,就像它已被输入shell一样.

args="'$f1' '$f2'"
eval ls $args
Run Code Online (Sandbox Code Playgroud)

然后eval将执行 ls 'file n1' 'file n2'

有一个非常类似的问题,试图通过争论从源变量/etc/default/,以start_stop_daemon在init脚本中.

  • 我同意@ ArranCudbard-Bell.您已经使用变量参数执行可能任意的代码.使用`eval`不允许代码在这种情况下做更多的事情. (5认同)
  • 因为"eval"存在严重的安全问题而被低估 - 请参阅http://stackoverflow.com/a/37573041/120818以获得更详细的解释,但基本上(来自http://mywiki.wooledge.org/BashFAQ/048):"它会导致您的代码被解析两次而不是一次;这意味着,例如,如果您的代码中包含变量引用,则shell的解析器将评估该变量的内容.如果该变量包含shell命令,则shell可能运行该命令,无论你是否想要它." (3认同)

tri*_*eee 6

使用set设置您的变量定位参数; 那么如果您通过"$@"或,等等引用它们"$1",引用将被保留"$2"。请确保在变量名周围使用双引号。

set -- "$f1" "$f2"
touch "$@"
ls "$@"
rm "$@"
Run Code Online (Sandbox Code Playgroud)


Dav*_*son 5

这可能是最糟糕的答案,但是您可以更改IFS。这是“内部字段分隔符”,默认情况下等于space + tab + newline。

#!/bin/sh
IFS=,
MAR="-n,my file"
cat $MAR
Run Code Online (Sandbox Code Playgroud)

上面的脚本将运行cat。第一个参数为-n(带编号的行),第二个参数为my file