Kann ich allen Befehlen Feedback geben, ob sie funktioniert haben oder nicht?

11

Wenn ich Befehle ausführe, wird manchmal keine Ausgabe angezeigt, daher bin ich mir nicht sicher, ob sie funktioniert haben oder nicht. Ist es möglich, dass alle Befehle eine Rückmeldung erhalten, ob sie korrekt ausgeführt wurden oder nicht? Oder zumindest, um die von ihnen ausgeführte Feedback-ID anzuzeigen (korrekt oder nicht)

Rajlego
quelle
6
Die allgemeine Idee ist: Kein Feedback bedeutet, dass es funktioniert hat.
Rinzwind
1
Das ist nicht genau richtig. Beispielsweise cryptsetupkönnen standardmäßig einige Fehlermeldungen übersprungen werden. Es ist eine gute Sache, $?in Ihrem zu haben PS1. Der nächste Schritt ist, auch die aktuelle Zeit hinzuzufügen, um immer die Timings der Befehle zu kennen;)
d33tah

Antworten:

11

(Ich denke, da Sie in Ask Ubuntu posten, können wir davon ausgehen, dass Sie über die Standard-Shell sprechen, dh Bash .)

In der Frage zum Stapelüberlauf gibt es eine sehr gute Antwort. In einem Shell-Skript: Echo-Shell-Befehle, wenn sie ausgeführt werden (dies ist nicht nur eine Ubuntu-spezifische Lösung).

Was Sie tun müssen, ist den Befehl set zu verwenden, um verbose oder xtrace einzuschalten.

set -o

wird Ihnen eine Liste von denen aktuellen Parameter geschaltet auf oder ab .

set -v

oder die Langformversion:

set -o verbose

schaltet ausführliche ON .

Ich denke, was Sie wollen, ist eigentlich xtrace. Dies gibt nicht nur jeden Befehl wieder, den Sie ausführen, sondern erweitert auch die Parameter und gibt Ihnen mehr Feedback. Wenn ich also etwas so Dummes tue wie das Eingeben von 'hi' am Terminal, erhalte ich das Echo meiner Eingabe sowie einen Bericht / eine Spur dessen, was die Shell getan hat, um den Befehl 'hi' auszuführen (siehe Abbildung unten) ):

Geben Sie hier die Bildbeschreibung ein

So aktivieren Sie xtrace:

set -x

oder:

set -o xtrace

Um diese Parameter zu deaktivieren, rufen Sie (kontraintuitiv) dieselben Befehle auf, außer mit einem Pluszeichen + anstelle eines Bindestrichs oder Minuszeichens. Beispiel:

set +v

wird die ausführliche drehen OFF , ähnlich:

set +x

schaltet xtrace OFF .


Eine ausführliche Anleitung zu Shell-Optionen finden Sie in Kapitel 33. Optionen, Advanced Bash-Scripting Guide .

Benjamin R.
quelle
1
Aber wie funktioniert es, wenn der Befehl korrekt ist? Gibt es eine Ausgabe? sagen Sie für den Befehl whoami >/dev/null.
Registrierter Benutzer
Ja, natürlich gibt es wieder, was Sie eingegeben haben, sowie alle zusätzlichen Parameter des Befehls, die beim Aufrufen Ihres Befehls stillschweigend aufgerufen wurden. Wenn Sie meinen, druckt es "ERFOLG", dann wird Avinash Rajs Antwort das leider tun.
Benjamin R
@ PeterMortensen danke für die netten subtilen Änderungen an meiner Antwort.
Benjamin R
13

Um zu überprüfen , ob einige Befehle erfolgreich oder nicht funktioniert können Sie das überprüfen Rückgabestatus , gegeben durch $?, von dem vorherigen Befehl mit:

echo $?

Ein Rückgabestatus von 0bedeutet, dass der Befehl erfolgreich abgeschlossen wurde, während eine Ausgabe ungleich Null ( Fehlercode ) bedeuten würde, dass einige Probleme aufgetreten sind oder ein Fehler vorliegt und die Kategorie aus dem Fehlercode bekannt ist. Die Linux / C-Fehlercodes sind in /usr/include/asm-generic/errno-base.hund definiert /usr/include/asm-generic/errno.h.

Auch in Bash .bashrcdefiniert das einen Alias alert, mit dem der Status der Fertigstellung benachrichtigt werden kann. Sie müssten den Alias ​​mit dem Befehl oder der Befehlskombination wie folgt anhängen:

some_command --some-switch; alert

Sie können die folgende Codezeile an Ihre ~/.bashrcDatei anhängen , um den Rückgabestatus des zuletzt ausgeführten Befehls anzuzeigen .

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

(Öffnen Sie die Datei ~/.bashrcmit einem Texteditor Ihrer Wahl, kopieren Sie die obige Zeile, fügen Sie sie in die Datei ein und speichern Sie sie. Starten Sie eine neue Instanz des Terminals, und Sie sollten sie in Aktion haben. Stattdessen können Sie eine Funktion definieren und verwenden es mit PS1wie unten abgebildet.)

eine kleine 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

PS1Ich spiele nur mit :) ..ein bisschen mehr,

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

(Sie können die Funktion ändern, um sie ausgefallener zu gestalten, so wie es @gronostaj in seinem Beitrag tut.)

präzise
quelle
2
Ihre erweiterte Antwort mit Beispielen gefällt mir sehr gut. Ich bin mir ziemlich sicher, dass OP xtrace will, aber ich persönlich würde dies nützlich finden, um meine eigenen Befehlszeilenprogramme zu debuggen und andere besser zu verstehen.
Benjamin R
1
Ich würde vorschlagen, den Rückgabewert links aufzufüllen, damit er immer gleich lang ist.
o0 '.
+1 zum Ändern PS1. Dies ist die, die ich benutze, mit roter Nummer im \[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
Fehlerfall
1
@rusty ist das keine Notwendigkeit, ~/.bashrcDatei zu quellen ?
Avinash Raj
2
Ja, das Ändern von PS1 ist hilfreich und sehr flexibel. Ich freue mich ^_^über den Erfolg und x_xüber alles andere.
Izkata
5

Sie können Ihre Eingabeaufforderung so ändern, dass ein grünes Häkchen angezeigt wird, wenn der vorherige Befehl mit 0 und ansonsten mit rotem X beendet wird. Arch Linux Wiki hat einen schönen Code, den Sie Ihrem hinzufügen können 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'

(Ich habe den eigentlichen Fehlercode deaktiviert, weil er mir nicht gefällt. Wenn Sie genaue Codes sehen möchten, entfernen Sie ihn einfach #aus dieser Zeile:#PS1="$White\$? " )

So sieht es aus:

Screenshot des GUI-Terminals

tty Screenshot

gronostaj
quelle
2

Ja , es ist möglich, für jeden Befehl, den Sie auf dem Terminal ausgeführt haben, eine Rückmeldung zu erhalten. Auf dieser Grundlage wird echo $?0 für einen erfolgreichen Befehlsabschluss und ein anderer Wert als 0 für einen Fehler zurückgegeben.

Fügen Sie der ~/.bashrcDatei die folgende Zeile hinzu, um das Feedback zu Erfolg oder Misserfolg zu erhalten .

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

Und dann die Quelldatei ~/.bashrc, damit es funktioniert.

source ~/.bashrc

Erläuterung:

Für jeden Befehl, den Sie auf dem Terminal ausgeführt haben, wird dieser ;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;Code automatisch daran gebunden.

Beispiel:

$ 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

Geben Sie hier die Bildbeschreibung ein

Avinash Raj
quelle
1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'wird auch das gleiche tun, müssen Sie nicht [[ $? == 0 ]]explizit überprüfen .
Souravc
Der C / Linux-Standard und das englische Grammatik-Standard-Gegenstück zu 'Success' wären jedoch FAILURE.
Benjamin R