
open3
이 프로그램은 또는 실행 시 sleep 3
어떤 오류가 반환 true;sleep 3
되고 sleep
종료되는지 보여줍니다.
#!/bin/bash
doit() {
shell="$1"
prg="$2"
(sleep 2 && killall sleep) &
perl -MIPC::Open3 -e 'open3($a,$b,$c,"'$shell'","-c","'"$prg"'"); wait; print $?>>8,"\n"'
}
export -f doit
parallel -j1 --tag doit \
::: ash bash csh dash fdsh fish fizsh ksh ksh93 mksh posh rc sash sh static-sh tcsh yash zsh \
::: '/bin/sleep 3' 'true;/bin/sleep 3'
내 시스템에서는 다음을 제공합니다.
ash /bin/sleep 3 143
ash true;/bin/sleep 3 143
bash /bin/sleep 3 0
bash true;/bin/sleep 3 143
csh /bin/sleep 3 143
csh true;/bin/sleep 3 143
dash /bin/sleep 3 143
dash true;/bin/sleep 3 143
fdsh /bin/sleep 3 143
fdsh true;/bin/sleep 3 143
fish /bin/sleep 3 143
fish true;/bin/sleep 3 143
fizsh /bin/sleep 3 143
fizsh true;/bin/sleep 3 143
ksh /bin/sleep 3 0
ksh true;/bin/sleep 3 0
ksh93 /bin/sleep 3 0
ksh93 true;/bin/sleep 3 0
mksh /bin/sleep 3 0
mksh true;/bin/sleep 3 143
posh /bin/sleep 3 143
posh true;/bin/sleep 3 143
rc /bin/sleep 3 1
rc true;/bin/sleep 3 1
sash /bin/sleep 3 255
sash true;/bin/sleep 3 0
sh /bin/sleep 3 143
sh true;/bin/sleep 3 143
static-sh /bin/sleep 3 143
static-sh true;/bin/sleep 3 143
tcsh /bin/sleep 3 143
tcsh true;/bin/sleep 3 143
yash /bin/sleep 3 0
yash true;/bin/sleep 3 0
zsh /bin/sleep 3 0
zsh true;/bin/sleep 3 0
143을 반환하는 모든 프로그램을 설명할 수 있습니다. 그런데 다른 오류 값의 원인은 무엇입니까? 제가 특히 혼란스러워하는 점은 bash
두 가지 다른 값을 제공한다는 것입니다.
답변1
~을 위한
bash /bin/sleep 3 0
우리는 이 상황을 관찰할 수 있다strace
$ strace -f -e trace=process bash -c 'sleep 1'
execve("/usr/bin/bash", ["bash", "-c", "sleep 1"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7fe3740) = 0
execve("/usr/bin/sleep", ["sleep", "1"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7fe3740) = 0
exit_group(0) = ?
+++ exited with 0 +++
$
TERM
신호가 발생 하지 않는 경우 디스플레이는 bash
자체적으로 대체됩니다 sleep
. 이와 대조적으로 복합 형식은 종료 코드를 분기 하고 처리하는 대신 (Linux의 경우) true;sleep 3
을 표시합니다 .clone
bash
sleep
참여를 통해 SIGTERM
우리는 다음을 봅니다.
$ strace -f -e trace=process bash -c 'sleep 999'
execve("/usr/bin/bash", ["bash", "-c", "sleep 999"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7fe3740) = 0
execve("/usr/bin/sleep", ["sleep", "999"], [/* 22 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7fe3740) = 0
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=3896, si_uid=0} ---
+++ killed by SIGTERM +++
$ echo $?
143
$
이는 잘못된 Perl 코드로 이어집니다.Perl의 $?
16비트 상태어 표현from wait(2)
, 쉘이 16비트 상태 워드를 수정하는 값이 아닙니다. 신호의 경우 실제로 0인 종료 코드 정보만 인쇄합니다. 대신 print $?>>8
콘텐츠에 대한 올바른 확인을 사용하는 경우 :$?
#!/usr/bin/env perl
use 5.14.0;
use warnings;
use IPC::Open3 qw(open3);
my ( $input, $output, $err );
open3( $input, $output, $err, qw(bash -c), "sleep 999" );
wait;
if ( $? == -1 ) {
say "noexec $!";
} elsif ( $? & 127 ) {
printf "died signal=%d core=%s\n",
( $? & 127 ), ( $? & 128 ) ? 'yea' : 'nay';
} else {
say "exit ", $? >> 8;
}
bash -c 'sleep 3'
그러면 Perl은 종료를 올바르게 보고합니다 :
$ perl ipcopenfoo
died signal=15 core=nay
$