/ bin / bash -c with subshel​​l作为命令的一部分

时间:2015-04-20 23:10:57

标签: git bash

我想知道Git是否存在任何未提交的文件,我访问系统的唯一方法是通过/ bin / bash -c传递命令。

例如: /bin/bash -c [[ $(git status --porcelain 2>/dev/null | wc -l) == 0 ]] && echo "done"

可悲的是,我能想到的所有变化都会失败。以上命令失败: "sh: 1: [[: not found "

看起来它正在执行wc -l的结果。我该如何解决这个问题?

由于

1 个答案:

答案 0 :(得分:4)

行情!

/bin/bash -c [[ $(git status --porcelain 2>/dev/null | wc -l) == 0 ]] && echo "done"

...没有像您想象的那样将-c传递给bash之后的整个字符串。相反,shell解释此命令会运行$()本身的扩展,并且只会在&&之前传递内容到bash,执行echo本身。

解决这个问题,得到:

/bin/bash -c '(( $(git status --porcelain 2>/dev/null | wc -l) == 0 )) && echo "done"'

如果仍然无效,那么您错误地认为您的代码是使用bash -c运行的;相反,它与sh -c一起运行,并且需要进行一些不同的更改才能兼容。

/bin/sh -c '[ "$(git status --porcelain 2>/dev/null | wc -l)" -eq 0 ] && echo "done"'

具体做法是:

  • 使用POSIX兼容的[命令而非[[ ]](用于字符串比较的bash扩展语法)或(( ))(用于数字比较的bash扩展语法)。
  • 双引号测试运算符两侧的扩展
  • 使用POSIX兼容的数字相等运算符-eq而不是==(这是(1)POSIX规范不保证的bash扩展名,以及(2) string < / em>比较,而不是数字比较)。