在 bash 中转义引号(嵌入式 awk)

Chr*_*tti 1 linux bash awk

我有一个复杂的命令,我通过 ssh 传递到远程服务器。我正在尝试解压缩文件,然后在第二个 ssh 命令中更改其命名结构和扩展名。我的命令是:

ssh root@server1 "gzip -d /tmp/file.out-20171119.gz; echo file* | awk -F'[.-]' '{print $1$3".log"}'"
Run Code Online (Sandbox Code Playgroud)

显然,打印语句的 .log 部分周围的 " 使我失败了。这个想法是我将从文件名中删除 .out 部分,并以 file20171119.log 作为结束结果。我只是有点困惑语法或如何正确转义,以便 bash 适当地解释 .log。

Cha*_*ffy 5

处理这个问题的最简单方法是避免它。不要费心尝试将脚本转义到命令行:改为将其传递到 stdin。

ssh root@server1 bash -s <<'EOF'
  gzip -d /tmp/file.out-20171119.gz
  # note that (particularly w/o a cd /tmp) this doesn't do anything at all related to the
  # line above; thus, probably buggy as given in the original question.
  echo file* | awk -F'[.-]' '{print $1$3".log"}'
EOF
Run Code Online (Sandbox Code Playgroud)

引用的 heredoc —— 一个带有<<'EOF'<<\EOF代替<<EOF—— 是按字面传递的,没有任何 shell 扩展;因此,$1或者$3不会像使用未引用的 heredoc 那样被调用 shell 替换。


如果你不想走回避路线,你可以让 shell 自己为你做引用。例如:

external_function() {
  gzip -d /tmp/file.out-20171119.gz
  echo file* | awk -F'[.-]' '{print $1$3".log"}'
}

ssh root@server1 "$(declare -f external_function); external_function"
Run Code Online (Sandbox Code Playgroud)

declare -f打印函数的定义。将该函数从字面上放入您的 SSH 命令可确保它远程运行。