Puis-je faire en sorte que toutes les commandes aient un retour si elles ont fonctionné ou non?

11

Parfois, lorsque j'exécute des commandes, il n'affiche pas de sortie, donc je ne sais pas si elles ont fonctionné ou non. Est-il possible de faire en sorte que toutes les commandes aient un retour si elles ont fonctionné correctement ou non? Ou au minimum pour afficher l'ID de rétroaction qu'ils ont exécuté (correctement ou non)

rajlego
la source
6
L'idée générale est: aucune rétroaction ne signifie que cela a fonctionné.
Rinzwind
1
Ce n'est pas tout à fait vrai. Par exemple, cryptsetuppeut par défaut ignorer certains messages d'erreur. C'est une bonne chose d'avoir $?dans votre PS1. L'étape suivante consiste à ajouter également l'heure actuelle, pour toujours connaître les horaires des commandes;)
d33tah

Réponses:

11

(Je pense que puisque vous postez dans Ask Ubuntu, nous pouvons supposer que vous parlez du shell par défaut, c'est-à-dire Bash .)

Il y a une très bonne réponse dans la question Stack Overflow Dans un script shell: les commandes shell echo lorsqu'elles sont exécutées (ce n'est pas seulement une solution spécifique à Ubuntu).

Ce que vous devez faire est d'utiliser la commande set pour activer verbose ou xtrace.

set -o

vous donnera une liste dont les paramètres actuels sont passés à sur ou hors .

set -v

ou la version longue:

set -o verbose

tournera verbeux ON .

Je pense que ce que vous voulez, c'est en fait xtrace. Cela fera non seulement écho à chaque commande que vous exécuterez, mais étendra également les paramètres et vous donnera plus de commentaires. Donc, si je fais quelque chose d'aussi stupide que de taper 'hi' sur le terminal, j'obtiendrai l'écho de ce que j'ai tapé ainsi qu'un rapport / trace de ce que le shell a fait pour tenter d'exécuter la commande 'hi' (voir capture d'écran ci-dessous ):

Entrez la description de l'image ici

Pour activer xtrace:

set -x

ou:

set -o xtrace

Pour désactiver ces paramètres, vous (contre-intuitivement) appelez les mêmes commandes sauf avec un symbole plus + au lieu d'un symbole tiret ou moins, donc, par exemple:

set +v

tournera verbeux OFF , de même:

set +x

tournera xtrace OFF .


Un guide détaillé sur les options du shell se trouve au Chapitre 33. Options, Advanced Bash-Scripting Guide .

Benjamin R
la source
1
Mais comment ça marche quand la commande est correcte? donne-t-il une sortie? dire pour la commande whoami >/dev/null.
Utilisateur enregistré le
Oui, bien sûr, cela fait écho à ce que vous avez tapé plus les paramètres supplémentaires impliqués dans la commande qui ont été appelés en silence lors de l'appel de votre commande. Si vous voulez dire, est-ce que cela affiche "SUCCÈS", alors malheureusement, non, la réponse d'Avinash Raj fera cela.
Benjamin R
@PeterMortensen merci pour les belles modifications subtiles de ma réponse.
Benjamin R
13

Pour vérifier si une commande a fonctionné avec succès ou non, vous pouvez vérifier l' état de retour , donné par $?, de la commande précédente avec:

echo $?

Un état de retour 0signifie que la commande s'est terminée avec succès, tandis qu'une sortie non nulle ( code d'erreur ) signifierait que certains problèmes ont été rencontrés ou qu'il y a une erreur et que la catégorie peut être connue à partir du code d'erreur. Les codes d'erreur Linux / C sont définis dans /usr/include/asm-generic/errno-base.het /usr/include/asm-generic/errno.h.

Toujours en bash, le .bashrcdéfinit un alias alertqui peut être utilisé pour notifier avec le statut d'achèvement. Vous devez attacher l'alias avec la commande ou le combo de commandes comme ceci:

some_command --some-switch; alert

Vous pouvez ajouter la ligne de code suivante à votre ~/.bashrcfichier pour afficher l' état de retour de la dernière commande exécutée.

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

(ouvrez le fichier ~/.bashrcavec l'éditeur de texte de votre choix, et copiez la ligne ci-dessus, collez-la dans le fichier et enregistrez. Lancez une nouvelle instance du terminal, et vous devriez l'avoir en action. Ou à la place, vous pouvez définir une fonction et utiliser avec PS1comme comme illustré ci-dessous.)

une petite démo:

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

Je joue juste avec PS1:) ..un peu plus,

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

(vous pouvez modifier la fonction pour la rendre plus sophistiquée, comme le fait @gronostaj dans son article.)

précis
la source
2
J'aime vraiment votre réponse élargie avec des exemples. Je suis à peu près sûr que OP veut xtrace mais personnellement, je trouverais cela utile pour déboguer mes propres programmes en ligne de commande ainsi que pour mieux comprendre les autres.
Benjamin R
1
Je suggérerais de remplir à gauche la valeur de retour, afin qu'elle soit toujours de la même longueur.
o0 '.
+1 pour la modification PS1. C'est celui que j'utilise, avec un numéro rouge en cas d'erreur, rien de plus si la dernière commande réussit:\[\033[01;41;37m\]${?#0}\[\033[00;01;36m\] \u@\h:\w\[\033[00m\]\$
Carlos Campderrós
1
@rusty, est-ce que ce n'est pas nécessaire de ~/.bashrcfichier source ?
Avinash Raj
2
Oui, la modification de PS1 est utile et très flexible. J'affiche un heureux ^_^succès, et un rouge x_xsur tout le reste.
Izkata
5

Vous pouvez modifier votre invite de commande pour afficher un signe de coche verte lorsque la commande précédente se termine avec 0 et X rouge sinon. Arch Linux Wiki a un joli morceau de code à ajouter à votre 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'

(J'ai désactivé le code d'erreur réelle parce que je ne l' aime pas, si vous souhaitez voir les codes exacts enlèverait juste #de cette ligne: #PS1="$White\$? ")

Voici à quoi ça ressemble:

Capture d'écran du terminal GUI

capture d'écran tty

gronostaj
la source
2

Oui , il est possible d'obtenir un retour pour chaque commande que vous avez exécutée sur le terminal. Cela fonctionne sur la base de echo $?laquelle retourne 0 pour une exécution réussie de la commande et toute autre valeur autre que 0 pour l'échec.

Pour obtenir les commentaires de réussite ou d'échec, ajoutez la ligne ci-dessous au ~/.bashrcfichier.

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

Et puis le ~/.bashrcfichier source pour le faire fonctionner.

source ~/.bashrc

Explication:

Pour chaque commande exécutée sur le terminal, ce ;if [[ $? == 0 ]]; then tput setaf 6 && echo SUCCESS; tput sgr0; else tput setaf 1 && echo FAILURE; tput sgr0; fi;code sera automatiquement lié à celui-ci.

Exemple:

$ 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

entrez la description de l'image ici

Avinash Raj
la source
1
bind 'RETURN: " && echo SUCCESS || echo FAILED \n"'fera également de même, vous n'avez pas besoin de vérifier [[ $? == 0 ]]explicitement.
souravc
Cependant, la norme C / Linux et la contrepartie de la grammaire anglaise à «Success» seraient FAILURE.
Benjamin R