在shell脚本中转​​义单引号

时间:2017-04-23 13:02:18

标签: linux bash shell

我需要在变量中转义单引号。

ssh_command 'file=$(hostname)_server-setup_$(date +%Y-%m-%d).tar.gz && cd /var && tar -zcvf $file ini | wc -l | xargs printf \'Num files: %d, File: $file\''

我可以用双引号括起变量但是当声明变量时会评估内部变量,而这不是我想要的。

ssh_command "file=$(hostname)_server-setup_$(date +%Y-%m-%d).tar.gz && cd /var && tar -zcvf $file ini | wc -l | xargs printf 'Num files: %d, File: $file'"

更新

现在已经提出了这个问题,但$file只打印为$file

ssh_command (){
    ssh root@host $1
}

ssh_command 'file=$(hostname)_server-setup_$(date +%Y-%m-%d).tar.gz && cd /var && tar -zcvf $file ini | wc -l | xargs printf '"'"'Num files: %d, File: $file'"'"

输出

Num files: 61, File: $file

2 个答案:

答案 0 :(得分:3)

当通过SSH发送一个复杂的命令(使用引号,美元符号,分号)时,我更喜欢base64编码/解码它。在这里,我发了base64_ssh.bash

#!/bin/bash
script64=$(cat script.txt | base64 -w 0)
ssh 127.0.0.1 "echo $script64 | base64 -d | bash"

在上面的示例中,只需在script.txt中放置要在远程服务器上运行的命令,然后运行bash脚本。

这确实需要一个额外的文件,但不必转义引号或其他特殊字符,这在我看来是一个更好的解决方案。

这也适用于创建功能。

它的工作方式是将命令转换为base64编码的字符串,该字符串具有更简单的字符集(Wikipedia base64),并且这些字符永远不需要转义。然后,一旦它在另一边,它就被解码,然后通过管道传输给bash解释器。

要使用上面的示例,请将以下内容放入script.txt

file=$(hostname)_server-setup_$(date +%Y-%m-%d).tar.gz && cd /var && tar -zcvf $file ini | wc -l | xargs printf "Num files: %d, File: $file"

答案 1 :(得分:3)

对于这个不太大的命令,我不会过度复杂化它并坚持使用原始的双引号,而只是逃避不应在本地扩展的$

ssh_command "file=\$(hostname)_server-setup_$(date +%Y-%m-%d).tar.gz && cd /var && tar -zcvf \$file ini | wc -l | xargs printf 'Num files: %d, File: \$file'"