Bash脚本通过测试命令返回状态来检测版本控制系统


11

我正在开发一个bash脚本,该脚本要用于几种类型的VCS。我正在考虑通过运行典型的info命令并检查返回码,成功或错误来测试目录是否是系统的存储库。用伪代码:

if a svn command succeded;
    Then run svn commands
elif a darcs command succeded;
    Then run darcs commands
elif a mercurial command succeded;
    then run hg commands
else 
    something else
fi

我可以运行一个命令,例如, darcs show repo并用于$?获取其返回代码。

我的问题是:是否有一种巧妙的方法可以在一行中运行并返回返回码号?例如

if [ 0 -eq `darcs show repo`$? ]; 

还是我必须定义一个功能?

附加要求是应同时打印stderr和stdout。

Answers:


15

如果自动检查返回码:

if (darcs show repo); then
  echo "repo exists"
else
  echo "repo does not exist"
fi

您也可以运行命令并使用&&(逻辑AND)或||。(逻辑OR)之后检查其是否成功:

darcs show repo && echo "repo exists"
darcs show repo || echo "repo does not exist"

重定向stdoutstderr可以完成一次exec

exec 6>&1
exec 7>&2
exec >/dev/null 2>&1

if (darcs show repo); then
  repo="darcs"
elif (test -d .git); then
  repo="git"
fi

# The user won't see this
echo "You can't see my $repo"

exec 1>&6 6>&-
exec 2>&7 7>&-

# The user will see this
echo "You have $repo installed"

前两个exec保存stdin和的stderr文件描述符,第三个同时重定向到/dev/null(或希望的其他位置)。最后两个exec再次恢复文件描述符。介于两者之间的所有内容都将重定向到无处。

像吉尔斯建议的那样附加其他回购检查。


不错,很干净,但是这些方法将消息打印给用户。我希望脚本保持沉默(我已将此问题添加到问题中)。
Niall Murphy

2
您为什么要在子shell中运行它们?没必要
克里斯·

4

正如其他人已经提到的那样,if command测试是否command成功。实际上[ … ],这是一个普通命令,尽管不常见,但可以在ifwhile有条件的命令之外使用。

但是,对于此应用程序,我将测试特征目录的存在。在更多情况下这是正确的。Bash / ksh / zsh / dash版本(未试用):

vc=
if [ -d .svn ]; then
  vc=svn
elif [ -d CVS ]; then
  vc=cvs
else
  d=$(pwd -P)
  while [ -n "$d" ]; do
    if [ -d "$d/.bzr" ]; then
      vc=bzr
    elif [ -d "$d/_darcs" ]; then
      vc=darcs
    elif [ -d "$d/.git" ]; then
      vc=git
    elif [ -d "$d/.hg" ]; then
      vc=hg
    fi
    if [ -n "$vc" ]; then break; fi
    d=${d%/*}
  done
fi
if [ -z "$vc" ]; then
  echo 1>&2 "This directory does not seem to be under version control."
  exit 2
fi

2

好吧,它不是很漂亮,但是它是内联完成的一种方法:

if darcs show repo > /dev/null 2>&1; then <do something>; fi

根据定义,如果测试命令的退出代码,则无需进行显式比较,除非您希望获得成功或失败以外的其他信息。可能有一种更优雅的方法可以做到这一点。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.