2012-02-21 48 views

回答

0

這並不容易直接做到這一點,但你可以使用下面的信息來重新創建管道:

  • 腳本的PID是$$環境變量
  • 使用ps -fe,看着2列3你可以找到您的腳本的父母和父母的父母等。流水線由一系列直接祖先組成,您可以沿着路徑向下處理PID 1(init流程或同等處理)。
  • 知道每個進程的PID,你可以從/proc/PID/cmdline(獲得它的命令行使用tr人類可讀的格式
  • 空格代替'\0'的。如果你知道腳本從管道叫,你基本上完成如果你需要知道它是從流水線調用的還是交互式的,你可能需要檢查ls -lh /proc/self/fd/0打印什麼,這是第0個文件描述符,意思是標準輸入,如果它指向/dev/someting(如/dev/pts/XX)如果鏈接的目標是以pipe:[開頭的,那麼很可能你正在從管道中接收數據(它也可能是一個網絡套接字,但是希望你可以在你的設置中將這種情況排除在外)
1

在這裏你去:

#!/usr/bin/env bash 

siblings=($(pgrep -P "$(ps -p $$ o ppid=)" | grep -Fvx $$)) 
pids=$$ 
sibling=$$ 

while true 
do 
    pid=$sibling 
    for sibling in ${siblings[@]} 
    do 
     if [ "$(readlink "/proc/${sibling}/fd/1")" = "$(readlink "/proc/${pid}/fd/0")" ] 
     then 
      # Found previous pipe process 
      pids="${sibling},${pids}" 
      continue 2 
     fi 
    done 
    break # No previous pipe process 
done 

while IFS= read -r line 
do 
    pipeline="${pipeline+${pipeline} | }$line" 
done < <(ps --sort=pid -p "$pids" o args=) 
printf '%s\n' "$pipeline" 

例子:

$ ./test.sh 
bash ./test.sh 

$ cat /dev/zero | sleep 1 | ./test.sh 
cat /dev/zero | sleep 1 | bash ./test.sh 

工作的一個小project使之成爲一個合適的工具。

+0

這將打印原始管道的組件,而不是原始管道本身。 – chepner 2013-06-18 14:31:51

+1

這應該做到這一點。 – l0b0 2013-06-18 15:10:57

相關問題