Лучшая практика для использования $? в ударе?

Добавьте пользователя к wheel группа:

gpasswd wheel -a username

Я использую gpasswd потому что не все версии usermod имейте простой способ добавить пользователя к группе, не изменяя группы всех пользователей. Однако на любом недавнем Fedora, usermod username -a -G wheel должен иметь тот же эффект. Вы могли также использовать system-config-users GUI, конечно.

При использовании Fedora 14 или ранее использовать visudo отредактировать sudoers файл, удаляя # от этой строки:

%wheel  ALL=(ALL)       ALL

Это - значение по умолчанию в sudoers файле на Fedora 15 и более новый, настолько добавляющий пользователя к wheel все, что необходимо сделать. Обратите внимание, что это сразу не вступит в силу; самая легкая вещь сделать, выходят и заходят снова.

См. также этот вопрос и ответ на Отказе сервера для получения информации о предоставлении подобного sudo "автора как сам" поведение к wheel элементы группы для графических приложений, которые используют consolehelper или PackageKit.

10
13.04.2017, 15:36
3 ответа

Один распространенный способ:

die() {
    IFS=' ' # make sure "$*" is joined with spaces

    # output the arguments if any on stderr:
    [ "$#" -eq 0 ] || printf '%s\n' "$*" 1>&2
    exit 1
}

затем Вы используете его как это:

mkdir -p some/path || die "mkdir failed with status $?"

Или если Вы хотите, чтобы это включало статус выхода, Вы могли бы изменить его на:

die() {
    last_exit_status=$?
    IFS=' '
    printf '%s\n' "FATAL ERROR: $* (status $last_exit_status)" 1>&2
    exit 1
}

и затем использование его немного легче:

mkdir -p some/path || die "mkdir failed"

Когда это перестало работать, mkdir вероятно, уже выпустит сообщение об ошибке, так, чтобы второй мог рассматриваться как избыточный, и Вы могли просто сделать:

mkdir -p some/path || exit   # with the same (failing) exit status as mkdir's
mkdir -p some/path || exit 1 # with exit status 1 always

(или используйте первый вариант die выше без аргумента)

На всякий случай Вы не видели command1 || command2 прежде, это работает command1, и если command1 сбои, это работает command2.

Таким образом, можно читать, это как "делает каталог или умирает".

Ваш пример был бы похож:

mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"

Или можно выровняться dies далее справа так, чтобы основной код более очевиден.

mkdir -p some/path         || die "mkdir failed"
cd some/path               || die "cd failed"
some_command               || die "some_command failed"

Или на следующей строке, когда командные строки долги:

mkdir -p some/path ||
  die "mkdir failed"

cd some/path ||
  die "cd failed"

some_command ||
  die "some_command failed"

Кроме того, если Вы собираетесь использовать имя some/path многократно, сохраните его в переменной, таким образом, Вы не должны продолжать вводить его и можете легко изменить его, если Вы должны. И при передаче аргументов переменной командам, удостоверьтесь, что использовали -- разделитель опции так, чтобы аргумент не был взят в качестве опции, если это запускается с -.

dir=some/path
mkdir -p -- "$dir"         || die "Cannot make $dir"
cd -P -- "$dir"            || die "Cannot cd to $dir"
some_command               || die "Cannot run some_command"
15
27.01.2020, 19:59

Вы могли переписать свой код как это:

#!/bin/bash
function try {
    "$@"
    code=$?
    if [ $code -ne 0 ]
    then
        echo "$1 did not work: exit status $code"
        exit 1
    fi
}

try mkdir -p some/path
try cd some/path
try run_some_command

Если Вы не должны на самом деле регистрировать код ошибки, но просто успешно выполнилась ли команда или нет, можно сократиться try() далее как так:

function try {
    if ! "$@"
    then
        echo "$1 did not work"
        exit 1
    fi
}
9
27.01.2020, 19:59
  • 1
    Можно также использовать код в этом формате. <пред> функциональная попытка { –  BillThor 07.03.2011, 19:40
  • 2
    Если Вы используете эту встроенную функциональность и не хотите возвращаться из истинной стороны, можно заменить return $? с : встроенный. –  BillThor 07.03.2011, 19:50

Если Вы действительно хотите exit на ошибке и используют Bash, затем необходимо также рассмотреть set -e. От help set:

- e Выход сразу, если команда выходит с ненулевым состоянием.

Это, конечно, не дает Вам гибкость did_it_work () функция, но это - простой способ удостовериться Ваши остановки сценария удара на ошибке, не добавляя много вызовов к Вашей новой функции.

8
27.01.2020, 19:59
  • 1
    set -e полезно. Существуют некоторые команды, которые возвращаются ненулевой при нормальных обстоятельствах (например, diff). Когда я использую набор-e в сценарии, где я ожидаю ненулевой возврат, я делаю command || true. –  Shawn J. Goff 07.03.2011, 20:49
  • 2
    Кроме того, даже если Вы используете set -e, можно установить “обработчик исключений” для фиксации всех ошибок с trap did_it_work EXIT. –  Gilles 'SO- stop being evil' 08.03.2011, 20:41
  • 3
    Это - часть POSIX, не удар определенная функция. Используйте его, но знать о некоторых ловушках mywiki.wooledge.org/BashFAQ/105 –  kmkaplan 05.02.2014, 09:46
  • 4
    @ShawnJ.Goff я предпочитаю делать command && true. Как этот не изменяется возвращаемое значение. –  kmkaplan 05.02.2014, 09:49

Теги

Похожие вопросы