Скрипт 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.

Ответы:


15

Если автоматически проверяет код возврата:

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
Почему вы запускаете их в подоболочке? Это не нужно.
Крис Даун

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

Ну, это не очень красиво, но это один из способов сделать это встроенным:

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

По определению, если тестирует код завершения команды, вам не нужно делать явное сравнение, если только вы не хотите большего, чем успех или неудача. Вероятно, есть более элегантный способ сделать это.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.