Pregunta En un script de shell: comandos echo shell a medida que se ejecutan


En un script de shell, ¿cómo echo un eco a todos los comandos de shell llamados y expandiendo cualquier nombre de variable? Por ejemplo, dada la siguiente línea:

ls $DIRNAME

Me gustaría que el script ejecute el comando y muestre lo siguiente

ls /full/path/to/some/dir

El propósito es guardar un registro de todos los comandos de shell llamados y sus argumentos. Tal vez hay una mejor forma de generar un tal log?


595
2018-05-18 00:03


origen


Respuestas:


set -x o set -o xtrace expande variables e imprime un pequeño signo + antes de la línea.

set -v o set -o verbose no expande las variables antes de imprimir.

Utilizar set +x y set +v para desactivar las configuraciones anteriores.

En la primera línea del script, uno puede poner #!/bin/sh -x (o -v) para tener el mismo efecto que set -x (o -v) más adelante en el guión.

Lo anterior también funciona con /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 te dará lo que quieras

Aquí hay un script de shell para demostrar:

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

ls $PWD

Esto expande todas las variables e imprime los comandos completos antes de la salida del comando.

salida:

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

241
2018-05-18 00:12



También puede alternar esto para líneas seleccionadas en su secuencia de comandos envolviéndolas en set -x y set +x  p.ej.

#!/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



Utilizo una función para hacer eco y luego ejecutar el comando

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

exe echo hello world

Que salidas

$ echo hello world
hello world

Editar:

Para obtener comandos más complicados, etc. puedes usar eval:

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

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

Que salidas

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

59
2018-04-28 13:21



La respuesta de shuckc para hacer eco de líneas seleccionadas tiene algunas desventajas: terminas con lo siguiente set +x comando también se hizo eco, y pierde la capacidad de probar el código de salida con $? ya que es sobrescrito por el set +x.

Otra opción es ejecutar el comando en una subcapa:

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

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

que le dará salida como:

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

Sin embargo, esto implica la sobrecarga de crear una nueva subcadena para el comando.


37
2017-10-15 22:34



Otra opción es colocar "-x" en la parte superior de su script en lugar de colocarlo en la línea de comando:

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

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

(Representante insuficiente para comentar sobre la respuesta elegida).


29
2018-05-12 20:24



Escriba "bash -x" en la línea de comando antes del nombre del script bash. Por ejemplo, para ejecutar foo.sh, escriba:

bash -x foo.sh

17
2018-03-15 17:40



De acuerdo a TLDPes Guía Bash para principiantes: Capítulo 2. Escritura y depuración de guiones

2.3.1. Depuración en todo el script

$ bash -x script1.sh

...

Ahora hay un depurador completo para Bash, disponible en SourceForge. Estas funciones de depuración están disponibles en la mayoría de las versiones modernas de Bash, a partir de 3.x.

2.3.2. Depuración en parte (s) de la secuencia de comandos

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

...

Tabla 2-1. Descripción general de las opciones de depuración del conjunto 

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.  

...

Alternativamente, estos modos se pueden especificar en el script en sí, por   agregando las opciones deseadas a la declaración del shell de la primera línea.   Las opciones se pueden combinar, como suele ser el caso con los comandos de UNIX:

#!/bin/bash -xv

15
2017-12-01 11:05



Usted puede ejecutar un script bash en modo de depuración con el -x opción.
Esto hará eco de todos los comandos.

bash -x example_script.sh

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


Tú también puedes guarde la opción -x en el script. Simplemente especifique la opción -x en el 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



Alguien arriba publicado:

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

y esto parece prometedor, pero no puedo por mi propia vida descubrir qué hace. Busqué en Google y busqué en la página de hombre bash para "\ $" y "$ @", y encuentro absolutamente nada.

Entiendo que se está creando una función, llamada "exec ()". Entiendo que los corchetes marcan el comienzo y el final de la función. Creo que entiendo que el punto y coma indica un "retorno difícil" entre un comando de varias líneas, de modo que "{echo" \ $ $ @ "; ps } 'se convierte, en esencia:

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

}

¿Puede alguien darme una breve explicación, o dónde encontrar esta información, ya que obviamente mi google-fu me está fallando?

(Sin querer comenzar una nueva pregunta en un hilo viejo, mi objetivo es redirigir el resultado a un archivo. El método "set -x; [commands]; set + x" me funcionaría adecuadamente, pero puedo hacerlo " t averiguar cómo hacer eco de los resultados en un archivo en lugar de en la pantalla, así que estaba tratando de entender este otro método con la esperanza de que pudiera utilizarme muy poco conocimiento de redirección / pipes / tee / etc para hacer lo mismo.)

¡Gracias!

EDICION POSTERIOR:

Con algunos retoques, creo que lo descubrí. Aquí está mi código equivalente para lo que necesito:

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

Los resultados en el archivo de registro.txt se ven algo así como:

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

Justo lo que necesitaba. ¡Gracias!


5
2018-06-07 21:07



Para eco zsh

 setopt VERBOSE

y para la depuración

 setopt XTRACE

3
2017-08-20 13:47