일반적인 문제
파이프 체인의 중간에 있더라도 사용자와 상호 작용하는 스크립트를 작성하고 싶습니다.
구체적인 예
구체적으로, 그것은 취 file
하거나 stdin
(행 번호), 디스플레이 라인을 입력하도록 요청하는 선택 또는 광고 번호, 다음에 대응하는 라인을 인쇄 stdout
. 이 스크립트를 호출 해 봅시다 selector
. 그런 다음 기본적으로 할 수 있기를 원합니다
grep abc foo | selector > myfile.tmp
foo
포함하는 경우
blabcbla
foo abc bar
quux
xyzzy abc
그런 다음 옵션이 selector
있는 터미널이 아닌 터미널에 표시됩니다 myfile.tmp
!
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
그 후 내가 입력
2-3
그리고 결국
foo abc bar
xyzzy abc
의 내용으로 myfile.tmp
.
선택기 스크립트가 설치되어 실행 중이며 기본적으로 입력 및 출력을 리디렉션하지 않으면 완벽하게 작동합니다. 그래서
selector foo
내가 원하는 것처럼 행동합니다. 그러나 위 예제와 같이 함께 파이핑 할 때 selector
제시된 옵션을 인쇄 myfile.tmp
하고 grepped 입력에서 선택 항목을 읽으려고합니다.
내 접근 방식
-u
에서 read
와 같이 의 플래그 를 사용하려고 했습니다.
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
그러나 이것은 내가 원하는 바를 수행하지 않습니다.
Q : 실제 사용자 상호 작용은 어떻게 받습니까?
cmd | { some processing; read var </dev/tty; } | cmd
alias selector='{ TMPFILE=$(mktemp); cat > $TMPFILE; nl -s") " $TMPFILE | column -c $(tput cols); read -e -p"Select options: " < /dev/tty; rangeselect -v range="$REPLY" $TMPFILE; rm $TMPFILE; }'
꽤 잘 작동합니다. 그러나 grep b foo | selector | wc -l
여기서 넘어집니다. 그것을 고치는 방법에 대한 아이디어가 있습니까? 그건 그렇고, rangeselect
내가 사용한 것은 pastebin.com/VAxTSSHs 에서 찾을 수 있습니다 . 주어진 행 번호 범위에 해당하는 파일의 행을 인쇄하는 간단한 AWK 스크립트입니다. (범위는 "3-10, 12,14,16-20"와 같은 것이 될 수 있습니다.)
alias
오히려 selector() { all of that stuff...; }
기능에 들어 가지 마십시오 . alias
es는 단순 명령의 이름을 바꾸는 반면 함수는 복합 명령 을 단일 단순 명령으로 묶습니다 .