Czy mogę sprawić, by wszystkie polecenia miały informację zwrotną, jeśli zadziałały lub nie działały?

11

Czasami po uruchomieniu poleceń nie wyświetla wyniku, więc nie jestem pewien, czy zadziałały, czy nie. Czy jest możliwe, aby wszystkie polecenia otrzymywały informacje zwrotne, jeśli zostały poprawnie uruchomione? Lub na samym minimum, aby wyświetlić informację zwrotną, którą uruchomili (poprawnie lub nie)

rajlego
źródło
6
Ogólna idea jest taka: brak opinii oznacza, że ​​zadziałało.
Rinzwind
1
To nie do końca prawda. Na przykład cryptsetupmoże domyślnie pominąć niektóre komunikaty o błędach. Dobrze mieć $?w sobie PS1. Następnym krokiem jest dodanie aktualnego czasu, aby zawsze znać czasy poleceń;)
d33tah

Odpowiedzi:

11

(Myślę, że skoro piszesz wewnątrz Zapytaj Ubuntu , możemy założyć, że mówisz o domyślnej powłoce, czyli Bash .)

Odpowiedź na pytanie przepełnienia stosu jest bardzo dobra. W skrypcie powłoki: wykonaj polecenia powłoki echa podczas ich wykonywania (nie jest to tylko rozwiązanie specyficzne dla Ubuntu).

To, co musisz zrobić, to użyć polecenia set, aby włączyć verbose lub xtrace.

set -o

daje listę z której obecne parametry są przełączane na lub off .

set -v

lub wersja długa:

set -o verbose

włączy pełne słowo .

Myślę, że to, czego chcesz, to tak naprawdę xtrace. Spowoduje to nie tylko echo każdego uruchomionego polecenia, ale także rozszerzy parametry i zapewni więcej informacji zwrotnych. Więc jeśli zrobię coś tak głupiego jak pisanie „cześć” na terminalu, otrzymam echo tego, co wpisałem, a także raport / ślad tego, co powłoka zrobiła, aby spróbować wykonać polecenie „cześć” (patrz zrzut ekranu poniżej ):

Wpisz opis zdjęcia tutaj

Aby włączyć xtrace:

set -x

lub:

set -o xtrace

Aby wyłączyć te parametry, (przeciw intuicyjnie) wywołujesz te same polecenia, z wyjątkiem symbolu plus + zamiast myślnika lub symbolu minus, więc na przykład:

set +v

włączy gadatliwy OFF , podobnie:

set +x

włączy xtrace OFF .


Szczegółowy przewodnik po opcjach powłoki znajduje się w rozdziale 33. Opcje, Advanced Bash-Scripting Guide .

Benjamin R.
źródło
1
Ale jak to działa, gdy polecenie jest prawidłowe? czy daje jakieś wyjście? powiedzieć za polecenie whoami >/dev/null.
Zarejestrowany użytkownik
Tak, oczywiście, że tak, przypomina to, co wpisałeś oraz wszelkie dodatkowe parametry związane z poleceniem, które zostały po cichu wywołane podczas wywoływania polecenia. Jeśli masz na myśli, czy wypisuje „SUKCES”, to niestety odpowiedź Avinash Raj to zrobi.
Benjamin R
@PeterMortensen dziękuję za miłą subtelną edycję mojej odpowiedzi.
Benjamin R
13

Aby sprawdzić, czy niektóre polecenia działały poprawnie, możesz sprawdzić status powrotu podany przez $?poprzednie polecenie za pomocą:

echo $?

Status powrotu 0oznacza, że ​​polecenie zakończyło się pomyślnie, a niezerowe wyjście ( kod błędu ) oznacza, że ​​napotkano pewne problemy lub wystąpił błąd, a kategoria może być znana z kodu błędu. Kody błędów systemu Linux / C są zdefiniowane w /usr/include/asm-generic/errno-base.hi /usr/include/asm-generic/errno.h.

Również w bash .bashrcdefiniuje alias, alertktórego można użyć do powiadomienia o stanie ukończenia. Musisz dołączyć alias za pomocą polecenia lub zestawu poleceń w następujący sposób:

some_command --some-switch; alert

Możesz dołączyć następujący wiersz kodu do swojego ~/.bashrcpliku, aby wyświetlić status powrotu ostatniego wykonanego polecenia.

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

(otwórz plik za ~/.bashrcpomocą edytora tekstu i skopiuj powyższą linię, wklej go do pliku i zapisz. Uruchom nową instancję terminala, a powinieneś mieć ją w akcji. Lub zamiast tego możesz zdefiniować jakąś funkcję i użyć z PS1podobnymi jak pokazano poniżej.)

małe demo:

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

Po prostu PS1bawię się :) .. trochę więcej,

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\$ '

(możesz zmodyfikować funkcję, aby była bardziej fantazyjna, coś takiego jak @gronostaj robi w swoim poście).

precyzyjny
źródło
2
Naprawdę podoba mi się twoja rozszerzona odpowiedź z przykładami. Jestem pewien, że OP chce xtrace, ale osobiście przydałoby mi się to do debugowania własnych programów wiersza poleceń, a także lepszego zrozumienia innych.
Benjamin R
1
Sugerowałbym uzupełnienie w lewo wartości zwracanej, aby zawsze miała tę samą długość.
o0 ”.
+1 za modyfikację PS1. Tego używam, z czerwonym numerem w przypadku błędów, nic więcej, jeśli ostatnie polecenie się powiedzie:\[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
Carlos Campderrós
1
@ zardzewiały czy nie ma potrzeby pobierania ~/.bashrcpliku źródłowego ?
Avinash Raj
2
Tak, modyfikacja PS1 jest pomocna i bardzo elastyczna. Jestem zadowolony ^_^z sukcesu, a czerwony x_xz czegokolwiek innego.
Izkata
5

Możesz zmienić swój wiersz polecenia, aby wyświetlać zielony znak zaznaczenia, gdy poprzednie polecenie kończy się z 0, a czerwony X w przeciwnym razie. Arch Linux Wiki ma fajny fragment kodu do dodania do 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'

(Wyłączyłem aktualny kod błędu, ponieważ mi się nie podoba, jeśli chcesz zobaczyć dokładne kody po prostu usuń #z tego wiersza #PS1="$White\$? ":)

Oto jak to wygląda:

Zrzut ekranu interfejsu GUI

zrzut ekranu

gronostaj
źródło
2

Tak , możliwe jest uzyskanie informacji zwrotnej dla każdej komendy wykonanej na terminalu. Działa na podstawie, echo $?która zwraca 0 dla pomyślnego zakończenia komendy i każdą inną wartość inną niż 0 dla niepowodzenia.

Aby uzyskać informację o sukcesie lub niepowodzeniu, dodaj poniższy wiersz do ~/.bashrcpliku.

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

A następnie ~/.bashrcplik źródłowy , aby działał.

source ~/.bashrc

Wyjaśnienie:

Dla każdego polecenia wykonanego na terminalu ;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;kod zostanie automatycznie powiązany z nim.

Przykład:

$ 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

wprowadź opis zdjęcia tutaj

Avinash Raj
źródło
1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'zrobi to samo, nie musisz [[ $? == 0 ]]jawnie sprawdzać .
souravc
Jednak standard C / Linux i odpowiednik gramatyki angielskiej będący odpowiednikiem „Sukcesu” byłyby AWARIA.
Benjamin R