![通过空格传播 bash 参数](https://linux22.com/image/115466/%E9%80%9A%E8%BF%87%E7%A9%BA%E6%A0%BC%E4%BC%A0%E6%92%AD%20bash%20%E5%8F%82%E6%95%B0.png)
在 my-script 中,“$1”是一串标记,以空格分隔。
例如,如何将这个单个参数“扩展”为多个参数以传递给另一个程序
./my-script2 ...$1 # spread the string into multiple arguments, delineating by whitepace
希望您理解这个问题,在寻找答案时遇到困难。
我试过这个:
./my-script2 <<< "$1"
和这个:
./my-script2 "" <<< $1
和其他组合,但这似乎不起作用。我需要支持 Bash v3 及更高版本。
答案1
./my-script2 $1
shell 扫描未出现在双引号内的参数扩展、命令替换和算术扩展的结果以进行分词。
这是指定的 POSIX 行为,尽管有些 shell(特别是 zsh)默认禁用它。如果您更改了默认值IFS
,则由您负责。
答案2
摘要:“文件名扩展”安全解决方案(针对 my-script2):
IFS=' ' read -a arr <<<"$1"
printf '<%s>--' "${arr[@]}" ; echo
使用未加引号的变量将其分为单词(基于 IFS 值)的简单解决方案也会将内容暴露给 *, ? 上的文件名扩展。和[(至少)。
这个特定的字符串工作正常:
$ set "a string with spaces"
$ printf '<%s>--' $1; echo
<a>--<string>--<with>--<spaces>--
但这个字符串显然失败了:
$ set "a bad * string with spaces"
$ printf '<%s>--' $1; echo
<a>--<bad>--<file1>--<file2>--<string>--<with>--<spaces>--
星号已扩展到 PWD 中的文件中。
这里-doc
在没有“路径名扩展”的情况下获得变量扩展的一种方法(经常被忽视但也非常有用)是使用此处文档。
IFS=' ' read -ra arr <<-_EOF_
$1
_EOF_
printf '<%s>--' "${arr[@]}" ; echo;
正如手册中所解释的:
如果 word 不加引号,则此处文档的所有行都会进行参数扩展、命令替换和算术扩展,……
请注意“路径名扩展”是不是应用。
此处文档的近亲是此处字符串,它使代码更短:
IFS=' ' read -ra arr <<<"$1"
printf '<%s>--' "${arr[@]}" ; echo;
请记住(在双引号内)字符 \、$ 和 ` 是特殊的。
从手册中:
字符序列 \ 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `