bash 쉘을 명명된 파이프에 연결하는 방법은 무엇입니까?

bash 쉘을 명명된 파이프에 연결하는 방법은 무엇입니까?

볼륨을 공유하는 두 개의 컨테이너 X와 Y(실제로는 동일한 Kubernetes 포드에 있는 두 개의 컨테이너)가 있다고 가정해 보겠습니다. 이 볼륨에는 /foo컨테이너 Y의 bash 프로세스에 연결하려는 명명된 파이프가 있습니다 . 컨테이너 X가 컨테이너 Y에 데이터를 보낼 때 예를 들어 다음과 같은 방식으로 작동하기를 원합니다 ssh. 명령은 원격 bash 셸, 파이프 등에서 읽어야 하며 모두 투명하게 처리됩니다.

머신 Y에서 다음을 시도했습니다.

  • bash -s <> /foo: XI 머신에서 실행하는 경우 echo “ls -l” > /foo; cat /foo명령은 Y에서 실행되지만 출력은 명명된 파이프 대신 Y의 터미널로 이동합니다.

  • bash -s < /foo > /foo머신 XI에서 실행하면 echo “ls -l” > /foo; cat /foo아무 일도 일어나지 않습니다.

  • bash -s < /foo | cat - > foo: XI 머신에서 실행하면 echo “ls -l” > /foo; cat /foo명령이 Y에서 실행되고 출력이 X의 터미널에 나타난 다음 Y에서 더 ​​이상 명령이 실행되지 않고 X가 정지됩니다.

내가 찾고 있는 것은 X의 현재 셸을 명명된 파이프에 연결하고 이를 X의 새 셸에 연결하는 방법일 수 있습니다. 다시 한 번 말하지만, 이전처럼 작동하고 싶습니다 ssh. 단일 비대화형 명령(또는 스크립트) 및/또는 파이프 데이터를 연결하고 보낼 수 있으며 어떻게든 예상한 대로 작동합니다. 나는 그것을 구현하기에 적합한 쉘 fu를 찾지 못했습니다.

또한 위의 세 가지 옵션이 왜 다른 결과를 생성하는지 이해하지 못합니다.

답변1

bash 셸을 명명된 파이프에 연결하려면 이 exec명령을 사용하여 현재 셸 프로세스를 명명된 파이프에 연결된 새 프로세스로 바꿉니다. 예를 들어 머신 Y에서 이 작업을 수행하는 방법은 다음과 같습니다.

cat /foo | bash

이는 현재 쉘 프로세스를 명명된 파이프를 읽고 쓰는 새로운 쉘 프로세스로 대체합니다 /foo. 이제 머신 X에서 전송된 모든 명령이나 데이터는 /foo머신 Y의 새로운 셸 프로세스에서 읽혀집니다.

세 번의 시도와 다른 결과에 관해:

  1. bash -s <> /foo: 이 명령은 표준 입력에서 읽고 표준 출력에 쓰는 새로운 쉘 프로세스를 실행합니다. 이 <>구문은 읽기 및 쓰기를 위해 명명된 파이프를 열도록 쉘에 지시합니다. 머신 X에서 실행 하면 echo "ls -l" > /foo명명된 파이프에 "ls -l" 문자열을 기록한 다음 머신 Y의 새 셸 프로세스에서 이를 읽습니다. 명령은 Y에서 실행되지만 Y의 터미널에 인쇄된 출력은 명명된 파이프에 기록됩니다.

  2. bash -s < /foo > /foo: 이 명령은 명명된 파이프에서 데이터를 읽고 쓰는 새로운 셸 프로세스를 실행합니다. X 머신에서 실행 하면 echo "ls -l" > /foo명명된 파이프에 "ls -l" 문자열을 기록한 다음 Y 머신의 새 셸 프로세스에서 이를 읽습니다. 그러나 셸 프로세스는 동일한 명명된 파이프에도 쓰기 때문에 교착 상태가 발생하고 아무 일도 일어나지 않습니다.

  3. bash -s < /foo | cat - > foo: 이 명령은 명명된 파이프에서 데이터를 읽고 해당 출력을 일반 파일에 쓰는 cat 명령으로 파이프하는 새로운 셸 프로세스를 실행합니다 foo. 머신 X에서 실행 하면 echo "ls -l" > /foo명명된 파이프에 "ls -l" 문자열을 기록한 다음 머신 Y의 새 셸 프로세스에서 이를 읽습니다. 명령은 Y에서 실행되고 출력은 X에서 실행되는 cat 프로세스에 기록되므로 X의 터미널에 나타납니다. 그러나 cat 프로세스는 명명된 파이프에 아무것도 다시 쓰지 않으므로 Y 시스템의 새 셸 프로세스가 중단됩니다.

답변2

좋습니다. Telometto, Kamil 및 Greg A. Woods의 도움으로 저는 제 요구 사항을 충족하는 다음과 같은 솔루션을 생각해냈습니다.

  • 공유 볼륨에서 다음을 생성합니다.명명 된 파이프 stdinstdoutstderr
  • 머신 Y에서 실행while true; do bash -s < stdin 2> stderr > stdout ; done
  • 원격 명령 실행을 돕기 위해 머신 XI에 도우미 스크립트를 만들었습니다.
#!/bin/bash

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM

(
  echo "$@"
  if read -t 0 ; then
    cat - 2> /dev/null
  fi
) | cat > stdin

cat stdout &
cat stderr > /dev/stderr &

wait

이를 사용하려면 ./run "ls -l"X에서 시작하여 Y에서 명령을 실행하면 됩니다. 또한 X에서 시작하여 Y에서 명령을 실행하여 ./run "cat > bar" < fooX의 내용을 Y로 이동할 수도 있습니다 . foo파이프 입력도 비슷하게 처리됩니다.

관련 정보