我正在编写一个简单的bash脚本,它正在执行以下操作:
cmd="egrep -i Hello /home/me/foo.txt"
if [ -n $cmd ]
then
$cmd
if [ $? -eq 0 ]
then
echo "YAY"
else
echo "BOO"
fi
fi
返回“YAY”。但是,如果我在Hello周围添加单引号,脚本将返回“BOO”
cmd="egrep -i 'Hello' /home/me/foo.txt"
if [ -n $cmd ]
then
$cmd
if [ $? -eq 0 ]
then
echo "YAY"
else
echo "BOO"
fi
fi
我一直在捣乱我的大脑尝试不同的报价逃脱,仍然是$?只要$ cmd变量中有引号,就返回1。如何使用引号格式化$ cmd以返回0?任何帮助将不胜感激。
答案 0 :(得分:3)
最安全的选择是使用数组:
cmd=(egrep -i 'Hello' /home/me/foo.txt)
if (( ${#cmd[@]} > 0 ))
then
"${cmd[@]}"
if [ $? -eq 0 ]
then
echo "YAY"
else
echo "BOO"
fi
fi
答案 1 :(得分:1)
如果您需要导出使用引号供其他人编写的代码使用的代码(以及您无法更改的代码),那么一个可靠的方法(只要该解释器是bash)就是导出功能:
myCmd() { egrep -i 'Hello' /home/me/foo.txt; }
cmd=myCmd
export -f myCmd; export cmd
此后,$cmd
会致电myCmd
,致电egrep -i 'Hello' /home/me/foo.txt
。
重要的是,如果您的Hello
实际上来自您不信任的来源。使用字符串替换将不受信任的字符串放入某些代码中会很危险 - 但如果将其导出到环境变量中,则可以安全地引用该环境变量:
# Assume this is in our environment, and came from an untrusted source
stringToSearchFor=$'$(rm -rf ~)\'$(rm -rf ~)\''
myCmd() { egrep -i "$stringToSearchFor" /home/me/foo.txt; }
export -f myCmd
export stringToSearchFor
然而,非常不安全,比如说:
# DO NOT DO THIS: WILL DELETE YOUR HOME DIRECTORY IF EVAL'D (w/ above malicious sample)
cmd="grep '${stringToSearchFor}' /home/me/foo.txt"
答案 2 :(得分:0)
在这种情况下,您想使用eval $cmd
。 Eval执行命令就像在shell上键入命令一样,并返回您运行的退出状态。
if [ -n "$cmd" ]
then
eval "$cmd"
if [ $? -eq 0 ]
then
echo "YAY"
else
echo "BOO"
fi
fi