问题: 我有一个编译简单RPN表达式的简单编译器。编译器的调用方式如下:
./compiler 1 2 3 + "*"
这很好用。
现在,让我说我已经把
1 2 3 + "*"
进入一个名为input的文件。然后当我像这样调用编译器时:
./compiler $(cat input)
我的编译器会抱怨:未知符号:“*”
如果我删除*周围的双引号,*会扩展为文件名。我也试过''和``,不好。
那么,如何从文件中输入普通*?
答案 0 :(得分:1)
zoo.sh
#!/bin/bash
set -f
echo $@
m.txt ,内容为:
1 2 3 + *
在shell中执行:
set -f
./zoo.sh 1 2 4 + *
1 2 4 + *
./zoo.sh $(cat m.txt)
1 2 3 + *
shell正在为您进行扩展。在命令运行之前发生。如果你想要它停止你需要明确地告诉它。在这里阅读: http://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin
在脚本上方还设置了这个,以防止脚本内的回显进行扩展,并使我的代码工作正常。您的编译器可能不需要(需要)执行此操作。
请记住执行set +f
恢复文件名扩展。
答案 1 :(得分:0)
从包含它们的变量中删除引用字符的唯一方法:
a='1 2 3 + "*"'
是shell“报价删除”。每次shell解析一个字符串时都会这样做(如果它不是其他扩展的结果)。因此,即使没有引用,也不会删除引号:
$ echo $a
1 2 3 + "*"
即使重复,也不会删除引号:
$ echo $(echo $( echo $a ) )
1 2 3 + "*"
但是如果我们用eval重新解析字符串,则会删除引号:
$ eval echo $a
1 2 3 + *
或者如果字符串被发送到外部程序(不是内置程序),它将在返回时重新解析。这就是xargs所发生的事情:
$ xargs <<<$a
1 2 3 + *
现在,根据您的具体情况,请执行以下操作:
$ eval echo $(<file.csv)
或
$ xargs <file.csv
在这种情况下,xargs正在执行默认回声,所以基本上和上面一样。
请注意,任一命令都适用于此特定代码,但却是严重安全风险的来源。记住:eval是邪恶的。