[Comm] man через ssh

Alexey Bochenin bochenin на avtlg.ru
Чт Фев 24 10:57:17 UTC 2011


24.02.2011 12:28, Dmitry Chistikov пишет:
> Добрый день!
>
> Начну с конца:
>
>> Если попробовать запустить в SSH-консоли
>> sh -c "(cd /usr/share/man&&  man-source
>> '/usr/share/man/man1/strace.1.bz2' '153' '1100i' | /usr/bin/nroff -S -p
>> -t -Dkoi8-r -mtty -mandoc | /usr/bin/less -isR)"
>> то ошибок нет
>
> Если Вы перечитаете вывод man -d strace, то обратите внимание на то, что
> сам последний sh -c "..." и не запускается: сообщения об ошибках выводятся
> раньше, например при определении preprocessor sequence:
>
>> [...]
>> bzip2: I/O or other error, bailing out.  Possible reason follows.
>> bzip2: Broken pipe
>> 	Input file = /usr/share/man/man1/strace.1.bz2, output file = (stdout)
>> using default preprocessor sequence
>> man:
>> not executing command:
>> [...]
>
> В этих местах man делает
> popen("/bin/bzip2 -c -d /usr/share/man/man1/strace.1.bz2", "r"),
> таким образом форкаясь и заменяя (execve()) дочерний процесс на
> sh -c "/bin/bzip2 -c -d /usr/share/man/man1/strace.1.bz2",
> который после этого делает еще один execve на собственно
> /bin/bzip2 -c -d /usr/share/man/man1/strace.1.bz2
>
> Этот bzip2 начинает разжимать руководство и выводить его крупными кусками
> в канал. Родительский процесс (сам man) читает из этого канала, причем
> на данный момент ему достаточно первого куска, после чего он делает
> pclose(). Если bzip2 еще не сделал всех своих write(), то на очередном
> вызове он получает SIGPIPE и умирает.
>
> У меня это происходит примерно так (заменил man -d на man -w, механика
> вроде не меняется):
>
> [pid 23192] write(1, ".\\\" Copyright (c"..., 4096) = 4096
> [pid 23191]<... read resumed>  ".\\\" Copyright (c"..., 4096) = 4096
> [pid 23191] waitpid(23192, Process 23191 suspended
>   <unfinished ...>
> [pid 23192] read(4, "", 4096)           = 0
> [pid 23192] write(1, ".  When the call"..., 4096) = -1 EPIPE (Broken pipe)
> [pid 23192] --- SIGPIPE (Broken pipe) @ 0 (0) ---
> Process 23191 resumed
> Process 23192 detached
> <... waitpid resumed>  [{WIFSIGNALED(s)&&  WTERMSIG(s) == SIGPIPE}], 0) = 23192
> --- SIGCHLD (Child exited) @ 0 (0) ---

Вот какое поведение наблюдаю у себя
$ ssh localhost -- strace -f -e trace=all -- man -w strace
...
[pid 27496] write(1, ".\\\" Copyright (c) 1991, 1992 Pau"..., 4096) = 4096
[pid 27495] <... read resumed> ".\\\" Copyright (c) 1991, 1992 Pau"..., 
4096) = 4096
[pid 27495] close(4)                    = 0
[pid 27495] wait4(27496, Process 27495 suspended
  <unfinished ...>
[pid 27496] read(4, "", 4096)           = 0
[pid 27496] write(1, " unfinished .\nWhen the call retu"..., 4096) = -32
[pid 27496] write(2, "\nbzip2: I/O or other error, bail"..., 67
bzip2: I/O or other error, bailing out.  Possible reason follows.
) = 67
[pid 27496] write(2, "bzip2: Broken pipe\n", 19bzip2: Broken pipe
) = 19
[pid 27496] write(2, "\tInput file = /usr/share/man/man"..., 71	Input 
file = /usr/share/man/man1/strace.1.bz2, output file = (stdout)
) = 71
[pid 27496] exit_group(1)               = ?
Process 27495 resumed
Process 27496 detached

>
> Таким образом, у меня bzip2 перед смертью не успевает ничего сказать.
> В Вашем примере, судя по всему, SIGPIPE не приводит к смерти bzip2,
> поэтому тот, зафиксировав i/o error (для него это критично), сообщает
> о пришедшем сигнале и завершается.
>
> Я делаю вывод, что в какой-то момент на SIGPIPE ставится обработчик.
> Попробуйте отследить, когда это происходит:
>
> $ ssh localhost -- strace -f -e trace=signal,process -- man -w strace
>
> Правильно ли я понимаю, что если не заворачивать все это дело в ssh,
> то bzip2 молчит?
>

Да, если не заворачивать все это дело в ssh, то bzip2 молчит. Ниже 
приведен strace по сигналам, но я не вижу SIGPIPE в листинге

$ ssh localhost -- strace -f -e trace=signal,process -- man -w strace

execve("/usr/bin/man", ["man", "-w", "strace"], [/* 15 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f3944605700) = 0
clone(Process 24150 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0x7f39446059d0) = 24150
[pid 24150] execve("/bin/sh", ["sh", "-c", "/bin/bzip2 -c -d 
/usr/share/man/"...], [/* 15 vars */]) = 0
[pid 24150] arch_prctl(ARCH_SET_FS, 0x7fa8bc650700) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24150] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24150] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24150] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigaction(SIGQUIT, {SIG_IGN, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigaction(SIGWINCH, {0x43e710, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24150] rt_sigaction(SIGCHLD, {0x42dcc0, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigprocmask(SIG_BLOCK, NULL, [PIPE], 8) = 0
[pid 24150] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_DFL, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {SIG_IGN, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 
0x7fa8bbf25750}, {0x42dcc0, [], SA_RESTORER, 0x7fa8bbf25750}, 8) = 0
[pid 24150] execve("/bin/bzip2", ["/bin/bzip2", "-c", "-d", 
"/usr/share/man/man1/strace.1.bz2"], [/* 15 vars */]) = 0
[pid 24150] arch_prctl(ARCH_SET_FS, 0x7f638fe02700) = 0
[pid 24150] rt_sigaction(SIGSEGV, {0x401950, [SEGV], 
SA_RESTORER|SA_RESTART, 0x7f638f6c9750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24150] rt_sigaction(SIGBUS, {0x401950, [BUS], 
SA_RESTORER|SA_RESTART, 0x7f638f6c9750}, {SIG_DFL, [], 0}, 8) = 0
[pid 24149] wait4(24150, Process 24149 suspended

bzip2: I/O or other error, bailing out.  Possible reason follows.
bzip2: Broken pipe
	Input file = /usr/share/man/man1/strace.1.bz2, output file = (stdout)
  <unfinished ...>
[pid 24150] exit_group(1)               = ?
Process 24149 resumed
Process 24150 detached
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 
24150
--- SIGCHLD (Child exited) @ 0 (0) ---
/usr/share/man/man1/strace.1.bz2
exit_group(0)                           = ?
$





-- 
WBR, Alexey


Подробная информация о списке рассылки community