Comment savoir si le script bash en cours d'exécution a été appelé avec -x pour le débogage?


11

J'ai un script launch.shqui s'exécute en tant qu'autre utilisateur afin de créer des fichiers avec le bon propriétaire. Je veux passer -x à cette invocation si elle a été initialement transmise au 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

J'ai lu la page de débogage bash mais il ne semble pas y avoir d'option claire qui indique si le script d'origine a été lancé avec -x.

Réponses:


15

De nombreux indicateurs pouvant être passés bashsur la ligne de commande sont des setindicateurs. setest le shell intégré qui peut basculer ces drapeaux lors de l'exécution. Par exemple, appeler un script comme bash -x foo.shest fondamentalement la même chose que faire set -xen haut du script.

Sachant que setle shell intégré en est responsable nous permet de savoir où chercher. Maintenant, nous pouvons le faire help setet nous obtenons ce qui suit:

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

Donc, à partir de cela, nous voyons que cela $-devrait nous dire quels drapeaux sont activés.

$ bash -c 'echo $-'
hBc

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

Donc, fondamentalement, il vous suffit de faire:

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

En prime, si vous souhaitez copier tous les drapeaux, vous pouvez également faire

bash -$- /other/script.sh

1
Vous devrez utiliser [[ $- == *x* ]]pour la correspondance de motifs.
glenn jackman

1
Ou vous pouvez utiliser la norme case $- in *x*) ... ;; *) ... ;; esac. Il est utile de connaître cette utilisation de casescripts destinés à être portables, et maintenant que je le sais, je trouve plus facile de m'en souvenir que de se rappeler "si spécifique à bash, alors [[, sinon case".
hvd

OK, alors toute cette série de commentaires pourrait être supprimée.
l0b0

$-sorties hB. Que signifient les -het -Bdrapeaux / arguments font? Ne voyez pas alors dans la page de manuel de bash .
Dan Dascalescu

3

set -oaffichera xtrace onsi -xest utilisé, sinon xtrace off.


2

Bien que la réponse de @Patrick soit la "bonne", vous pouvez également passer un paramètre ou une variable exportée dans votre script enfant qui lui indique quoi faire - comme activer le traçage.

Cela a l'inconvénient que (je crois) vous devez le réexporter vers chaque niveau de script que vous êtes sur le point d'entrer.

Il a l'avantage de pouvoir tracer de manière sélective (ou autrement affecter) uniquement le (s) script (s) dont vous avez besoin du comportement de sortie / modifié - pour réduire la sortie étrangère, etc. Par exemple, le traçage peut être désactivé pour le script appelant et toujours activé dans le script appelé. Ce n'est pas une proposition tout ou rien.

Ne fait pas partie de votre question, mais est liée:

Je définis parfois une variable comme

E=""
E="echo "

ou

E=""
E=": "

et l'utiliser (dans plusieurs déclarations) comme

"${E}" rsync ...

ou, juste pour la deuxième variation,

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

Ensuite, je commente simplement la deuxième définition lorsque je veux exécuter la ou les commandes. Vous pouvez également utiliser cette technique avec un paramètre ou une variable exportée à la place.

Avec l'un ou l'autre, vous devez faire attention aux instructions composées car la méthode ne fonctionne que sur la première instruction de la liste composée.


1

Vous pouvez saisir le PID du processus, puis examiner la table de processus avec ps pour voir quels étaient ses arguments.


Vous pouvez récupérer le processus PID via: $$
Paul Calabro

2
Je ne pense pas que ce soit une bonne idée en général, car si le a -xété défini dans le script, il ne sera pas affiché en pssortie. Et cette solution est de toute façon inefficace.
vinc17

Voilà un argument juste. En fait, je ne connaissais pas la variable $ -. Cela semble être une bien meilleure approche pour résoudre ce problème.
Paul Calabro

1
Il y a aussi la set -osolution que j'ai proposée. Cela devrait également fonctionner pour les options qui n'ont pas de drapeau associé comme -x.
vinc17
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.