我有一个脚本通过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\)"
答案 0 :(得分:2)
双引号内的事物具有可变扩展和命令替换。所以,例如:
ssh remotehost "echo $(pwd)"
将让其他主机回应pwd
在本地主机上生成的内容。 (即,$(pwd)
首先在这里运行,然后像echo /home/user/current/dir
这样的东西被发送到远程主机,它尽职地回应现在常量的字符串。)
您需要阻止命令替换(以任何合适的方式,例如使用单引号):
ssh remotehost 'echo $(pwd)'
将文字字符串echo $(pwd)
传递给远程主机(在该主机上使用的任何shell都将对其进行操作)。
除此之外,您可以对命令序列进行一些小的改进:
git status
documentation建议在脚本中使用--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
。 (这不是一个非常重要的错误,但它仍然不是真的。)