현재 명령이 실행되기 전에 실행된 명령을 설명하는 문자열에 액세스하는 방법을 알고 싶습니다.
예를 들어, 다음을 실행하면:
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_aliases
Tee와 같은 도구를 제공합니다.
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