【问题标题】:Write a user supplied command to file将用户提供的命令写入文件
【发布时间】:2019-09-06 18:35:45
【问题描述】:

我需要使用 bash 将用户提供的命令写入文件。

测试用例是script.sh -- echo "Hello \$USER",我想要一个包含echo "Hello $USER"(或echo Hello\ $USER)的文件,可以执行

我正在使用 heredoc 写入文件,所以类似于

cat > "${FILE}" <<EOF
Your command is:
${CMD}
"$@"
EOF

我尝试使用printf -v CMD '%q ' "$@",但这导致echo Hello\ \$USER 这不是我想要的。

我该怎么做?

【问题讨论】:

  • 您使用%q 格式有什么原因吗?因为我刚刚尝试使用 %s 并且它有效
  • 你可以像这样使用$* printf "Your command is $*\n"
  • 问题是引号/空格:使用 $*%s 将导致 echo Hello $USER -> 2 个参数而不是 1 个。这是一个问题,例如cat "foo with bar" -> cat foo with bar
  • 您想要引用空格而不是美元符号?如果是这样,您将不得不进行一些手动字符串操作;没有转义机制可以透视地知道引用一个但不引用另一个。
  • 问题从提供给脚本的内容开始。你能让用户引用整个字符串吗? script.sh -- 'echo "Hello $USER"' 将是小菜一碟。

标签: bash heredoc variable-expansion


【解决方案1】:

根据手动执行的建议,我使用以下推理提出以下建议:

  • "$@" 语法意味着:将所有 args 扩展为 "$1" "$2" ...
  • 这在我的情况下似乎不起作用,因此请手动执行:
    CMD=()
    for var in "$@"; do
        CMD+=( '"'"${var}"'"' )
    done

    cat > ${FILE} <<EOF
    Your command is: 
    ${CMD[@]}

所以基本上:创建一个带引号的字符串数组。然后打印这个。这适用于测试用例。

但是:它在很多其他事情上都失败了。示例:myScript.sh -- echo "Hello \"\$USER\"" 不转义引号。

所以我得出结论,这项任务是不可能的或至少不可行,并建议使用基于 printf 的解决方案,这似乎也是其他命令处理它的方式(例如:srun/sbatch 上 SLURM)

【讨论】:

    猜你喜欢
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2018-10-14
    相关资源
    最近更新 更多