볼륨을 공유하는 두 개의 컨테이너 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의 새로운 셸 프로세스에서 읽혀집니다.
세 번의 시도와 다른 결과에 관해:
bash -s <> /foo
: 이 명령은 표준 입력에서 읽고 표준 출력에 쓰는 새로운 쉘 프로세스를 실행합니다. 이<>
구문은 읽기 및 쓰기를 위해 명명된 파이프를 열도록 쉘에 지시합니다. 머신 X에서 실행 하면echo "ls -l" > /foo
명명된 파이프에 "ls -l" 문자열을 기록한 다음 머신 Y의 새 셸 프로세스에서 이를 읽습니다. 명령은 Y에서 실행되지만 Y의 터미널에 인쇄된 출력은 명명된 파이프에 기록됩니다.bash -s < /foo > /foo
: 이 명령은 명명된 파이프에서 데이터를 읽고 쓰는 새로운 셸 프로세스를 실행합니다. X 머신에서 실행 하면echo "ls -l" > /foo
명명된 파이프에 "ls -l" 문자열을 기록한 다음 Y 머신의 새 셸 프로세스에서 이를 읽습니다. 그러나 셸 프로세스는 동일한 명명된 파이프에도 쓰기 때문에 교착 상태가 발생하고 아무 일도 일어나지 않습니다.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의 도움으로 저는 제 요구 사항을 충족하는 다음과 같은 솔루션을 생각해냈습니다.
- 공유 볼륨에서 다음을 생성합니다.삼명명 된 파이프
stdin
및stdout
stderr
- 머신 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" < foo
X의 내용을 Y로 이동할 수도 있습니다 . foo
파이프 입력도 비슷하게 처리됩니다.