我在使用bash解析命令行中的单词时遇到了一些麻烦。我觉得最容易举一个例子,所以不用多说,我们走了。
这是脚本test.sh:
#!/bin/bash
echo "inside test with $# arguments"
if [[ $# -eq 0 ]]
then
data=cat data.txt
echo ./test $data
./test $data
else
for arg in "$@"
do
echo "Arg is \"$arg\""
done
fi
这是文件data.txt:
cat data.txt
所需的输出
"abc 123" 1 2 3 "how are you"
是
$ test.sh
但相反,我得到了
inside test with 0 arguments
./test "abc 123" 1 2 3 "how are you"
inside test with 5 arguments
Arg is "abc 123"
Arg is "1"
Arg is "2"
Arg is "3"
Arg is "how are you"
真正烦人的是,如果我执行从test.sh的第7行转储的命令,我做得到所需的输出(当然没有前两行)。
所以从本质上说,如果给定的输入已经从文件中读取,有没有办法让bash解析单词?
答案 0 :(得分:1)
您可以使用eval
:
eval ./test "$data"
您must be careful知道在使用eval
时可以信任该文件的内容。要说明原因,请在数据文件的行末添加; pwd
。运行脚本时,将打印当前目录。想象一下,如果它是破坏性的东西。
如果您可以选择数据文件中字段之间的空格以外的分隔符,那可能会更好。例如,如果您使用制表符,则可以执行以下操作:
while IFS=$'\t' read -r -a array
do
for item in "${array[@]}"
do
something with "$item"
done
done < data.txt
您不需要引用包含空格的字段。
这是对我认为是你问题中的拼写错误的更正:
data=$(cat data.txt)
答案 1 :(得分:1)
无需两次调用脚本。
如果您发现没有参数,可以使用set
将其更改为其他参数,例如:
#!/bin/bash
if [ $# -eq 0 ]
then
echo "inside test with $# arguments"
eval set -- $(<data.txt)
fi
echo "inside test with $# arguments"
for arg in "$@"
do
echo "Arg is \"$arg\""
done
答案 2 :(得分:0)
是的,只需替换
./test $data
与
eval ./test $data