Question Dans un script shell: commandes shell echo lors de leur exécution


Dans un script shell, comment puis-je répercuter toutes les commandes shell et développer tous les noms de variables? Par exemple, étant donné la ligne suivante:

ls $DIRNAME

Je voudrais que le script exécute la commande et affiche les éléments suivants

ls /full/path/to/some/dir

Le but est d'enregistrer un journal de toutes les commandes shell appelées et de leurs arguments. Peut-être existe-t-il une meilleure façon de générer un tel journal?


595
2018-05-18 00:03


origine


Réponses:


set -x ou set -o xtrace Développe les variables et imprime un petit signe + devant la ligne.

set -v ou set -o verbose ne pas développer les variables avant l'impression.

Utilisation set +x et set +v pour désactiver les paramètres ci-dessus.

Sur la première ligne du script, on peut mettre #!/bin/sh -x (ou -v) avoir le même effet que set -x (ou -v) plus tard dans le script.

Ce qui précède fonctionne également avec /bin/sh.

http://www.faqs.org/docs/abs/HTML/options.html

$ cat shl
#!/bin/bash                                                                     

DIR=/tmp/so
ls $DIR

$ bash -x shl 
+ DIR=/tmp/so
+ ls /tmp/so
$

655
2018-05-18 00:06



set -x vous donnera ce que vous voulez.

Voici un exemple de script shell pour démontrer:

#!/bin/bash
set -x #echo on

ls $PWD

Cela étend toutes les variables et imprime les commandes complètes avant la sortie de la commande.

sortie:

+ ls /home/user/
file1.txt file2.txt

241
2018-05-18 00:12



Vous pouvez également activer cette option pour sélectionner des lignes dans votre script en les enveloppant set -x et set +x  par exemple.

#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
   echo "grabbing $URL"
   set -x
   curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
   set +x
fi

71
2017-12-05 08:09



J'utilise une fonction pour echo puis lance la commande

#!/bin/bash
#function to display commands
exe() { echo "\$ $@" ; "$@" ; }

exe echo hello world

Quelles sorties

$ echo hello world
hello world

Modifier:

Pour les commandes plus compliquées, les pipes etc. vous pouvez utiliser eval:

#!/bin/bash
#function to display commands
exe() { echo "\$ ${@/eval/}" ; "$@" ; }

exe eval "echo 'Hello World' | cut -d ' ' -f1"

Quelles sorties

$  echo 'Hello World' | cut -d ' ' -f1
Hello

59
2018-04-28 13:21



La réponse de shuckc pour faire écho aux lignes select a quelques inconvénients: vous vous retrouvez avec ce qui suit set +x commande étant renvoyée également, et vous perdez la possibilité de tester le code de sortie avec $? car il est écrasé par le set +x.

Une autre option consiste à exécuter la commande dans un sous-shell:

echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )

if [ $? -eq 0 ] ; then
    echo "curl failed"
    exit 1
fi

ce qui vous donnera une sortie comme:

getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed

Cependant, cela entraîne des frais généraux de création d'un nouveau sous-shell pour la commande.


37
2017-10-15 22:34



Une autre option consiste à placer "-x" en haut de votre script plutôt qu'en ligne de commande:

$ cat ./server
#!/bin/bash -x
ssh user@server

$ ./server
+ ssh user@server
user@server's password: ^C
$

(Représentant insuffisant pour commenter la réponse choisie.)


29
2018-05-12 20:24



Tapez "bash -x" sur la ligne de commande avant le nom du script bash. Par exemple, pour exécuter foo.sh, tapez:

bash -x foo.sh

17
2018-03-15 17:40



Selon TLDPde Bash Guide for Beginners: Chapitre 2. Écrire et déboguer des scripts

2.3.1. Débogage sur l'ensemble du script

$ bash -x script1.sh

...

Il y a maintenant un débogueur complet pour Bash, disponible sur SourceForge. Ces fonctionnalités de débogage sont disponibles dans la plupart des versions modernes de Bash, à partir de 3.x.

2.3.2. Débogage sur une partie du script

set -x            # activate debugging from here
w
set +x            # stop debugging from here

...

Tableau 2-1. Vue d'ensemble des options de débogage 

Short  | Long notation | Result  
-------+---------------+--------------------------------------------------------------
set -f | set -o noglob | Disable file name generation using metacharacters (globbing).  
set -v | set -o verbose| Prints shell input lines as they are read.  
set -x | set -o xtrace | Print command traces before executing command.  

...

Alternativement, ces modes peuvent être spécifiés dans le script lui-même, par   ajouter les options souhaitées à la déclaration de première ligne shell.   Les options peuvent être combinées, comme c'est généralement le cas avec les commandes UNIX:

#!/bin/bash -xv

15
2017-12-01 11:05



Vous pouvez exécuter un script bash en mode débogage avec le option -x.
Cela fera écho à toutes les commandes.

bash -x example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt


Vous pouvez aussi enregistrer l'option -x dans le script. Spécifiez simplement l'option -x dans le shebang.

######## example_script.sh ###################
#!/bin/bash -x

cd /home/user
mv text.txt mytext.txt

##############################################

./example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt




6
2017-09-05 14:50



Quelqu'un ci-dessus posté:

#!/bin/bash
#function to display commands
exe() { echo "\$ $@" ; "$@" ; }

et cela semble prometteur, mais je ne peux pas pour la vie de moi comprendre ce qu'il fait. J'ai googlé et cherché dans la page bash homme pour "\ $" et "$ @", et trouve absolument rien.

Je comprends qu'une fonction est en cours de création, nommée "exec ()". Je comprends que les accolades marquent le début et la fin de la fonction. Je pense que je comprends que le point-virgule marque un "retour dur" entre une commande multiligne, de sorte que '{echo "\ $ $ @"; "$ @"; } 'devient, en substance:

{
echo "\$ $@"
"$@"

}

Quelqu'un peut-il me donner une brève explication, ou où trouver cette information, puisque évidemment mon google-fu me manque?

(Sans vouloir démarrer une nouvelle question sur un ancien thread, mon but est de rediriger la sortie vers un fichier.) La méthode "set -x; [commands]; set + x" fonctionnerait bien pour moi, mais je peux ' t comprendre comment faire écho les résultats à un fichier à la place de l'écran, donc j'essayais de comprendre cette autre méthode dans l'espoir que je pourrais utiliser très mauvaise compréhension de redirection / pipes / tee / etc pour faire la même chose.)

Merci!

PLUS TARD EDIT:

Avec un peu de bricolage, je crois que j'ai compris. Voici mon code équivalent pour ce dont j'ai besoin:

SCRIPT_LOG="\home\buddy\logfile.txt"
exe () {
  params="$@"                       # Put all of the command-line into "params"
  printf "%s\t$params" "$(date)" >> "$SCRIPT_LOG"   # Print the command to the log file
  $params                           # Execute the command
}

exe rm -rf /Library/LaunchAgents/offendingfile
exe rm -rf /Library/LaunchAgents/secondoffendingfile

Les résultats dans le fichier logfile.txt ressemblent à ceci:

Tue Jun  7 16:59:57 CDT 2016  rm -rf /Library/LaunchAgents/offendingfile
Tue Jun  7 16:59:57 CDT 2016  rm -rf /Library/LaunchAgents/secondoffendingfile

Juste ce dont j'avais besoin. Merci!


5
2018-06-07 21:07



Pour zsh echo

 setopt VERBOSE

et pour le débogage

 setopt XTRACE

3
2017-08-20 13:47