그래서 나는 지금 몇 시간 동안 이것으로 만지작거리고 있습니다. 다음과 같은 질문이 있습니다.
stdout
via 에 작성된 명령(node.js 스크립트)을 실행하고 있습니다 process.stdout.write
. 대화형이므로 어느 시점에는 종료됩니다.
종료 결과가 필요하므로 하위 쉘을 생성하지만 상위 쉘에서도 활성화되어야 하므로 다음과 같이 출력을 상위 쉘로 리디렉션합니다.
exec 4>&1; res=$(exec 3>&1 1>&4; node test.js)
이 주문의 아이디어는 무엇입니까?
1>&4
node test.js의 출력이 기본(상위) 셸로 전송되는지 확인하세요. 프로세스 결과를 서브셸에 기록 3>&1
하여 $res
.
예(의사 코드):
//node.js script:
process.stdout.write('write to parent shell because 1>&4')
writeToPipe('/dev/fd/3', 'write the RESULT to subshell so that we can have it in the $res variable')
질문이 있으신가요?
문제는 (아마도 내 쉘/유닉스 측의 오해 때문일 것입니다) 단순히 쓰고 싶지 않다는 것입니다. 왜냐하면 /dev/fd/3
다른 사람도 쓰고 있다면 어떨까요? 단순히 켜서 사용하는 것은 /dev/fd/3
좋은 구현이 아니라고 생각합니다 . fd/3
누군가 내 프로세스를 여러 개 호출하여 충돌하면 어떻게 되나요?
내가 어떻게 해결하려고 노력하는지
나는 다음과 같이 할 수 있다고 생각합니다.
tmppipe=$(mktemp -u)
mkfifo "$tmppipe"
매번 고유한 명명된 파이프를 생성하고 충돌을 피할 수 있기 때문입니다.
문제는 내가 그것을 작동시킬 수 없다는 것입니다. "사소한 대안"으로 처음에는 다음을 시도했습니다.
exec 4>&1; res=$(exec "$tmppipe">&1 1>&4; node test.js)
그러나 이것은 작동하지 않습니다. 나는 명명된 파이프에 대해 이 구문이 작동하지 않는다고 생각하지만 터미널에서 권한 문제가 있다고 알려주고 종료됩니다.
답변1
test.js
나는 당신이 사용자와 어떤 형태로든 대화형 대화를 나누기 위해 파이프와 파일 설명자를 사용하여 작업할 계획이라고 생각합니다 .
예를 들어, 표준 출력을 사용하여 test.js
사용자에게 질문을 하면 사용자는 표준 입력에 응답할 수 있습니다. 프로그램은 어떻게든 표준 출력에 최종 출력을 제공해야 하기 때문에 test.js
명령 대체에 데이터를 제공하려면 대체의 표준 출력에 연결될 파일 설명자 3을 구성하고 최종 출력을 여기에 작성해야 합니다. 설명자 중간 test.js
.
이건 좀 당황스럽네요.
도구의 최종 출력(예: 대화형 질문, 진단 오류 메시지, 진행률 표시줄 등)의 일부가 아닌 대화형 사용자 대화를 처리하는 데 일반적으로 허용되는 방법은 표준 오류 스트림으로 출력하는 것입니다. 기본적으로 이로 인해 이러한 메시지가 터미널로 직접 전송되므로(파일 설명자 2에 대한 리디렉션이 설정되어 있지 않다고 가정) 명령 대체를 통해 캡처되거나 파이프 등을 통해 전송된 결과가 아닙니다.
이것이 쉘과 기타 여러 도구가 작동하는 방식입니다. 쉘은 표준 오류를 프롬프트할 것입니다. 쉘은 표준 오류에 명령문 출력(일종의 메뉴)을 bash
쓰고 , 명령은 select
표준 오류 스트림에 read -p 'text'
인쇄되어 text
사용자에게 프롬프트를 표시하며, (분명히) 표준 오류에 오류 메시지를 인쇄합니다.
따라서 코드를 다음과 같이 단순화할 수 있습니다.
res=$(node test.js)
여기서는 test.js
표준 오류 스트림에서 사용자와 상호 작용하고, 표준 입력 스트림에서 사용자 입력을 읽고, 마지막으로 표준 출력 스트림에서 일부 출력을 생성합니다. 이 출력은 res
셸의 변수에 저장되어야 합니다.
쉘에서의 간단한 데모 bash
:
res=$( read -p 'enter something: '; printf 'You entered "%s"\n' "$REPLY" )
printf '"$res" is now "%s"\n' "$res"
res
의지의 최종 가치아니요enter something:
유틸리티가 표준 오류 스트림에 쓰는 문자열을 포함합니다 read
.