Как возвратить код выхода? Ошибка:вернуть: чтение: числовой аргумент требуется

(Ответ Chris Down имеет правильное объяснение, но не хорошее обходное решение),

Ваша проблема происходит от комбинации ошибки дизайна удара и ошибки дизайна tmux.

По умолчанию tmux запускает оболочку входа в систему в каждом окне. Это не имеет никакого смысла: при установке tmux как оболочки входа в систему необходимо установить default-command опция к чему-то другому, чем tmux; и если Вы не установили tmux как свою оболочку входа в систему, необходимо установить default-command опция постараться не запускать оболочку входа в систему внутри tmux. Так надуйте это в Вашем ~/.tmux.conf сказать tmux запускать обычную оболочку:

set-option -g default-command $SHELL

Затем Ваш .bashrc будет считан. Существует другая проблема с ударом, который не имеет значения здесь, если Вы настраиваете tmux, как рекомендуется выше, но который появится снова, если Вы войдете в систему в текстовом режиме (на текстовой консоли, или по SSH). Чтения Bash ~/.bash_profile в оболочках входа в систему, и ~/.bashrc в интерактивных оболочках, но только если они не оболочки входа в систему. Читать ~/.bashrc также в оболочках входа в систему, если они являются интерактивными, добавьте это к Вашему ~/.bash_profile:

case $- in *i*) . ~/.bashrc;; esac

7
07.07.2013, 21:41
2 ответа

Bash return() может только возвратить числовые аргументы. В любом случае, по умолчанию, это возвратит статус выхода последней выполненной команды. Так, все, в чем Вы действительно нуждаетесь:

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    sudo apt-get install --assume-yes $@
fi
}

Вы не должны явно устанавливать значение, которое будет возвращено с тех пор по умолчанию, функция возвратится $?. Однако это не будет работать если первое apt команда перестала работать, и Вы не вошли if цикл. Для создания этого более устойчивым используйте это:

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
    ## If this is executed, the else is ignored and $? will be
    ## returned. Here, $?will be the exit status of this command
    sudo apt-get install --assume-yes $@
else
    ## Else, return the exit value of the first apt-get
    return $ret
fi
}

Общее правило состоит в том, что, чтобы иметь функцию, возвращают статус выхода конкретного задания и не обязательно последнего, которое он выполнил, необходимо будет сохранить статус выхода к переменной и возвратить переменную:

function foo() {
    run_a_command arg1 arg2 argN
    ## Save the command's exit status into a variable
    return_value= $?

    [the rest of the function  goes here]
    ## return the variable
    return $return_value
}

Править: На самом деле, как @gniourf_gniourf указанный в комментариях, Вы могли значительно упростить все это использование &&:

install_auto() {
  apt-get -h > /dev/null 2>&1 &&
  sudo apt-get install --assume-yes $@
}

Возвращаемое значение этой функции будет одним из:

  1. Если apt-get -h неудавшийся, это возвратит свой код выхода
  2. Если apt-get -h следовавший, это возвратит код выхода sudo apt-get install.
7
27.01.2020, 20:17
  • 1
    Извините, мой пример не был достаточно ясен. Мне нужен оператор возврата (или некоторая эквивалентная логика) в моем фактическом сценарии, таким образом, материал после этого оператора не выполняется, если склонный - добираются, присутствовал в этой системе. Если склонный - добираются, не присутствует, это ищет застежку-молнию и т.д. Я предполагаю добавление return $? на следующей строке Вашего примера после sudo apt-get ... могло бы быть достаточным. Это правильно? Спасибо –  MountainX-for-Monica 07.07.2013, 22:12
  • 2
    @MountainX видит обновленный ответ. Путем Вы записали это (и способ, которым я записал свой пример), если apt сбои, затем его статус выхода возвращается и функциональные выходы, возвращая значение выхода at-get. Не это, в чем Вы нуждаетесь? –  terdon♦ 07.07.2013, 22:15
  • 3
    ret переменная бесполезна. apt-get -h > /dev/null 2>&1 && sudo apt-get install --assume-yes "$@" сделал бы то же. О, и использование больше кавычек, специально для $@ –  gniourf_gniourf 07.07.2013, 22:17
  • 4
    @gniourf_gniourf да действительно, ответ обновляется. –  terdon♦ 07.07.2013, 22:22
  • 5
    спасибо за обратную связь. Я вставил свою полную функцию, поскольку я понял, что мой упрощенный пример не был достаточно. Я ценю дальнейшие комментарии. –  MountainX-for-Monica 07.07.2013, 22:34

Для полноты вот моя фактическая функция с некоторыми модификациями, как предложено @terdon и @gniourf_gniourf:

install_auto() {
    if [ ! $# -gt 0 ] ; then
        echo "usage: $0 package_name [package_name ...]"
    fi 

    apt-get -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        if [ -f "$@" ] || [[ "$@" =~ '/' ]] ; then
            sudo gdebi -n "$@"
            return $?
        else    
            sudo apt-get install --assume-yes "$@"
            return $?
        fi
    fi

    zypper help > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
            sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"
            return $?
    fi

    #may check other package managers in the future

    echo "ERROR: package manager not found"
    return 255
}

Я ценю дальнейшие предложения.

1
27.01.2020, 20:17
  • 1
    cmd; if [ $? -eq 0 ]; then ... конструкция обычно лучше выражается как if cmd; then ... или даже просто cmd && ... если "затем" часть является просто простой командой. –  tripleee 08.07.2013, 09:00

Теги

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