1 votes

La chaîne de l'invite PS4 se duplique lors de l'utilisation de set -x

Mon OS : Ubuntu 18.04.5 LTS

J'utilise le traçage pour dépanner un script. J'ai remarqué différents comportements dans le traçage selon la façon dont je le configure. J'aimerais comprendre pourquoi il se comporte de cette façon.

Normalement, j'active le traçage en utilisant set -x dans mon script où j'ai besoin que le traçage ait lieu. Cependant, le PS4 de la chaîne d'invite ("+ " par défaut) semble se "dupliquer".

enter image description here

Si j'active le traçage dans la ligne shebang # !, PS4 n'est imprimé qu'une seule fois.

enter image description here

De même, si j'appelle bash directement pour exécuter mon script, et en spécifiant -x dans la ligne de commande, PS4 n'est également imprimé qu'une seule fois.

enter image description here

Pourquoi est-ce que set -x se comporte-t-il différemment dans le premier exemple ? Je suppose qu'il y a quelque chose de fondamental dans le Shell que je ne comprends pas ici...

1voto

steeldriver Points 118154

La distinction ici n'est pas de savoir où vous placez le -x il s'agit de savoir si vous spécifiez un Shell à utiliser (soit via un shebang, soit en invoquant le Shell explicitement avec bash -x ).

Según man bash , PS4 :

   PS4    The value of this parameter is expanded  as  with  PS1  and  the
          value  is  printed  before  each command bash displays during an
          execution trace.  The first character of PS4 is replicated  mul
          tiple  times, as necessary, to indicate multiple levels of indi
          rection.  The default is ``+ ''.

Cependant, elle n'est pas franche sur ce que "niveaux d'indirection" signifie dans ce contexte.

Lorsque vous essayez d'exécuter un fichier texte sans spécifier l'interpréteur à utiliser, l'appel système à la fonction execve échoue avec ENOEXEC (Exec format error) . Ce qui se passe ensuite dépend du Shell à partir duquel vous essayez de l'exécuter, comme décrit ici :

En particulier, si le Shell invoquant est bash alors le script semble être exécuté directement par le script qui l'invoque : cela semble être l'"indirection" mentionnée dans le manuel :

$ strace -e trace=%process -f bash -c 'echo "Starting $0"; ./hw_no_shebang; echo "Finished."'
execve("/bin/bash", ["bash", "-c", "echo \"Starting $0\"; ./hw_no_sheb"...], 0x7ffd3dadbee8 /* 25 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7f95fe939740) = 0
Starting bash
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f95fe939a10) = 26515
strace: Process 26515 attached
[pid 26514] wait4(-1,  <unfinished ...>
[pid 26515] execve("./hw_no_shebang", ["./hw_no_shebang"], 0x555e5058a4f0 /* 25 vars */) = -1 ENOEXEC (Exec format error)
++ echo Hello
Hello
++ echo World
World
++ set +x
[pid 26515] exit_group(0)               = ?
[pid 26515] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26515
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26515, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7fffba5272d0, WNOHANG, NULL) = -1 ECHILD (No child processes)
Finished.
exit_group(0)                           = ?
+++ exited with 0 +++

Notez que le bash -c dans l'appel de strace prend ici la place de votre Shell interactif, plutôt que de l'appel de la bash -x que vous avez utilisé dans votre dernier exemple.

Dès que nous ajoutons un shebang, ex.. :

$ cat hw_shebang
#!/bin/bash

set -x
echo "Hello"
echo "World"
set +x

alors (indépendamment du fait que -x est invoqué en utilisant set ou autre), alors execve réussit et le script est exécuté dans son propre script, sans "indirection" :

$ strace -e trace=%process -f bash -c 'echo "Starting $0"; ./hw_shebang; echo "Finished."'
execve("/bin/bash", ["bash", "-c", "echo \"Starting $0\"; ./hw_shebang"...], 0x7ffccc0af338 /* 25 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7f81b9ed2740) = 0
Starting bash
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f81b9ed2a10) = 26553
strace: Process 26553 attached
[pid 26552] wait4(-1,  <unfinished ...>
[pid 26553] execve("./hw_shebang", ["./hw_shebang"], 0x55879d9924f0 /* 25 vars */) = 0
[pid 26553] arch_prctl(ARCH_SET_FS, 0x7fa55de83740) = 0
+ echo Hello
Hello
+ echo World
World
+ set +x
[pid 26553] exit_group(0)               = ?
[pid 26553] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26553
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26553, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffda2983b10, WNOHANG, NULL) = -1 ECHILD (No child processes)
Finished.
exit_group(0)                           = ?
+++ exited with 0 +++

Si vous aviez invoqué le no-shebang script à partir de dash par exemple, le comportement serait différent : après l'échec initial execve il aurait execve 'd /bin/sh pour exécuter le script :

$ strace -e trace=%process -f dash -c 'echo "Starting $0"; ./hw_no_shebang; echo "Finished."'
execve("/bin/dash", ["dash", "-c", "echo \"Starting $0\"; ./hw_no_sheb"...], 0x7ffc283d8638 /* 25 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7fd2cc787540) = 0
Starting dash
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd2cc787810) = 26590
strace: Process 26590 attached
[pid 26589] wait4(-1,  <unfinished ...>
[pid 26590] execve("./hw_no_shebang", ["./hw_no_shebang"], 0x557143e3c8d8 /* 25 vars */) = -1 ENOEXEC (Exec format error)
[pid 26590] execve("/bin/sh", ["/bin/sh", "./hw_no_shebang"], 0x557143e3c8d8 /* 25 vars */) = 0
[pid 26590] arch_prctl(ARCH_SET_FS, 0x7f3b9aa14540) = 0
+ echo Hello
Hello
+ echo World
World
[pid 26590] exit_group(0)               = ?
[pid 26590] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26590
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26590, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
Finished.
exit_group(0)                           = ?
+++ exited with 0 +++

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X