Git /bin/bash-c,子shell作为命令的一部分

Git /bin/bash-c,子shell作为命令的一部分,git,bash,Git,Bash,我想知道是否有未提交Git的文件,我访问系统的唯一方法是通过/bin/bash-c传递命令 例如: /bin/bash-c[$(git状态--2>/dev/null | wc-l)==0]&&echo“完成” 可悲的是,我能想出的所有变化都失败了。上述命令失败,原因如下: “sh:1:[[:未找到 “ 它看起来像是在执行wc-l的结果。我该如何解决这个问题 谢谢 本引用 /bin/bash -c [[ $(git status --porcelain 2>/dev/null | wc -l

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

例如:
/bin/bash-c[$(git状态--2>/dev/null | wc-l)==0]&&echo“完成”

可悲的是,我能想出的所有变化都失败了。上述命令失败,原因如下:
“sh:1:[[:未找到
“

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

谢谢

引用

/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)用于字符串比较,而不是数字比较)
    • 引用

      /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)用于字符串比较,而不是数字比较)


      [[:not found
      ,如
      sh:
      ,表示正在使用的shell是
      sh
      ,而不是
      bash
      。顺便说一句,错误消息中的
      1
      是发生错误的行号,而不是
      wc-l
      的输出。如果您只想查看git status命令是否产生任何输出,可以使用
      git sta>tus--Cerlier 2>/dev/null | grep-q.| echo done
      -
      grep-q
      如果任何模式匹配并且
      匹配任何字符,则返回成功…或者更有效地:
      git status--Cerlier 2>/dev/null |{read&[$REPLY]]}
      ,避免任何外部工具的需要(而且——就像
      grep-q
      方法一样——阅读不超过一行)。
      [[:not found
      ,如
      sh:
      ,表示正在使用的shell是
      sh
      ,而不是
      bash
      。顺便说一句,错误消息中的
      1
      是发生错误的行号,而不是
      wc-l
      的输出。如果您只想查看git status命令是否产生任何输出,可以使用
      git sta>tus--Cerlier 2>/dev/null | grep-q.| echo done
      -
      grep-q
      如果任何模式匹配并且
      匹配任何字符,则返回成功…或者更有效地:
      git status--Cerlier 2>/dev/null |{read&[$REPLY]]}
      ,避免任何外部工具的需要(就像grep-q方法一样——只读一行)。谢谢,这听起来很合乎逻辑,但我猜答案是
      /bin/bash:($(git status-2>/dev/null | wc-l)==0))&回显“完成”:没有与未传递
      -c
      时得到的文件或目录一致的文件或目录。我的日志似乎是正确的-
      exec\u start:/bin/bash-c'($(git status--2>/dev/null | wc-l)==0))&echo \“完成\”“
      问题:你能从命令行重现这个问题吗?如果我给你的代码在命令行中起作用,那么我们已经证明这个问题本质上是环境问题。如果你想知道你的环境出了什么问题--
      sysdig-v evt.type=execve
      将是理想的;
      strace-s 2048-e execv-f/path/to/command-如果您没有sysdig,那么启动此命令是一种回退。谢谢,这听起来非常符合逻辑,但我猜响应是
      /bin/bash:(($(git status--2>/dev/null | wc-l)==0))&&echo“done”:没有与未传递
      -c
      时得到的文件或目录一致的文件或目录。我的日志似乎是正确的-
      exec\u start:/bin/bash-c'($(git status--2>/dev/null | wc-l)==0))&echo \“完成\”“
      问题:你能从命令行重现这个问题吗?如果我给你的代码在命令行中起作用,那么我们已经证明这个问题本质上是环境问题。如果你想知道你的环境出了什么问题--
      sysdig-v evt.type=execve
      将是理想的;
      strace-s 2048-e execv-f/path/to/command-如果您没有sysdig,则启动此命令的
      是一个回退。