Могу ли я сделать так, чтобы все команды имели обратную связь, работали они или не работали?


11

Иногда, когда я запускаю команды, он не отображает вывод, поэтому я не уверен, сработали они или нет. Можно ли заставить все команды иметь обратную связь, если они были запущены правильно или нет? Или как минимум для отображения идентификатора обратной связи, который они запустили (правильно или нет)


6
Общая идея такова: отсутствие обратной связи означает, что это сработало.
Rinzwind

1
Это не совсем так. Например, cryptsetupможет по умолчанию пропустить некоторые сообщения об ошибках. Это хорошо иметь $?в себе PS1. Следующий шаг - добавить текущее время, чтобы всегда знать время команд;)
d33tah

Ответы:


11

(Я думаю, что поскольку вы публикуете внутри Ask Ubuntu, мы можем предположить, что вы говорите о оболочке по умолчанию, то есть Bash .)

На вопрос переполнения стека есть очень хороший ответ. В сценарии оболочки: команды оболочки echo по мере их выполнения (это не просто решение для Ubuntu).

Что вам нужно сделать, это использовать команду set, чтобы включить подробный или xtrace.

set -o

даст вам список из которых текущие параметры переключаются на или выключен .

set -v

или длинная версия:

set -o verbose

повернет многословным ON .

Я думаю, что вы хотите, однако, на самом деле xtrace. Это будет не только отображать каждую команду, которую вы запускаете, но также будет расширять параметры и давать вам больше отзывов. Поэтому, если я сделаю что-то глупое, набрав в терминале «привет», я получу отголосок того, что набрал, а также отчет / трассировку того, что сделала оболочка, чтобы попытаться выполнить команду «привет» (см. Скриншот ниже). ):

Введите описание изображения здесь

Чтобы включить xtrace:

set -x

или:

set -o xtrace

Чтобы отключить эти параметры, вы (нелогично) вызываете те же команды, за исключением символа плюс + вместо символа тире или минус, например, так:

set +v

повернет многословным OFF , аналогично:

set +x

повернет xtrace OFF .


Подробное руководство по настройкам оболочки приведено в главе 33. Опции, Руководство по расширенному написанию сценариев .


1
Но как это работает, когда команда верна? это дает какой-либо вывод? скажем за команду whoami >/dev/null.
Зарегистрированный пользователь

Да, конечно, он повторяет то, что вы ввели, плюс любые дополнительные параметры, задействованные в команде, которые были беззвучно вызваны при вызове вашей команды. Если вы имеете в виду, печатает ли он «УСПЕХ», то, к сожалению, нет, ответ Авинаша Радж сделает это.
Бенджамин Р

@PeterMortensen спасибо за приятные тонкие изменения в моем ответе.
Бенджамин Р

13

Чтобы проверить, работала ли какая-либо команда успешно или нет, вы можете проверить статус возврата , заданный $?предыдущей командой, с помощью:

echo $?

Статус возврата 0означает, что команда завершилась успешно, в то время как ненулевой вывод ( код ошибки ) будет означать, что возникли некоторые проблемы или имеется ошибка, и категорию можно узнать из кода ошибки. Коды ошибок Linux / C определены в /usr/include/asm-generic/errno-base.hи /usr/include/asm-generic/errno.h.

Также в bash .bashrcопределяется псевдоним, alertкоторый можно использовать для уведомления о статусе завершения. Вам нужно будет присоединить псевдоним с помощью команды или комбо-команды следующим образом:

some_command --some-switch; alert

Вы можете добавить следующую строку кода в ваш ~/.bashrcфайл, чтобы отобразить статус возврата последней выполненной команды.

# show the return code of last command executed
PS1='${debian_chroot:+($debian_chroot)}\u@\h(lst ret. $(echo $?) ):\w\$ '

(откройте файл в ~/.bashrcтекстовом редакторе по вашему выбору и скопируйте приведенную выше строку, вставьте его в файл и сохраните. Запустите новый экземпляр терминала, и вы должны запустить его. Или вместо этого вы можете определить какую-то функцию и использовать это PS1как показано ниже.)

немного демо:

hash@precise(lst ret. 0 ):~$ ls -sh someFileThatsNotThere
ls: cannot access someFileThatsNotThere: No such file or directory
hash@precise(lst ret. 2 ):~$ 
hash@precise(lst ret. 2 ):~$ aCommandThatsNot
aCommandThatsNot: command not found
hash@precise(lst ret. 127 ):~$ 
hash@precise(lst ret. 127 ):~$ echo "you should get a lst ret. 0, I believe the system has echo installed :)"
you should get a lst ret. 0, I believe the system has echo installed :)
hash@precise(lst ret. 0 ):~$
hash@precise(lst ret. 0 ):~$ sudo touch /tmp/someTestFile
[sudo] password for hash: 
hash@precise(lst ret. 1 ):~$
hash@precise(lst ret. 1 ):~$ chown $USER:$USER /tmp/someTestFile 
chown: changing ownership of `/tmp/someTestFile': Operation not permitted

Просто играть с PS1:) .. немного больше,

function showRetStat {
## line1: initiliazing retStat with the return status of the previous command
retStat=$?
## line2: Left padding the return status with spaces. If you prefer the unpadded one, you can just replace
# $retStatFtd in the lines initializing noErrStr and errStr among other possible ways.
retStatFtd=$(sed -e :a -e 's/^.\{1,2\}$/ &/;ta' <<< $retStat)
## lines3&4: Setting the strings to display for a successful and unsuccessful run of previous command
# which we are going to display with the prompt string. Change the strings to display text of your
# choice like you may set noErrStr="yippie!" , errStr="oopsie!" in place of what they're now.
noErrStr="retStat "$retStatFtd" :: PASS ^_^"
errStr="retStat "$retStatFtd" :: FAIL x_x"
## line5: Applying the logic and display the proper string at the prompt. Space padded number i.e. retStatFtd, here,
# worked in the logic, originally I intended to use this for the display while retStat in the conditional
# check; you could make the function one statement less if you want to.
echo "$([ $retStatFtd = 0 ] && echo "$noErrStr" || echo "$errStr")"
}

## Combining the function showRetStat into the prompt string.
PS1='${debian_chroot:+($debian_chroot)}\u@\h($(showRetStat)):\w\$ '

(Вы можете изменить функцию, чтобы сделать ее более необычной, например, @gronostaj в своем посте.)


2
Мне очень нравится ваш расширенный ответ с примерами. Я уверен, что OP хочет xtrace, но лично я нашел бы это полезным для отладки моих собственных программ командной строки, а также лучшего понимания других.
Бенджамин Р

1
Я бы предложил заполнить возвращаемое значение слева, чтобы оно всегда было одинаковой длины.
о0 '.

+1 за изменение PS1. Это тот, который я использую, с красным номером в случае ошибок, ничего лишнего, если последняя команда выполнена успешно:\[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
Carlos Campderrós

1
@rusty, что нет необходимости в исходном ~/.bashrcфайле?
Авинаш Радж

2
Да, изменение PS1 полезно и очень гибко. Я показываю счастливый ^_^на успех, и красный x_xна все остальное.
Изката

5

Вы можете изменить командную строку, чтобы отображать зеленую галочку, когда предыдущая команда завершается с 0 и красным X в противном случае. Arch Linux Wiki имеет небольшой кусок кода, который можно добавить к вашему bash.rc:

set_prompt () {
    Last_Command=$? # Must come first!
    Blue='\[\e[01;34m\]'
    White='\[\e[01;37m\]'
    Red='\[\e[01;31m\]'
    Green='\[\e[01;32m\]'
    Reset='\[\e[00m\]'
    FancyX='\342\234\227'
    Checkmark='\342\234\223'

    # Add a bright white exit status for the last command
    #PS1="$White\$? "
    # If it was successful, print a green check mark. Otherwise, print
    # a red X.
    if [[ $Last_Command == 0 ]]; then
        PS1+="$Green$Checkmark "
    else
        PS1+="$Red$FancyX "
    fi
    # If root, just print the host in red. Otherwise, print the current user
    # and host in green.
    if [[ $EUID == 0 ]]; then
        PS1+="$Red\\h "
    else
        PS1+="$Green\\u@\\h "
    fi
    # Print the working directory and prompt marker in blue, and reset
    # the text color to the default.
    PS1+="$Blue\\w \\\$$Reset "
}
PROMPT_COMMAND='set_prompt'

(Я отключил фактический код ошибки , потому что не нравится, если вы хотите , чтобы увидеть точные коды просто удалить #из этой строки: #PS1="$White\$? ")

Вот как это выглядит:

Скриншот графического терминала

скриншот tty


2

Да , можно получить обратную связь для каждой команды, которую вы выполнили на терминале. Она работает на основе echo $?которой возвращает 0 для успешного завершения команды и любое другое значение, кроме 0 для сбоя.

Чтобы получить отзыв об успехе или неудаче, добавьте следующую строку в ~/.bashrcфайл.

bind 'RETURN: ";if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;\n"' 

А затем исходный ~/.bashrcфайл, чтобы он работал.

source ~/.bashrc

Объяснение:

Для каждой команды, которую вы выполняете на терминале, этот ;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;код будет автоматически привязываться к нему.

Пример:

$ sudo apt-cache policy firefox;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;
firefox:
  Installed: 24.0+build1-0ubuntu1
  Candidate: 24.0+build1-0ubuntu1
  Version table:
 *** 24.0+build1-0ubuntu1 0
        500 http://ubuntu.inode.at/ubuntu/ saucy/main amd64 Packages
        100 /var/lib/dpkg/status
SUCCESS

$ suda apt-get update;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;
No command 'suda' found, did you mean:
 Command 'sudo' from package 'sudo-ldap' (universe)
 Command 'sudo' from package 'sudo' (main)
 suda: command not found
FAILURE

введите описание изображения здесь


1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'также будет делать то же самое, вам не нужно [[ $? == 0 ]]явно проверять .
souravc

Однако стандарт C / Linux и стандарт грамматики английского языка, аналогичный «Success», будут FAILURE.
Бенджамин Р
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.