GNU/Linux >> Tutoriels Linux >  >> Linux

Comment voir la ligne de commande exacte en cours d'exécution dans une instance Bash ?

J'ai un long bash instance (à l'intérieur d'un screen session) qui exécute un ensemble complexe de commandes à l'intérieur d'une boucle (chaque boucle faisant des pipes, des redirections, etc.).

La longue ligne de commande a été écrite à l'intérieur du terminal - elle n'est dans aucun script. Maintenant, je connais l'ID du processus bash et j'ai un accès root - comment puis-je voir la ligne de commande exacte exécutée à l'intérieur de ce bash ?

Exemple

bash$ echo $$
1234
bash$ while true ; do 
    someThing | somethingElse 2>/foo/bar | 
    yetAnother ; sleep 600 ; done

Et dans une autre instance de shell, je veux voir la ligne de commande exécutée à l'intérieur du PID 1234 :

bash$ echo $$
5678
bash$ su -
sh# cd /proc/1234
sh# # Do something here that will display the string  
   'while true ; do someThing | somethingElse 2>/foo/bar | 
    yetAnother ; sleep 600 ; done'

Est-ce possible ?

MODIFICATION #1

Ajout de contre-exemples pour certaines réponses que j'ai.

  1. À propos de l'utilisation de la cmdline sous /proc/PID :cela ne fonctionne pas, du moins pas dans mon scénario. Voici un exemple simple :

    $ echo $$
    8909
    
    $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
    

    Dans un autre shell :

    $ cat /proc/8909/cmdline
    bash
    
  2. Utilisation de ps -p PID --noheaders -o cmd est tout aussi inutile :

    $ ps -p 8909 --no-headers -o cmd
    bash
    
  3. ps -eaf n'est pas non plus utile :

    $ ps -eaf | grep 8909
    ttsiod    8909  8905  0 10:09 pts/0    00:00:00 bash
    ttsiod   30697  8909  0 10:22 pts/0    00:00:00 sleep 30
    ttsiod   31292 13928  0 10:23 pts/12   00:00:00 grep --color=auto 8909
    

    C'est-à-dire qu'il n'y a pas de sortie de la ligne de commande ORIGINAL, ce que je recherche - c'est-à-dire le while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done .

Réponse acceptée :

Je savais que je m'accrochais à des pailles, mais UNIX n'échoue jamais !

Voici comment j'ai réussi :

bash$ gdb --pid 8909
...
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libnss_files.so.2
0xb76e7424 in __kernel_vsyscall ()

Puis au (gdb) invite J'ai exécuté la commande, call write_history("/tmp/foo") qui écrira cet historique dans le fichier /tmp/foo .

(gdb) call write_history("/tmp/foo")
$1 = 0

Je me détache alors du processus.

(gdb) detach
Detaching from program: /bin/bash, process 8909

Et quittez gdb .

(gdb) q

Et bien sûr…

bash$ tail -1 /tmp/foo
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

Pour une réutilisation ultérieure facile, j'ai écrit un script bash, automatisant le processus.


Linux
  1. Astuces Bash pour tous les jours en ligne de commande

  2. Bash Echo La ligne de commande exécutée sur la ligne de commande elle-même (pas dans un script) ?

  3. Comment définir la couleur de l'invite de commande dans Bash ?

  4. Comment puis-je obtenir mon adresse IP à partir de la ligne de commande ?

  5. Bash Loop - Comment arrêter la boucle lorsque j'appuie sur Control-C dans une commande ?

Comment utiliser la commande de lecture Bash

Comment créer une instance dans OpenStack via la ligne de commande

Comment afficher l'historique de Bash sans numéros de ligne

Comment utiliser la commande echo dans les scripts Bash sous Linux

Comment insérer une nouvelle ligne dans l'e-mail à l'aide de la commande linux mail ?

Comment modifier les lignes précédentes dans une commande à plusieurs lignes dans Bash ?