Bazı bash örneğinin içinde tam komut satırının yürütüldüğünü nasıl görebilirim?


29

Uzun süre çalışan bir bashörneğim var (bir screenoturumun içinde) bir döngü içinde karmaşık komutlar yürüten (her döngüde borular, yönlendirmeler, vb.).

Uzun komut satırı terminalin içine yazılmıştır - herhangi bir betiğin içinde değildir. Şimdi, bash işlem kimliğini biliyorum ve root erişimine sahibim - içinde komut satırının tam olarak nasıl çalıştığını nasıl görebilirim bash?

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

Ve başka bir kabuk örneğinde, PID 1234 içinde yürütülen komut satırını görmek istiyorum:

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'

Mümkün mü?

# 1 DÜZENLEME

Bazı cevaplar için karşı örnekler ekledim.

  1. cmdlineAltında kullanma hakkında /proc/PID: bu işe yaramaz, en azından benim senaryomda değil. İşte basit bir örnek:

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

    Başka bir kabukta:

    $ cat /proc/8909/cmdline
    bash
  2. Kullanmak ps -p PID --noheaders -o cmdaynı işe yaramaz:

    $ ps -p 8909 --no-headers -o cmd
    bash
  3. ps -eaf Ayrıca yararlı değil:

    $ 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

    Yani, ORİJİNAL komut satırının çıktısı yok, bu da aradığım şey - yani while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done.

Yanıtlar:


40

Çörekleri tuttuğumu biliyordum, ama UNIX asla başarısız olmaz!

İşte nasıl başardım:

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

Sonra (gdb)komut isteminde call write_history("/tmp/foo")bu geçmişi dosyaya yazacak olan komutu çalıştırdım /tmp/foo.

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

Daha sonra işlemden ayrılıyorum.

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

Ve istifa et gdb.

(gdb) q

Ve elbette yeterince ...

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

Gelecekteki kolay kullanım için işlemi otomatikleştiren bir bash betiği yazdım .


1
+1 çok güzel uyuma. Bunu 2 gün içinde A hariç olarak işaretleyin.
slm

@slm: Teşekkürler! Bununla ilgili bir blog yazısı yazacağım - eğlenceliydi, bunu avladım.
ttsiodras

1
İle taleb etkin ayrıca yapabilirsiniz gdb: print (char *)rl_line_buffer. Bir dizideki geçerli komut şudur print (char *)the_printed_command. Ayrıca call history_builtin(), ancak bu bash işleminin tty çıktısı olacak, bu yüzden daha az yararlı olabilir.
mr.spuratic

11
@slm: Karşı koyamadım - Burada blog yazdım
ttsiodras

1
Bash thread güvenli midir? Gdb'den bir şey yürüttüğünüzde çalışmakta olan kodu altüst eden bazı iç durumları değiştirmeyeceğinizi ümit etmeniz gerekecek. Uygulamada, bash, kesinlikle, kesinlikle, gdb ile askıya alındığında, çocuk sürecinin bitmesini bekliyor olacaktır.
Adrian Pronk

5

Komut hala ekranda çalıştığından, ana bash hiçbir geçmişi okumadı.

  • ekrana yeniden bağlayın
  • ^Zo zaman basup arrow
  • bonus: komutu tek tırnaklara sarın ( ^A^A- çünkü ekran (1) - ve ^E) ile gezinme ve echo + yönlendirmesini bir dosyaya
  • fg komut yürütmeyi sürdürmek

Uyarılar var, ama bu çoğu zaman yeterince kullanışlıdır.


Evet, onu öldürüp basmaya bile başla up. Her ne kadar herhangi bir sorun olmadan tekrar başlayacağından emin olmak zorunda olsanız da, ancak başlamazsa, yine de yeniden başlattıktan sonra aynı sorunu yaşarsınız. Bir kesinti bir sorun olmayacaksa anınızı seçmek zorundasınız.
Matthieu Napoli

0

Kendi cevabını bulduğunu biliyorum, ama böyle bir şey yapamamanın bir nedeni var:

(set -x; for f in 1 2 3 4 ; do  echo "$f"; sleep $f; done)

Belki de asıl işin çıktısını ve şu anda yürütülen satırı gösteren bash çıktısını birleştiremezsiniz.

Ayrıca, FWIW, ayrıntılandırmayı tercih ediyorsanız set -o xtrace,.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.