我有一个名为“name_value.sh”的 shell,我想传递在子 shell 中生成的参数。如何保证从子shell接收参数的命令保留空格?
注意:这是我正在做的事情的一个极其简化的例子。请在回复前完整阅读。
一个简化的例子是:
./name_value.sh $(echo "no_spaces"; echo "with spaces")
name_value.sh 看起来像这样:
#!/bin/bash
echo "Name=$1"
echo "Value=$2"
期望的输出是:
Name=no_spaces
Value=with spaces
这是一个大大简化的示例。我真正的子 shell 很复杂,循环并输出数十个名称/值对,这些名称/值对必须同时生成并同时传递给 name_value.sh。我也无法控制我正在调用的 shell 文件。
我尝试过用引号回显并使用 printf 和“%q”。我还考虑过首先将子 shell 的结果放入数组中,但也无法使其工作。我需要父 shell 来解释子 shell,就像输入文本代替子 shell 一样。
答案1
是的。将变量(通常包含空格、制表符、换行符)设置IFS
为换行符。这样,空格和制表符将不会用于分词。这将为您提供所需的输出。
IFS=$'\n'
set -o noglob # disable the second effect of leaving that
# $(...) unquoted.
./name_value.sh $(echo "no_spaces"; echo "with spaces")
但是,我要做的是从标准输入读取脚本。
# name_value.sh
IFS= read -r name
IFS= read -r value
echo "Name=$name"
echo "Value=$value"
然后
( echo no_spaces; echo with spaces ) | ./name_value.sh
我认为这种方法更加稳健。
答案2
当你使用这个命令时
./name_value.sh $(echo "no_spaces"; echo "with spaces")
bash 执行“$()”中的“sub-shells”命令并返回输出字符串
例子
输入命令:./name_value.sh $(echo "no_spaces"; echo "with space")
处理后的命令:./name_value.sh no_spaces 带空格
下一步是使用三个参数执行 bash 脚本
第一个论点:没有空间
第二个论点:和
第三个论点:空间
这与使用命令手动调用脚本相同
./name_value.sh no_spaces with spaces
为了解决您的问题,您需要在子 shell 调用“$()”周围插入引号
你需要这个
./name_value.sh $(echo "no_spaces") "$(echo "with spaces")"
你处理的命令是
./name_value.sh no_spaces "with spaces"
最后,你的输出将是
Name=no_spaces
Value=with spaces