繁体   English   中英

以bash转义引号(Embedded awk)

[英]Escaping quotes in bash (Embedded awk)

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

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

显然,print语句的.log部分周围的“令我失败。我的想法是,我将从文件名中删除.out部分,最后得到file20171119.log作为结束结果。语法或有关如何正确进行转义的内容,因此bash会正确解释.log。

解决此问题的最简单方法是避免它。 不要费心尝试转义脚本以进入命令行:而是在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

一个带引号的heredoc-用<<'EOF'<<\\EOF代替<<EOF -按<<EOF传递,没有任何shell扩展; 因此, $1$3将不会被调用shell替换,就像用未引用的heredoc那样。


如果您不想走回避路线,则可以让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"

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

您需要转义"以防止它们提早关闭带引号的字符串,并且需要转义awk脚本中的$以防止局部参数扩展。

ssh root@server1 "gzip -d /tmp/file.out-20171119.gz; echo file* | awk -F'[.-]' '{print \$1\$3\".log\"}'"

最可能的原因(因为您未在服务器中显示root主目录的内容)是您要解压缩/tmp目录中的文件,但要提供到root主目录中应存在的awk文件名。

"允许用\\转义序列,因此正确的做法是

ssh root@server1 "gzip -d /tmp/file.out-20171119.gz; echo file* | awk -F'[.-]' '{print \$1\$3\".log\"}'"

(就像您在问题中所写的一样),这意味着以下命令是使用服务器计算机中的外壳执行的。

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

您正在执行两个命令,第一个命令对/tmp/file.out-2017119.gz进行gunzip(请注意, 因为它将被压缩/tmp )。 第二个可能是问题的根源。 它回显本地目录 (这是root用户主目录,可能是服务器中的/root )中所有以名称(可能没有)开头的file ,并将其提供给下一个awk命令。

作为一般规则...。在本地测试您的命令,当它在本地工作时,只需在第一个shell解析后转义所有将转义的特殊字符即可。

解决该问题的另一种方法是使用gzip(1)作为过滤器...因此您可以确定输出文件的名称

ssh root@server1 "gzip -d </tmp/file.out-20171119.gz >file20171119.log"

这样,您保存awk(1)执行只是为了格式化输出文件。 或者,如果您有来自环境变量的日期。

DATE=`date +%Y%m%d`
ssh root@server1 "gzip -d </tmp/file.out-${DATE}.gz >file${DATE}.log"

最后,让我给出一些建议:不要使用/tmp解压缩文件。 /tmp被多个发行版用作高速临时目录。 它通常是基于ram的,速度太快,但是空间有限,因此解压缩日志文件可能会填满用于基于ram的文件系统的内核内存,这不是一个好主意。 另外,日志文件通常会扩展很多, /tmp是本地系统常规目录,其他用户可以在其中存储名为file<something>并且您可以与这些文件冲突(以防万一,例如使用通配符模式进行搜索同样在您知道将文件分配给环境变量并使用这些变量的文件名后,这很常见,因此,如果您需要更改文件名的格式,则只需在一个地方进行即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM