Bash script untuk mendeteksi sistem kontrol versi dengan menguji status pengembalian perintah

11

Saya sedang mengerjakan skrip bash yang ingin saya gunakan untuk beberapa jenis VCS. Saya berpikir untuk menguji apakah direktori adalah repo untuk sistem dengan menjalankan perintah info khas dan memeriksa kode kembali, berhasil atau kesalahan. Dalam kode semu:

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

Saya dapat menjalankan perintah, misalnya darcs show repodan gunakan $?untuk mendapatkan kode pengembaliannya.

Pertanyaan saya adalah: apakah ada cara yang rapi untuk menjalankan dan mengembalikan nomor kode pengembalian dalam satu baris? sebagai contoh

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

Atau apakah saya harus mendefinisikan suatu fungsi?

Persyaratan tambahan adalah stderr dan stdout harus dicetak.

Niall Murphy
sumber

Jawaban:

15

Jika secara otomatis memeriksa kode kembali:

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

Anda juga bisa menjalankan perintah dan menggunakan && (logis DAN) atau || (logis ATAU) setelah itu untuk memeriksa apakah berhasil atau tidak:

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

Pengarahan ulang stdoutdan stderrdapat dilakukan sekali denganexec

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"

Dua yang pertama execadalah menyimpan file stdindan stderrdeskriptor, yang ketiga mengarahkan keduanya ke /dev/null(atau di tempat lain jika diinginkan). Dua terakhir execmengembalikan file deskriptor lagi. Segala sesuatu di antaranya akan dialihkan ke mana-mana.

Tambahkan cek repo lain seperti yang disarankan Gilles.

mengibaskan
sumber
Bagus dan bersih, namun metode ini mencetak pesan kepada pengguna. Saya lebih suka skripnya diam (saya telah menambahkan ini ke pertanyaan).
Niall Murphy
2
Mengapa Anda menjalankan ini dalam subkulit? Itu tidak perlu.
Chris Down
4

Seperti yang telah disebutkan orang lain, if commandtes apakah commandberhasil. Sebenarnya [ … ]adalah perintah biasa, yang dapat digunakan di luar ifatau whilebersyarat meskipun itu tidak biasa.

Namun, untuk aplikasi ini, saya akan menguji keberadaan direktori karakteristik. Ini akan benar dalam banyak kasus tepi. Versi Bash / ksh / zsh / dash (belum diuji):

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
Gilles 'SANGAT berhenti menjadi jahat'
sumber
2

Yah, itu tidak terlalu cantik, tapi itu salah satu cara untuk melakukannya sebaris:

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

Menurut definisi, jika menguji kode keluar dari suatu perintah, maka Anda tidak perlu melakukan perbandingan eksplisit, kecuali jika Anda menginginkan lebih dari keberhasilan atau kegagalan. Mungkin ada cara yang lebih elegan untuk melakukan ini.

SethG
sumber
0

Opsi ringkas lainnya adalah:

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