在 bash 变量中传递带有空格的引号文件名

在 bash 变量中传递带有空格的引号文件名

在 bash shell 中,请考虑以下内容:

$ x="-name 'foo bar'"
$ find $x
find: paths must precede expression: `bar''
$ find -name 'foo bar'
./foo bar

我可以放入什么$x来让find $x行为变得像find -name 'foo bar'

答案1

不要将单独的内容 (-namefoo bar) 放入单个字符串中。

相反,使用数组:

args=( -name 'foo bar' )

find . "${args[@]}"

数组变量扩展周围的引号确保每个元素都被单独引用。这确保了这foo bar是一个单一的参数。

您还可以使用位置参数:

set -- -name 'foo bar'

find . "$@"

再次强调,引用"$@"是必不可少的。

当您放入-name 'foo bar'变量并使用不带引号的变量时find,shell 会在空格、制表符和换行符上拆分该值。这意味着该find实用程序获取参数-name'foobar'。由于bar'不知道该参数find,因此它会抱怨。

如果字符串中有通配模式(如 )-name '*.txt',那么 shell 会将其拆分为-name'*.txt',然后用作'*.txt'通配模式来扩展当前目录中的名称。

答案2

注意:Linux 支持 find 语法,但它并不通用。它不适用于大多数 BSD 衍生品,例如,产生以下结果:

bash-3.2$ find -name 'foo bar'
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]

你的问题不是位置,而是引用和引用解释。您可以将您的代码替换为

x='foo bar'
find -name "$x"

或者,您可以尝试使用 eval:

x="-name 'foo bar'"
eval "find $x"

至少在我的系统上导致:

bash-5.1$ x="-name 'foo bar'"
bash-5.1$ eval "find $x"
./foo bar

我相信这是期望的结果。

相关内容