Bash,变量和转义符号

时间:2014-08-26 09:23:38

标签: linux git bash ssh

我有一个脚本通过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\)"

1 个答案:

答案 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。 (这不是一个非常重要的错误,但它仍然不是真的。)