【问题标题】:Constructing arguments to command that requires quotes [duplicate]为需要引号的命令构造参数[重复]
【发布时间】:2018-10-04 20:37:46
【问题描述】:

我有一个 Bash 脚本,它需要调用一个命令,该命令需要为它的一个参数加上引号。当我运行命令时

myTimeCommand --time="2018 04 23 1100" -o /tmp/myOutput ~/myInput

从命令行,它工作正常。在我的脚本中,我想将“2018 04 23 1100”作为参数传递并直接发送给命令。

myScript --time="2018 04 23 1100"

但是,当我尝试这个时,我收到一条错误消息,

""2018" is not a valid time.

我正在使用getopt 来解析参数。这是我的脚本

OPTIONS=t:
LONGOPTIONS=time:

PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@")
echo ${PARSED}

# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

# now enjoy the options in order and nicely split until we see --
while true; do
    echo "option: ${1}"
    case "$1" in
        -t|--time)
            timeBase="$2"
            timeBase="--time=\"${timeBase}\""
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Programming error"
            exit 3
            ;;
    esac
done

echo ${timeBase}

myTimeCommand ${timeBase} -o /tmp/myOutput ~/myInput

编辑:删除了 runCommand() 函数。虽然这产生了一些不错的 cmets,但从手头的问题中分心 - 复制引用的参数以使用命令运行。

第二个例子: 带有

的文本文件 (myTest.txt)
I have a Bash script that needs to call a command that will require quotes for one of it's arguments.  When I run the command

myTimeCommand --time="2018 04 23 1100" -o /tmp/myOutput ~/myInput

from the command line, it works fine.  In my script, I want to pass "2018 04 23 1100" as a parameter and send it directly to the command.

当我运行grep "command line" myTest.txt 时,我在最后一行得到了命中(如预期的那样)。当我将脚本修改为

OPTIONS=s:
LONGOPTIONS=str:

PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@")

echo ${PARSED}

# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

# now enjoy the options in order and nicely split until we see --
while true; do
    echo "option: ${1}"
    case "$1" in
        -s|--str)
            sStr="\"$2\""
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Programming error"
            exit 3
            ;;
    esac
done

echo "grep ${sStr} myTest.txt"

grep ${sStr} myTest.txt

echo 按预期显示命令,但实际 grep 失败

-bash-4.2~>./extText --str="command line"
grep "command line" myTest.txt
grep: line": No such file or directory

如何使用我传入的参数调用 grep(本例中为“命令行”)?

【问题讨论】:

  • 试试cmd=$(printf 'myTimeCommand "%s" -o /tmp/myOutput ~/myInput' "${timeBase}"。使用 timeBase 普通值,不添加任何引号。
  • 我正在尝试将命令放入变量中,但复杂的情况总是失败! BashFAQ/050
  • @LuisMuñoz,与 OP 的原始代码有同样的错误——当需要语法引号时,它仍然会生成带有文字引号的字符串;但是,字符串的扩展不会将引号解析为语法,因此字符串扩展中的引号永远不会是语法(除非使用eval,调用带有作为代码传递的字符串的新shell,或者另一个等价于从头开始强制重新解析——所有这些都会导致更大的问题)。
  • @charles-duffy,感谢您的澄清。稍后会尝试这些东西。

标签: bash shell quotes


【解决方案1】:

不要使用变量来运行命令!它们用于保存数据而不是函数。使用数组

cmdArray=()
cmdArray=( "myTimeCommand" "${timeBase}" "-o" "/tmp/myOutput" "~/myInput" )

并传递带引号的数组以防止分词

runCommand "${cmdArray[@]}"

BashFAQ/050 - I'm trying to put a command in a variable, but the complex cases always fail!

【讨论】:

    猜你喜欢
    • 2018-02-13
    • 2020-05-24
    • 2021-02-15
    • 2012-09-15
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    相关资源
    最近更新 更多