Chr*_*ing 10 bash shell-script
使用将有关自身的一些信息转储到 stderr 然后调用cat以形成管道的 bash 函数,我如何知道管道中的哪个阶段调用了哪个其他阶段?
一种解决方案是为每个阶段提供一个名称,如, a, b, c, d,然后当我查看输出时,我知道a > b > c > d. 但假设我不想命名阶段。有没有办法可以查看阶段的文件描述符并看到一个阶段stdout是另一个阶段,stdin所以我知道前者正在进入后者?如果是这样,我如何识别共享管道?我试过了,lsof但我不知道如何建立链条。
例如,
printf '%s\n' main "$(lsof -p $$ | grep dev)" > /dev/stderr
pipe() {
printf '%s %s:%s %s\n' $1 $BASHPID $BASH_SUBSHELL $$ > /dev/stderr
printf '%s\n' $1 "$(lsof -p $$ | grep dev)" > /dev/stderr
cat
}
echo
echo hi | pipe a | pipe b | pipe c | pipe d
Run Code Online (Sandbox Code Playgroud)
生产
main
bash 51147 Setup 0u CHR 16,2 0t476770 3717 /dev/ttys002
bash 51147 Setup 1u CHR 16,2 0t476770 3717 /dev/ttys002
bash 51147 Setup 2u CHR 16,2 0t476770 3717 /dev/ttys002
bash 51147 Setup 26u CHR 15,0 0t214349 579 /dev/ptmx
bash 51147 Setup 27u CHR 15,1 0t1206500 579 /dev/ptmx
a 51176:1 51147
d 51147:0 51147
b 51177:1 51147
c 51179:1 51147
b
bash 51147 Setup 1u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 2u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 26u CHR 15,0 0t214349 579 /dev/ptmx
bash 51147 Setup 27u CHR 15,1 0t1206500 579 /dev/ptmx
bash 51147 Setup 254u CHR 16,2 0t477304 3717 /dev/ttys002
d
bash 51147 Setup 1u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 2u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 26u CHR 15,0 0t214349 579 /dev/ptmx
bash 51147 Setup 27u CHR 15,1 0t1206500 579 /dev/ptmx
bash 51147 Setup 254u CHR 16,2 0t477304 3717 /dev/ttys002
a
bash 51147 Setup 1u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 2u CHR 16,2 0t477304 3717 /dev/ttys002
bash 51147 Setup 26u CHR 15,0 0t214349 579 /dev/ptmx
bash 51147 Setup 27u CHR 15,1 0t1206500 579 /dev/ptmx
bash 51147 Setup 254u CHR 16,2 0t477304 3717 /dev/ttys002
c
bash 51147 Setup 1u CHR 16,2 0t478702 3717 /dev/ttys002
bash 51147 Setup 2u CHR 16,2 0t478702 3717 /dev/ttys002
bash 51147 Setup 26u CHR 15,0 0t214349 579 /dev/ptmx
bash 51147 Setup 27u CHR 15,1 0t1206500 579 /dev/ptmx
bash 51147 Setup 254u CHR 16,2 0t478702 3717 /dev/ttys002
hi
Run Code Online (Sandbox Code Playgroud)
但我没有看到stdoutin的标识符a是stdinfor b。
xhi*_*nne 18
管道是匿名的(与命名管道相反),因为它们是用pipe(2)命令创建的。但是,它们当然有一个由lsof(您可以在 中看到ls -l /proc/<pid>/fd)显示的内部 ID 。
但是我没有看到 stdout 的标识符
a作为b.
这是因为您没有lsof采用正确的流程。$$扩展到您的脚本 PID,而不是由管道命令创建的子 shell 的 PID。您必须$BASHPID改用。
如此修改您的函数:
pipe() {
local pid=$BASHPID
printf '%s %s:%s %s\n' "$1" "$pid" "$BASH_SUBSHELL" $$ > /dev/stderr
printf '%s\n' "$1" "$(lsof -a -p "$pid" -d 0,1)" > /dev/stderr
cat
}
Run Code Online (Sandbox Code Playgroud)
你现在会得到类似的东西:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 1290 xhienne 0r FIFO 0,12 0t0 180254229 pipe
bash 1290 xhienne 1w FIFO 0,12 0t0 180254230 pipe
Run Code Online (Sandbox Code Playgroud)
... 其中节点号是管道的内部 ID。然后您将能够注意到管道 #12345678 将 stdout of 连接a到 stdin of b,依此类推。
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |