Çalışan bir sürecin çıktısını başka bir bash oturumunda nasıl görebilirim?


199

Yerel olarak üzerinde çalıştığım andan itibaren uzaktaki bir bilgisayarda çalışan bir komut dosyası bıraktım. SSH üzerinden makineye aynı kullanıcı ile bağlanabilir ve içinde çalışan betiği görebilirim ps.

$ ps aux | grep ipcheck
myuser  18386  0.0  0.0  18460  3476 pts/0    S+   Dec14   1:11 /bin/bash ./ipchecker.sh

Sadece yerel bir oturumda stdout çıktısı ( ./ipchecker.shyerel bir terminal penceresi oluşturdum, yönlendirme yok, screenvb. Kullandım).

Yine de bir SSH oturumundan bu çalışan komutun çıktısını görüntüleyebiliyor muyum (durdurmadan)?

Şimdiye kadar bulduğum en iyi şey kullanmak strace -p 18386ama ekrana uçan metin orduları alıyorum, çok ayrıntılı. Ben durdurabilir straceve daha sonra çıkışı elemek ve metin bekletilmektedir ama onun çok uzun ve kafa karıştırıcı ve durdu iken açıkçası kaçırabilir şey getirmek bulabilirsiniz. Senaryo çıkışını yerel olarak çalışıyormuş gibi canlı olarak görmenin bir yolunu bulmak istiyorum.

Bunu geliştirebilecek biri var mı? Açıkça cevap, komut dosyasını yeniden yönlendirme ile veya bir screenoturumda vb . Yeniden başlatmaktır , bu kritik bir komut dosyası değildir, bu yüzden bunu yapabilirim. Yine de, bunu eğlenceli bir öğrenme alıştırması olarak görüyorum.


İşleminiz sanal bir konsolda mı yoksa GUI / xterm benzeri bir ortamda mı çalışıyor?
jippie

4
strace -p 4232 -e write
Strace

@jippie Makine tam bir GUI (Linux Mynt 13, XFCE masa üstü) kullanıyor, bir gnome-terminali çalıştırdım.
jwbensley

3
Bu sitede en az bir düzine benzer soru var. Bunlardan birkaçı (ve bir cevap) bulmak için burada reptyr arayın .
Stéphane Chazelas,

Yanıtlar:


180

Yapmak istediğiniz tek şey var olan işlemi casus strace -p1234 -s9999 -e writeyapmaksa, işlem kimliğinin 1234 olduğu yerde kullanabilirsiniz . ( -s9999dizelerin 32 karaktere kesilmesini ve writeçıktı üreten sistem çağrısını engellemekten kaçınır .) Yalnızca belirli bir dosya tanımlayıcıda yazılan verileri görüntülemek istiyorsanız, strace -p1234 -e trace= -e write=3yalnızca dosya tanımlayıcı 3'e yazılan verileri görmek gibi bir şey kullanabilirsiniz ( -e trace=sistemi önler kaydedilmiş olan aramalar). Bu size zaten üretilmiş olan çıktıyı vermez.

Çıktı çok hızlı kayıyorsa, onu gibi bir çağrı cihazına yönlendirebilir lessveya ile bir dosyaya gönderebilirsiniz strace -o trace.log ….

Birçok programda, sonraki çıktınızı ptrace hack ile mevcut terminalinize veya yeni bir ekran oturumuna yönlendirebilirsiniz. Bkz. Çalışan bir işlemi nasıl reddedebilir ve yeni bir ekran kabuğuyla ilişkilendirebilirim? ve diğer bağlantılı iplikler.

Sisteminizin nasıl kurulduğuna bağlı olarak, tüm bunları çalıştırmanız gerekebilir. strace olarak, işlem kullanıcınız altında çalışıyorsa, ek ayrıcalıklara sahip olmasanız bile, komutları root olarak unutmayın. (İşlem farklı bir kullanıcı olarak çalışıyorsa veya ayarlanmış veya ayarlanmışsa, straceroot olarak çalıştırmanız gerekir .) Çoğu dağıtım yalnızca bir sürecin çocuklarını izlemesine izin verir (bu orta derecede bir güvenlik avantajı sağlar - bazı doğrudan kötü amaçlı yazılım bulaşmasını önler, ancak dosyaları değiştirerek dolaylı enjeksiyon yapılmasını engellemez). Bu kernel.yama.ptrace_scomesysctl tarafından kontrol edilir .


18
Çıktıyı sadece standart çıktıya daraltmanın bir yolu olduğunu sanmıyorum ?
Jonah

3
Tüm argümanları açıklayabilir misiniz?
Kullanıcı

6
Düğümlerden aldığım çıktıların çoğunda ters eğik çizgiler ve sayılar vardı; Hangi kodlamada olduklarına dair ipucu var mı? İhtiyacım olan tek şey de vardı.
ThorSummoner

3
"Tüm argümanları açıklayabilir misiniz?" @ Kullanıcı:man strace
Pistos

3
@RafaelMoni İstediğiniz şeyi yapmak için bir program bir hata ayıklayıcı denir.
Gilles,

139

Çıkışı, procÇıktıya dosya sistemi .

tail -f /proc/<pid>/fd/1

1= stdout, 2= stderr


7
Bana şunu veriyor: 'Okuma için / proc / <pid'im> / fd / 1 açılamıyor: Böyle bir cihaz veya adres yok'.
Yaroslav Nikitenko

18
evet <
pid'im

29
Bu, çıktı bir tty'ye (ya da yönlendirildiği /dev/null) giderse işe yaramaz - yalnızca çıktı bir dosyaya yönlendirilirse çalışır.
mattdm

1
Ubuntu 16.04 üzerinde test edilmiştir ve çalışmaz. Bir oturumda yaparım: ping google.esve bir diğerinde kök olarak: tail -f /proc/`pgrep ping`/fd/2ve hiçbir şey gösterilmez.
david.perez

1
Haklısın. Çünkü fd 1 ve 2, / dev / pts aygıtına sembolik bağlar kurar. Kaza yapamazsın, bir pts aygıtı. Ping komutunuzu bir cronjob olarak programlayın ve ardından aynı şeyi yapın. kuyruk -f sonra çalışacak
tvlooy 11

9

BSD'de, watchhangi tipte bir tty kullandığınızı, örneğin

watch /dev/pts/0

Linux'ta, işlem daha önce screenveya daha önce olduğu gibi çoklayıcı altında yapılmadıysa mümkün olmaz tmux. Ayrıca bakınız: Reptyr: Çalışan Bir İşlemi Yeni Bir Terminale Eklemek

Bu işlemde hata ayıklamak için tek yoldur görünüyor (örn strace, dtrace/ dtruss, gdb,lldb , vb.)

Kullandığınızdan strace, anlamlı bir çıktı almak için, uygun bir ifadeye göre filtrelemeniz (örneğin file) ve daha sonra çıktıyı ayrıştırmanız gerekir. İşte örnek:

strace -e trace=write -s1000 -fp 18386 2>&1 | grep -o '".\+[^"]"'

Ne yazdırıyor PID ile belirtilen işlemin (1000 uzunluk) yazma işlemini yazdırır. pgrep isim ile bulmak için ), standart hatayı çıktıya (filtre edilecek) yönlendirir ve çift tırnaklı dize yazdırır.

İkili çıktı ile uğraşıyorsanız, kaçış dizileri karakterlerini read(with -r) ve printf (with %b) ile ayrıştırabilirsiniz ;

while read -r -t1 line; do printf "%b" $line; done

help readDaha fazla parametre olup olmadığını kontrol edin (örneğin -n, yeni satır yerine belirli sayıda karakterden sonra yazdırmak için).

İşte daha eksiksiz bir örnek:

strace -e trace=write -s1000 -fp 18386 2>&1 \
| grep --line-buffered -o '".\+[^"]"' \
| grep --line-buffered -o '[^"]\+[^"]' \
| while read -r line; do
  printf "%b" $line;
done

Herhangi bir işlemi kullanan örnekler için lütfen şunları kontrol edin: Kabukta strace nasıl düz metne ayrıştırılır? stackoverflow'ta


4
  1. Uzak sunucu oturum açma kimlik bilgilerinizle ssh localhost 'DISPLAY=:0.0 xwd -root' | xwud -scalenerede localhostdeğiştirileceğini ve :0.0GUI'nizin ekran numarasını kullanarak uzaktaki ekranda göz atabilirsiniz.

  2. x11vncEkran X oturumu için bir VNC sunucusu olan kullanın .

  3. 6 sanal konsoldan birinde çalışırken sudo setterm -dump 2 -file /dev/stdout, 2uygun vc ile değiştireceğiniz yeri deneyin .


4

Bir adlandırılmış yöneltme ( mkfifo) yapmanızı ve daha sonra bu dosyaya yazmanızı öneririm . Sonra, ondan oku. tailÇıktıyı en aza indirmek, vb. Gibi şeylerle her zaman yapabilirsiniz . Boruyu her temizlediğinizde (ondan okuyun) temizlenir, böylece çıktı korunmaz.

Diğer seçenek ise her şeyi bir dosyaya yazmaktır (bir logfile gibi) ve daha sonra istediğiniz zaman analiz etmektir. Tüm çıktıları korumak istiyorsanız, bu tercih edilen eylem olacaktır.


3

Her zaman bir süreç nereye başlatabilir nohup ve &

nohup rsync source_file dest_file &

Ardından, ilerlemenizi herhangi bir numaradan kontrol edebilirsiniz:

tail -f nohup.out

Bu bana iyi çalışıyor.


6
Cevabınız anlaşılacağı gibi ben bir uyarı çalışan sürecinin çıkışını görüntülemek hakkında olur bu soru değil, nasıl arka planda bir süreci çalıştırmak için
jwbensley

Aslında, senin: nohup bahset beni aydınlatıyor! Teşekkürler!
Nam G VU

1

Çıktıyı almak çok basit bir çıktıyı bir dosyaya yakalamak ve bu dosyayı takip etmek olacaktır.

EĞER YAPMAK: ./ipcheck

KURULUM YAPIN: ./ipcheck> [dosya adınızla değiştirin]

Bu, komut dosyanızın bulunduğu bir çıktı dosyası oluşturur. Daha sonra herhangi bir bash kabuğundan, dosyayı basitçe yerleştirebilirsiniz:

kuyruk [yerine dosyaadeni] -f


Dosya yeniden yönlendirme, varsayılan olarak ( sorunlu setbuf(3)) olabilecek blok tabanlı arabelleklemeyi kullanma eğilimindedir tail.
thrig

5
Ayrıca bu, stdout'un yeni bir işlem için nasıl yönlendirileceğinden değil, halihazırda çalışan bir sürecin çıktısının nasıl görüntüleneceği ile ilgili olan soruya yardımcı olmaz.
jwbensley

1

Strace çıktısının ayrıştırılması:

En üstteki cevabı kullandım (28223 işlem kimliğimle) ...

> sudo strace -p28223 -s9999 -e write
...
write(9, "Info\nI\nCare\nabout", 55) = 55
...

Umurumda olduğumu belirlemek için write(9. (Aşağıda 9 kullanılır, muhtemelen bir dosya tanıtıcısıdır ve işleminiz için farklı olabilir.) Sonra bunları ayrıştırmak ve görüntülemek için hızlı bir Ruby betiği yazdım.

Aşağıdakini yapıştırın /usr/bin/parse_strace.rb

#!/usr/bin/ruby

num = ARGV[0]
STDIN.each { |line|
  if (line.match(/write\(#{ num },\s*"(.*?)"/)) then
    puts $1.split('\x').map { |s| s.to_i(16).chr }.join()
  end
}

Unutma chmod a+x /usr/bin/parse_strace.rb

Ben çağırdım strace -xx(hex çıktılar, böylece regex düzgün eşleşir), betiğime (STDERR dahil) 9ilk argümanla bağladım.

sudo sh -c 'strace -xx -p28223 -s9999 -e write 2>&1 | parse_strace.rb 9'

Ve işte, işlemin orijinal STDOUT, newlines, color ve hepsini çıkarır!

STDOUT işlemine ekleme


0

işlem kimliğini alamaz ve bununla USR1 ile iletişim kuramazsanız,

$pgrep -l '^ipchecker.sh$'

betiğinizin PID’ini yazdırır, sonra

$ kill -USR1 PID

USR1'in "kullanıcı tanımlı" bir sinyal olduğunu anlıyorum, yani programı oluşturan kişi onu "kapatma" veya "günlüklerinizi atma" ya da "bin kere basma" ya da her neyse "kullanabilir" anlamına gelir.

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.