프로그램을 stdin에 다시 연결

프로그램을 stdin에 다시 연결

stdin문자열을 수집한 다음 완료되면 다시 연결하는 프로그램을 원한다고 가정해 보겠습니다 .

다음 트릭을 사용하면 이 작업을 수행할 수 있다는 것을 알고 있습니다.

(echo id; cat) | sh

좋은 결과. stdin사용중이라 닫히지 않습니다 cat. 그러나 출력은 지저분합니다.

더 깊이 파고보니 그것이 누락된 것을 발견했습니다 tty.

내 이해가 정확하다면 sh파이프라인에 구멍이 없는 것입니다 tty.

내가 찾은 비결은 expect.

그냥 파일에 넣으세요:

spawn sh
reattach

그런 다음 cat통제력을 회복하면 다음을 수행하십시오.

expect exp.sh

tty이것은 내가 필요한 모든 것을 할 수 있게 해주기 때문에 좋습니다 : ssh, tmux등등...

내가 왜 그런지 이해하지 못하는 유일한 것은 내가 입력한 모든 내용을 터미널에서 다시 볼 수 있다는 것입니다.

예:

(echo whoami; cat) | sh
moon
expect exp.sh
spawn sh
sh-3.2$ whoami
whoami
moon

whoami로그인하기 전에 출력의 마지막 줄을 기록해 두십시오 .

누군가 나에게 이유를 설명해 줄 수 있습니까? 그것은 직접적으로 연결되어 있기 때문에 분명히 stdoutfrom의 속성 이 아닙니다 . 예, 어리석더라도 다음을 시도했습니다. 그런 다음 아무 일도 일어나지 않았습니다.catsh(echo id; cat > /dev/null) | sh

그러면 키보드로 입력한 내용이 표시되지 않습니다 tty/속성?pty

답변1

{ echo 'exec <&3 3<&-; id' | sh -si; } 3<&0

대부분의 구현에서 작동하는 것 같습니다 sh. 우리는 대화형 쉘에 요청하고 -i(그렇지 않으면 일부 쉘은 터미널 장치가 아니기 때문에 stdin을 비활성화합니다) 쉘의 stdin을 파이프로 시작한 다음 이전에 exec <&3설명자에 .stdin으로 저장한 원본(외부) 파일로 변경하도록 지시합니다. 삼 3<&0.

우리는 이것을한다앞으로실행 중이지만 id여전히 동일한 명령을 사용 중입니다.철사, 표준 입력 id도 복원됩니다. 표준 입력을 읽지 않기 때문에 중요하지 않지만 id편집기나 셸과 같은 대화형 명령이 됩니다.

당신이 입력한 내용을 내가 본 이유는 무엇입니까 (echo id | cat) | sh? 귀하의 구현은 sh매우 오래된 버전이며 bash대화형 모드에서 실행 중인 것 같습니다. -i사용한 것처럼 프롬프트가 표시되는 것을 볼 수 있습니다 .

그런 다음 자체 라인 편집기를 구현하지만 tty 장치의 자체 라인 편집기를 비활성화할 수 있는 방법이 없습니다(표준 입력이 tty 장치가 아닌 파이프이기 때문에). 따라서 tty 장치를 통해 입력한 내용에 대한 에코를 얻게 됩니다. 줄 규칙이 표시되고 Enter를 누르자마자 cat파이프에서 즉시 작성된 후행 개행 문자를 포함하여 줄 버퍼의 모든 내용이 즉시 표시되고 bash자체 줄 편집기의 일부로 bash출력됩니다 .echo

당신이 그렇게한다면 나는 의심합니다 :

stty -icanon -echo; (echo id; cat) | sh; stty sane

bash더 나은 동작을 얻을 수 있으며, 입력한 모든 문자를 직접 수신하므로 readline 줄 편집 기능을 사용할 수도 있습니다 .

사용자가 대화형 셸을 사용하기 전에 명령을 자동으로 실행하기 위한 추가 옵션은 다음을 참조하세요.

관련 정보