我正在编写一个 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 都应该被打印。
答案1
如果自动检查返回码:
if (darcs show repo); then
echo "repo exists"
else
echo "repo does not exist"
fi
您还可以运行命令并使用 &&(逻辑与)或 || (逻辑或)之后检查是否成功:
darcs show repo && echo "repo exists"
darcs show repo || echo "repo does not exist"
重定向stdout
并且stderr
可以完成一次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
再次恢复文件描述符。中间的所有内容都会被重定向到任何地方。
像吉尔斯建议的那样附加其他回购检查。
答案2
正如其他人已经提到的,if command
测试是否command
成功。实际上是一个普通命令,尽管不常见,但[ … ]
可以在if
or条件之外使用。while
但是,对于此应用程序,我将测试特征目录是否存在。这在更多边缘情况下是正确的。 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
答案3
嗯,它不是很漂亮,但它是内联执行此操作的一种方法:
if darcs show repo > /dev/null 2>&1; then <do something>; fi
根据定义,if 测试命令的退出代码,因此您不需要进行显式比较,除非您想要的不仅仅是成功或失败。可能有一种更优雅的方法来做到这一点。
答案4
另一个简洁的选择是:
[ -d .svn ] && { svn command 1; svn command 2; }