Come posso sapere se lo script bash attualmente in esecuzione è stato invocato con -x per il debug?


11

Ho uno script launch.shche si esegue come un altro utente in modo da creare file con il proprietario corretto. Voglio passare -x a questa invocazione se è stata originariamente passata allo 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

Ho letto la pagina di debug di bash ma non sembra esserci alcuna opzione chiara che indichi se lo script originale è stato avviato -x.

Risposte:


15

Molti dei flag a cui è possibile passare bashdalla riga di comando sono setflag. setè la shell integrata che può attivare o disattivare questi flag in fase di esecuzione. Ad esempio, chiamare uno script come bash -x foo.shsostanzialmente è come fare set -xnella parte superiore dello script.

Sapere che setè la shell integrata responsabile di ciò ci consente di sapere dove cercare. Ora possiamo fare help sete otteniamo quanto segue:

$ 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.
...

Quindi da questo vediamo che $-dovrebbe dirci quali flag sono abilitati.

$ bash -c 'echo $-'
hBc

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

Quindi in pratica devi solo fare:

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

Come bonus, se vuoi copiare tutte le bandiere, puoi anche farlo

bash -$- /other/script.sh

1
Dovrai utilizzare [[ $- == *x* ]]per la corrispondenza dei motivi.
Glenn Jackman,

1
Oppure potresti usare lo standard case $- in *x*) ... ;; *) ... ;; esac. È utile conoscere questo uso di casescript che sono pensati per essere portatili, e ora che ne sono a conoscenza, trovo più facile ricordarlo, piuttosto che ricordare "se specifico di bash, quindi [[, altro case".
hvd,

OK, allora tutta questa serie di commenti potrebbe essere eliminata.
l0b0,

$-uscite hB. Che cosa l' -he -Bbandiere / argomenti fanno? Non vedere quindi nella pagina man di bash .
Dan Dascalescu,

3

set -overrà emesso xtrace onse -xutilizzato, altrimenti xtrace off.


2

Sebbene la risposta di @Patrick sia "giusta", puoi anche passare un parametro o una variabile esportata nello script figlio che gli dice cosa fare, come attivare la traccia.

Questo ha lo svantaggio che (credo) devi riesportarlo ad ogni livello di script che stai per inserire.

Ha il vantaggio di essere in grado di tracciare selettivamente (o influenzare in altro modo) solo gli script da cui hai bisogno dell'output / comportamento modificato - per ridurre l'output estraneo, ecc. Ad esempio, la traccia può essere disattivata per lo script chiamante e viene ancora attivato nello script chiamato. Non è una proposta tutto o niente.

Non fa parte della tua domanda, ma è correlato:

A volte definisco una variabile come

E=""
E="echo "

o

E=""
E=": "

e usarlo (in più istruzioni) come

"${E}" rsync ...

o, solo per la seconda variante,

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

Quindi, ho solo commentato la seconda definizione quando voglio che i comandi vengano eseguiti. Puoi anche usare questa tecnica con un parametro o una variabile esportata.

Con uno di questi, devi fare attenzione alle istruzioni composte perché il metodo è garantito per funzionare solo sulla prima istruzione nell'elenco composto.


1

Puoi prendere il PID del processo e quindi esaminare la tabella dei processi con ps per vedere quali sono stati gli argomenti.


Puoi prendere il processo 'PID tramite: $$
Paul Calabro il

2
Non penso che sia una buona idea in generale, perché se è -xstato impostato all'interno dello script, non verrà mostrato in psoutput. E questa soluzione è comunque inefficiente.
vinc17,

Questa è una discussione giusta. In realtà non sapevo della variabile $. Sembra un approccio molto migliore per risolvere questo.
Paul Calabro,

1
C'è anche la set -osoluzione che ho proposto. Dovrebbe funzionare anche per le opzioni che non hanno un flag associato come -x.
vinc17,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.