파이프라인 데이터를 생성하는 명령 가져오기

파이프라인 데이터를 생성하는 명령 가져오기

현재 명령이 실행되기 전에 실행된 명령을 설명하는 문자열에 액세스하는 방법을 알고 싶습니다.

예를 들어, 다음을 실행하면:

ls | myscripthere

나는 "ls" 명령이 STDIN을 통해 얻은 출력을 생성하는 명령임을 알 수 있기를 원합니다. 이를 수행할 수 있는 방법이 있습니까?

감사해요

답변1

파이프의 수신측 프로그램은 실제로 들어오는 데이터가 어디서 오는지 알 수 있는 방법이 없습니다. 귀하의 예를 사용하여 :

$ ls | myscript

표준 출력은 ls표준 입력으로 리디렉션됩니다 myscript. 그러나 이는 다음과 전혀 구별할 수 없습니다.

$ ls > datafile
$ myscript < datafile

또는

$ ls > datafile
$ cat datafile | myscript

또는

$ wget -o - https://www.example.com/some/file/that/resembles/the/output/of/ls | myscript

또는

$ ls | sed '/secrethiddenfile/d' | myscript

심지어

$ cat - | myscript

말은 말일 뿐입니다.

답변2

다음을 수행할 수 있습니다.

echo 'ls' | read var;echo $var > var_file;$var | myscript

명령의 값을 파일에 기록합니다 var_file.

echo 'ls'문자열 입력으로 제공 되며 ls값은 var가 됩니다 ls. $var로 확장되어 ls출력을 myscript.

여러 명령이 있고 이를 한 줄씩 가져오려면 var_file다음 >을 바꾸십시오 >>.

echo 'ls' | read var;echo $var >> var_file;$var | myscript

답변3

일반적으로 다음과 같은 이유로 이는 불가능합니다.

파이프라인의 각 명령은 자체 하위 셸에서 실행됩니다.

(에서배쉬 매뉴얼).

send 명령이 충분히 오래 지속되면 이를 찾을 수 있는 기회가 있습니다. 다음은 "수신자" 스크립트의 예입니다. lsof수신자의 stdin에 해당하는 NODE 열을 가져온 다음 lsof일치하는 stdout NODE가 있는 프로세스에 대한 더 넓은 출력을 검색합니다.

#!/bin/sh
# look for f0 and get its node
node=$(lsof -p "$$" -Ffi | awk '/^p/ { node=""; } /^f0$/ { getline; node=substr($0, 2); exit; } END { print node }')

# run lsof and get the pid(s) with f1 whose node match $node
lsof -Ffci | awk -v node="$node" '
  /^c/ { procname=substr($0, 2); }
  /^f1$/ { getline; thisnode=substr($0, 2); }
  /^p/ { if (procname != "" && thisnode == node) { print procname; procname=""; thisnode=""; } }
  END { if (procname != ""&& thisnode == node) print procname; }
  '
cat

답변4

내 프로그램에서 이 기능을 사용하여 .bash_aliasesTee와 같은 도구를 제공합니다.

function teee { 
#This can be used between pipes to print on screen what is coming in from the left command and flows to the next command
        v="$(</dev/stdin)"; 
        echo '---------------- pipe entry-------------' >/dev/tty;
        while read -r l;do 
          echo "$l" >/dev/tty;
        done <<<"$v";
        echo '---------------- pipe exit-------------' >/dev/tty;
        echo "$v"; ##echo to pipe buffer - necessary to keep the data flow to the next command
                }

시험:

cat file11
1
2
3
8
9

cat file11 |sed 's/3//' |teee |sed 's/1//'
---------------- pipe entry-------------
1
2

8
9
---------------- pipe exit-------------

2

8
9

귀하의 경우 모든 것을 스크립트 내부의 내용 >/dev/tty으로 바꿀 수 있습니다.>logfile

관련 정보