2016-07-29 1 views
0

스크립트와 데이터를 stdin으로 쉘 및 해당 하위 프로세스로 파이프하려고합니다. 기본적으로 쉘을 시작하여 "exec wc -c;\n<data>"과 같은 문자열을 stdin을 통해 쉘에 보냅니다.bash/sh/busybox가 stdin을 하위 프로세스로 전달합니다.

하위 프로세스를 시작하고 해당 하위 프로세스로 데이터를 전달하려고합니다. 사용 execwc -c은 내 셸을 바꾸고 stdin을 통해 보낸 바이트 수를 계산합니다.

예 :

echo -ne 'exec wc -c;\nabc' | dash 
echo -ne 'exec wc -c;\nabc' | bash 
echo -ne 'exec wc -c;\nabc' | bash --posix 
echo -ne 'exec wc -c;\nabc' | busybox sh 

는하지만 대시 또는 busybox sh와, bash는 일관되게 작동하는 것 같다. 둘 다 간헐적으로 실패하는 것 같습니다. stdin 위로 <data>을 보내기 전에 100ms 동안 잠자기하면 작동합니다. 그러나 수면은 신뢰할만한 문제가 아닙니다.

사실 나는 사소한 양의 데이터를 보내고 있으므로 인코딩하거나 메모리에 저장하고 싶지는 않습니다. 어떤 아이디어?

참고 :이 문제를 해결할 수있는 유용한 사례가 많이 있습니다. 그러나 이것이 왜 일관되게 작동하지 않는지 알아 보려고합니다. 그리고/또는 어떤 쉘 마법 나는 플랫폼 :)를 통해 바람직하게, 안정적으로 작동하도록 할 수

업데이트 : 내가 sh을 실행하고/표준 출력/표준 오류, 내가 좋아하는 것 표준 입력에 노출 원격 시스템을 명확하게 그러한 설정이 무엇이든 할 수 있음을 증명합니다. "exec cat - > /myfile;\n<data>"을 보내면 /myfile에 스트리밍하여 <data>이 포함될 수 있다고 상상할 수 있습니다. 다시 <data>이 큰 것으로 상상해보십시오.

기본적으로 sh에 대해 stdin을 사용하여 시스템을 제어 할 수 있음을 증명하고자합니다. sh 대신에 매우 단순한 것이 있으며 정적 바이너리로 여러 플랫폼에서 즉시 사용할 수 있습니다.

나는 이것이 완전히 미쳤을지도 모른다는 것을 인정하고 나는 SSH 같은 프로토콜을 채택해야한다고 인정할 것이다. 그렇지만 그것을 구현해야 할 것이다.

+3

왜'echo -n 'abc'| wc -c' 또는 더 일반적으로'generatedata | process'가 아닌가? 쉘을 시작한 후'exec'를하는 이점은 무엇이라고 보십니까? – John1024

+3

BTW, 당신이 이식성에 관심이 있다면 * 어떤 * 플래그와 함께'echo'보다는'printf'를 사용하는 습관을 갖기를 원할 것입니다; -n은 POSIX에서 명시 적으로 정의되지 않은 행동입니다. 인수 목록에'-e'가 전달되었을 때 출력시'-e'를 출력하는 것 이외의 것은 j가 아닙니다. 정의되지 않은 공간에 있지만 표준과 반대로 행동해야합니다. 특히 APPLICATION USAGE 섹션을 포함하여 http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html을 참조하십시오. –

답변

1

이것은 bash에서는 작동하지만 나에게는 대시 또는 busybox sh에서는 전혀 적용되지 않는 것으로 보입니다. 나는 그것이 전혀 작동한다는 것에 놀랍니다. 셸이 첫 번째 줄의 명령과 그 이후의 데이터를 모두 포함하여 처리하기 전에 입력에서 큰 부분을 읽을 것으로 기대합니다. 그것은 exec'ed 명령의 stdin에 아무것도 남기지 않을 것입니다.

실제로는 bash가 개행을 본 다음 즉시 exec를 수행 할 때까지 한 번에 1 바이트 씩 읽는 것으로 보이므로 모든 것이 좋습니다.

대시와 busybox sh는 내가 예상했던대로 정확히 전체 입력을 읽습니다.

당신은

echo -ne "exec wc -c <<'END'\nabc" | sh 

대신 할 수 있습니까? 입력에 나타날지 걱정되는 경우 END를 END_adjfioe38999f3jf_END로 바꾸시겠습니까?

업데이트 : 생각해 보니 "메모리에 버퍼하지 않음"기준이 충족되지 않습니다. 오류 ... 오케이, 어렵습니다.그런 다음, 4K 이내에 것 "작업"같은 뭔가 끔찍한 맞는을 실행하는 명령을 보장 할 수있는 경우 :

echo -ne "exec wc -c\nabc" | perl -e 'sysread(STDIN, $buf, 4096); $buf =~ s/([^\n]*)\n//; open(my $pipe, "|-", $1); syswrite($pipe, $buf); open(STDOUT, ">&", $pipe); exec("cat")' 

을하지만 거의 당신이 찾고 있던 휴대용 쉘 기반 솔루션 없습니다. (그것은 4k 덩어리의 입력을 읽고 그것으로부터 명령을 포착하고, 파이프로 연결된 명령을 실행하는 껍질을 떼어 내고 포크를 만들고, 초기 덩어리의 나머지 부분을 파이프로 보내고, 자신의 stdout을 파이프로 옮긴 다음, exec가 cat을 한 번에 한 조각 씩 파이프로 복사하여 표준 입력으로 받아 들일 것입니다. 쉘을 사용하는 단순한 구문을 사용하면 그 일이 끝나기를 원하는 것입니다.

+0

그는 재미있는 질문입니다. @sfink 유스 케이스는 shell이 ​​실행하는'sh'에'cat -'을 보내서 taskcluster 대화 형 쉘을 테스트하는 것입니다 ... 이상하게도, 나는 그 작업을 안정적으로 얻을 수 있다면 또한 쉘을 사용하여 파일 및 기타 미친 것들을 전송할 수 있습니다 ... 그러나 나는 포함하기가 더 쉬운 sh/busybox 대신 bash를 실행해야 할 수도 있다고 생각합니다. – jonasfj