¿Cómo puedo saber si la secuencia de comandos bash que se está ejecutando actualmente se ha invocado con -x para la depuración?

11

Tengo un script launch.shque se ejecuta como otro usuario para crear archivos con el propietario correcto. Quiero pasar -x a esta invocación si se pasó originalmente al script

if [ `whoami` == "deployuser" ]; then
  ... bunch of commands that need files to be created as deployuser
else
  echo "Respawning myself as the deployment user... #Inception"
  echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
  sudo -u deployuser -H bash $0 "$@"  # How to pass -x here if it was passed to the script initially?
fi

He leído la página de depuración de bash, pero parece que no hay una opción clara que indique si se inició el script original -x.

Dan Dascalescu
fuente

Respuestas:

15

Muchas de las banderas a las que se puede pasar bashen la línea de comando son setbanderas. setes el shell incorporado que puede alternar estas banderas en tiempo de ejecución. Por ejemplo, llamar a un script como bash -x foo.shes básicamente lo mismo que hacer set -xen la parte superior del script.

Saber que ese setes el shell integrado responsable de esto nos permite saber dónde buscar. Ahora podemos hacer help sety obtenemos lo siguiente:

$ help set
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
...
      -x  Print commands and their arguments as they are executed.
...
    Using + rather than - causes these flags to be turned off.  The
    flags can also be used upon invocation of the shell.  The current
    set of flags may be found in $-.  The remaining n ARGs are positional
    parameters and are assigned, in order, to $1, $2, .. $n.  If no
    ARGs are given, all shell variables are printed.
...

Entonces, de esto vemos que $-debería decirnos qué banderas están habilitadas.

$ bash -c 'echo $-'
hBc

$ bash -x -c 'echo $-'
+ echo hxBc
hxBc

Entonces, básicamente, solo tienes que hacer:

if [[ "$-" = *"x"* ]]; then
  echo '`-x` is set'
else
  echo '`-x` is not set'
fi

Como beneficio adicional, si desea copiar todas las banderas, también puede hacer

bash -$- /other/script.sh
Patricio
fuente
1
Tendrá que usar [[ $- == *x* ]]para la coincidencia de patrones.
Glenn Jackman
1
O podrías usar el estándar case $- in *x*) ... ;; *) ... ;; esac. Es útil conocer este uso de casescripts que están destinados a ser portátiles, y ahora que lo sé, me resulta más fácil recordar eso, que recordar "si es específico de bash, entonces [[, de lo contrario case".
hvd
OK, entonces toda esta serie de comentarios podría ser eliminada.
l0b0
$-salidas hB. ¿Qué hacen los -hy -Blas banderas / argumentos hacen? No veo entonces en la página de manual de bash .
Dan Dascalescu
3

set -osaldrá xtrace onsi -xse usa, de lo contrario xtrace off.

vinc17
fuente
2

Aunque la respuesta de @Patrick es la "correcta", también puede pasar un parámetro o una variable exportada a su script secundario que le diga qué hacer, como activar el rastreo.

Esto tiene la desventaja de que (creo) que tiene que volver a exportarlo a cada nivel de script que está a punto de ingresar.

Tiene la ventaja de poder rastrear selectivamente (o afectar de otra manera) solo los scripts de los que necesita el comportamiento de salida / modificado, para reducir la salida extraña, etc. Por ejemplo, el rastreo puede estar desactivado para el script de llamada y todavía se activa en el script llamado. No es una propuesta de todo o nada.

No es parte de su pregunta, pero está relacionado:

A veces defino una variable como

E=""
E="echo "

o

E=""
E=": "

y usarlo (en múltiples declaraciones) como

"${E}" rsync ...

o, solo para la segunda variación,

"${E}" echo "this is a debugging message"

Luego, solo comento la segunda definición cuando quiero que se ejecuten los comandos. También puede utilizar esta técnica con un parámetro o variable exportada en su lugar.

Con cualquiera de estos, debe tener cuidado con las declaraciones compuestas porque el método solo está garantizado para funcionar en la primera declaración de la lista compuesta.

Joe
fuente
1

Puede tomar el PID del proceso y luego examinar la tabla de procesos con ps para ver cuáles fueron sus argumentos.

Paul Calabro
fuente
Puede tomar el proceso 'PID a través de: $$
Paul Calabro
2
No creo que sea una buena idea en general, porque si -xse configuró dentro del script, no se mostrará en la pssalida. Y esta solución es ineficiente de todos modos.
vinc17
Ese es un argumento justo. En realidad no sabía sobre la variable $. Ese parece ser un enfoque mucho mejor para resolver esto.
Paul Calabro
1
También está la set -osolución que he propuesto. También debería funcionar para opciones que no tienen un indicador asociado como -x.
vinc17