Git /bin/bash-c,子shell作为命令的一部分
我想知道是否有未提交Git的文件,我访问系统的唯一方法是通过/bin/bash-c传递命令 例如: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
/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,则启动此命令的
是一个回退。