I am working on a bash script that I would like to work for several types of VCS. I am thinking of testing if a directory is a repo for a system by running a typical info command and checking the return code, success or error. In pseudo code:

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
    something else

I can run a command, e.g. darcs show repo and use $? to get its return code.

My question is: is there a neat way to run and return the return code number in one line? for example

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

Or do I have to define a function?

An added requirement is that both stderr and stdout should be printed.


If automatically checks the return code:

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

You could also run the command and use && (logical AND) or || (logical OR) afterwards to check if it succeeded or not:

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

Redirecting stdout and stderr can be done once with exec

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

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

# 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"

The first two exec are saving the stdin and stderr file descriptors, the third redirects both to /dev/null (or somewhere other if wished). The last two exec restore the file descriptors again. Everything in between gets redirected to nowhere.

Append other repo checks like Gilles suggested.

  • Nice and clean, however these methods print out messages to the user. I would prefer the script to be silent (I have added this to the question). – Niall Murphy Dec 13 '10 at 18:55
  • 2
    Why are you running these in a subshell? It's unnecessary. – Chris Down Dec 3 '11 at 16:09

As others have already mentioned, if command tests whether command succeeds. In fact [ … ] is an ordinary command, which can be used outside of an if or while conditional although it's uncommon.

However, for this application, I would test the existence of the characteristic directories. This will be correct in more edge cases. Bash/ksh/zsh/dash version (untested):

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

Well, it's not very pretty, but it's one way to do it inline:

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

By definition, if tests the exit code of a command, so you don't need to do an explicit comparison, unless you want more than success or failure. There's probably a more elegant way to do this.


Another succinct option would be:

[ -d .svn ] && { svn command 1; svn command 2; } 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.