Kısa cevap
In bash
(ve dash
) çeşitli "iş durumu" mesajları sinyal işleyici görüntülenen, ancak açık bir kontrol yapılmasını gerektirir değildir. Bu kontrol yalnızca yeni bir komut istemi yapılmadan önce yapılır, muhtemelen yeni bir komut yazarken kullanıcıyı rahatsız etmemelidir.
kill
Muhtemelen, işlem henüz ölmediği için görüntülenmesinden hemen sonraki istemden önce gösterilmez - kill
kabuğun dahili bir komutu olduğu için bu özellikle olası bir durumdur , bu nedenle yürütmek çok hızlıdır ve çatallamaya gerek yoktur.
Bunun killall
yerine, aynı deneyi yapmak genellikle hemen "öldürülmüş" mesajını verir, zaman / bağlam anahtarlarının / harici bir komutun yürütülmesi için gereken her şeyin, kontrol kabuğa dönmeden önce işlemin öldürülmesi için yeterince uzun bir gecikmeye neden olduğunu belirtin .
matteo@teokubuntu:~$ dash
$ sleep 60 &
$ ps
PID TTY TIME CMD
4540 pts/3 00:00:00 bash
4811 pts/3 00:00:00 sh
4812 pts/3 00:00:00 sleep
4813 pts/3 00:00:00 ps
$ kill -9 4812
$
[1] + Killed sleep 60
$ sleep 60 &
$ killall sleep
[1] + Terminated sleep 60
$
Uzun cevap
dash
Her şeyden önce, aynı davranışı sergilediği ve kod kesinlikle daha basit olduğu için, dash
kaynaklara bir göz vardı .dash
bash
Yukarıda belirtildiği gibi, nokta, iş durumu mesajlarının bir sinyal işleyicisinden ("normal" kabuk kontrol akışını kesintiye uğratabilecek şekilde) yayılmadığı, ancak yapılan açık bir kontrolün (bir showjobs(out2, SHOW_CHANGED)
çağrı girişi dash
) sonucudur. yalnızca kullanıcıdan yeni girdi talep etmeden önce, REPL döngüsünde.
Böylece, kullanıcı girişi beklenirken kabuk engellenirse böyle bir mesaj gönderilmez.
Şimdi, öldürmeden hemen sonra yapılan kontrol neden sürecin gerçekten sonlandığını göstermiyor? Yukarıda açıklandığı gibi, muhtemelen çok hızlı olduğu için. kill
kabuğun dahili bir komutudur, bu nedenle yürütülmesi çok hızlıdır ve çatallamaya gerek yoktur, bu nedenle, kill
kontrol gerçekleştirildikten hemen sonra , süreç hala hayatta (veya en azından hala öldürülüyor).
bash
Beklendiği gibi, bash
çok daha karmaşık bir kabuk olmak, daha gdb
hileli ve biraz -fu gerekiyordu.
Bu mesajın yayıldığı zamanki iz,
(gdb) bt
#0 pretty_print_job (job_index=job_index@entry=0, format=format@entry=0, stream=0x7ffff7bd01a0 <_IO_2_1_stderr_>) at jobs.c:1630
#1 0x000000000044030a in notify_of_job_status () at jobs.c:3561
#2 notify_of_job_status () at jobs.c:3461
#3 0x0000000000441e97 in notify_and_cleanup () at jobs.c:2664
#4 0x00000000004205e1 in shell_getc (remove_quoted_newline=1) at /Users/chet/src/bash/src/parse.y:2213
#5 shell_getc (remove_quoted_newline=1) at /Users/chet/src/bash/src/parse.y:2159
#6 0x0000000000423316 in read_token (command=<optimized out>) at /Users/chet/src/bash/src/parse.y:2908
#7 read_token (command=0) at /Users/chet/src/bash/src/parse.y:2859
#8 0x00000000004268e4 in yylex () at /Users/chet/src/bash/src/parse.y:2517
#9 yyparse () at y.tab.c:2014
#10 0x000000000041df6a in parse_command () at eval.c:228
#11 0x000000000041e036 in read_command () at eval.c:272
#12 0x000000000041e27f in reader_loop () at eval.c:137
#13 0x000000000041c6fd in main (argc=1, argv=0x7fffffffdf48, env=0x7fffffffdf58) at shell.c:749
Ölü işleri ve eşleri kontrol eden çağrı. olduğu notify_of_job_status
(daha fazla veya daha az eşdeğer showjobs(..., SHOW_CHANGED)
olarak dash
); # 0- # 1 iç çalışmasıyla ilgilidir; 6-8 yacc tarafından üretilen ayrıştırıcı kodudur; 10-12 REPL döngüsüdür.
Buradaki ilginç yer # 4, yani notify_and_cleanup
çağrının geldiği yer. Görünüşe göre bash
, dash
komut satırından okunan her karakterde sonlandırılmış işleri kontrol edebilir, ancak bulduğum şey:
/* If the shell is interatctive, but not currently printing a prompt
(interactive_shell && interactive == 0), we don't want to print
notifies or cleanup the jobs -- we want to defer it until we do
print the next prompt. */
if (interactive_shell == 0 || SHOULD_PROMPT())
{
#if defined (JOB_CONTROL)
/* This can cause a problem when reading a command as the result
of a trap, when the trap is called from flush_child. This call
had better not cause jobs to disappear from the job table in
that case, or we will have big trouble. */
notify_and_cleanup ();
#else /* !JOB_CONTROL */
cleanup_dead_jobs ();
#endif /* !JOB_CONTROL */
}
Bu nedenle, etkileşimli modda , muhtemelen kullanıcının komutları girmesini rahatsız etmemek için yeni bir bilgi istemi sağlanana kadar denetimi ertelemek niyetlidir . Kontrolün hemen ardından yeni istemi görüntülerken denetimin ölü işlemi fark etmemesine gelince kill
, önceki açıklama geçerlidir (işlem henüz ölmedi).
pid="$(sh -c 'cat "$fileName" |less & echo ${!}')"
ama daha az görünmeyecek