[英]Bash, variables and escaping symbols
我有一个脚本,该脚本通过SSH连接到测试服务器并检索当前的Git分支。 当我尝试使用变量来打印分支和已修改文件数量的计数时,我会使用转义符号进行堆叠。
以下内容适用于本地文件夹:
mc=$(git status -s | grep -E '^[^?]+' -c);
branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \1/');
echo $branch \($mc\)
但这不起作用:
ssh -i ~/.ssh/id_rsa.cron local.stage "cd /var/www && mc=$(git status -s | grep -E '^[^?]+' -c);
branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \1/');
echo $branch \($mc\)"
双引号内的内容具有变量扩展和命令替换功能。 因此,例如:
ssh remotehost "echo $(pwd)"
将使其他主机回显pwd
在本地主机上产生的内容。 (即, $(pwd)
首先在此处运行,然后将类似echo /home/user/current/dir
内容发送到远程主机,该主机将忠实地回显现在不变的字符串。)
您需要防止命令替换(以任何合适的方式,例如,使用单引号):
ssh remotehost 'echo $(pwd)'
它将原义字符串echo $(pwd)
传递到远程主机(在该主机上,无论您在该主机上使用任何shell都将对其起作用)。
除此之外,您还可以对命令序列进行一些小的改进:
git status
文档建议在脚本中使用--porcelain
而不是--short
( -s
)。 git symbolic-ref -q --short HEAD
(这比使用git branch
并提取*
-ed行并进行修改要简单得多)。 将它们放在一起并将内部引号转换为双引号(这是可以的,因为那里不会发生替换):
ssh -i ~/.ssh/id_rsa.cron local.stage 'cd /var/www &&
mc=$(git status --porcelain | grep -E "^[^?]+" -c);
branch=$(git symbolic-ref -q --short HEAD);
echo $branch \($mc\)'
这里仍然存在一个错误:请注意&&
与分号之间的绑定。 如果/var/www
不存在,则会使mc
设置状态,并继续尝试设置branch
。 (这不是一个非常重要的错误,但是仍然不是很正确。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.