【问题标题】:Bash, variables and escaping symbolsBash、变量和转义符号
【发布时间】:2014-08-26 17:42:58
【问题描述】:

我有一个通过 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) 使用heredoc 而不是将所有指令放在第一行 2) it won't work 是什么意思?一般来说,当您使用 ssh 转义某些内容时,这意味着它将在您的远程计算机上进行解释。否则,将在本地解释。你的问题可能就在这里。

标签: linux git bash ssh


【解决方案1】:

双引号内的内容执行变量扩展和命令替换。所以,例如:

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。 (这不是一个非常严重的错误,但它仍然不太正确。)

【讨论】:

  • Torek,非常感谢您的详细解释。我在你的回答中发现了很多有趣的东西。再次感谢您提供完整的解决方案。
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 2017-07-26
  • 2014-09-06
  • 2011-06-11
  • 2017-11-20
  • 2013-11-22
  • 1970-01-01
  • 2012-06-24
相关资源
最近更新 更多