コマンドの戻りステータスをテストしてバージョン管理システムを検出するBashスクリプト


11

いくつかの種類のVCSで使用したいbashスクリプトを作成しています。典型的な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し、使用$?そのリターンコードを取得します。

私の質問は、戻りコード番号を1行で実行して返すためのきちんとした方法はありますか?例えば

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

または、関数を定義する必要がありますか?

追加の要件として、stderrとstdoutの両方を印刷する必要があります。

回答:


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"

最初の2つexecstdinstderrファイル記述子を保存し、3番目は両方に/dev/null(または必要に応じて他の場所に)リダイレクトします。最後の2つexecは、ファイル記述子を再び復元します。その間のすべてがどこにもリダイレクトされません。

Gillesが提案したように、他のリポジトリチェックを追加します。


見た目もすっきりしていますが、これらのメソッドはユーザーにメッセージを出力します。スクリプトはサイレントにすることをお勧めします(これを質問に追加しました)。
Niall Murphy、

2
なぜこれらをサブシェルで実行しているのですか?不要です。
Chris Down

4

他の人がすでに述べたように、成功するif commandかどうかをテストしcommandます。実際に[ … ]は、通常のコマンドであり、まれですが、ifまたは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

2

まあ、それはあまりきれいではありませんが、インラインで実行する1つの方法です。

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

定義により、ifはコマンドの終了コードをテストするので、成功または失敗以上のものを必要としない限り、明示的な比較を行う必要はありません。これを行うには、おそらくもっとエレガントな方法があるでしょう。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.