Bash脚本:egrep不返回带有变量的单引号的结果

时间:2018-02-16 15:26:18

标签: bash scripting

我正在编写一个简单的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?任何帮助将不胜感激。

3 个答案:

答案 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