[docker] 의사 TTY를 할당하는 Docker -t 옵션에 대해 혼동

이 옵션은 정확히 무엇을합니까? 나는 TTY에 대해 많은 것을 읽었으며 여전히 혼란스러워합니다. 나는를 가지고 있지 함께 놀았 -t그냥 -i그것은 사용자 입력이없이 오류가 발생 기대할 프로그램처럼 보인다 -t. pseudo-TTY를 활성화하는 것이 중요한 이유는 무엇입니까?



답변

-t옵션은 유닉스 / 리눅스 터미널 접속을 처리하는 방법에 간다. 과거에는 터미널이 유선 연결이었고 나중에 모뎀 기반 연결이었습니다. 여기에는 실제 장치 드라이버가있었습니다 (실제 장비였습니다). 일반화 된 네트워크가 사용되면 의사 터미널 드라이버가 개발되었습니다. 이 터미널 기능 (남자 페이지를 읽고 직접 프로그램으로 작성할 필요없이 사용할 수있는 이해 사이의 분리를 생성하기 때문입니다 stty, curses).

따라서 배경으로 옵션없이 컨테이너를 실행하고 기본적으로 stdout 스트림이 있습니다 ( docker run | <cmd>작동합니다). 로 실행 -i하면 stdin 스트림이 추가됩니다 (그래서 <cmd> | docker run -i작동합니다). -t일반적으로 조합하여을 사용 -it하고 터미널 드라이버가 추가되어 프로세스와 상호 작용하는 경우 원하는 것 같습니다. 기본적으로 컨테이너 시작은 터미널 연결 세션처럼 보입니다.


답변

늦은 답변이지만 누군가를 도울 수 있습니다

docker run/exec -i컨테이너 내부의 명령의 STDIN을 docker run/exec자체 의 STDIN에 연결 합니다.

그래서

  • docker run -i alpine cat입력을 기다리는 빈 줄을 제공합니다. “hello”를 입력하면 에코 “hello”가 나타납니다. 기본 프로세스 가의 터미널 입력 인 무한 스트림의 입력을 기다리고 있으므로 CTRL+ 를 보낼 때까지 컨테이너가 종료되지 않습니다 .Dcatdocker run
  • 반면에 echo "hello" | docker run -i alpine cat“hello”를 인쇄 cat하고 입력 스트림이 종료되었다는 것을 알기 때문에 즉시 종료됩니다.

docker ps위 중 하나를 종료 한 후에 시도 하면 실행중인 컨테이너가 없습니다. 두 경우 모두 cat자체가 종료되었으므로 docker가 컨테이너를 종료했습니다.

이제 “-t”의 경우 도커 내부의 기본 프로세스에 입력이 터미널 장치임을 알립니다.

그래서

  • docker run -t alpine cat빈 줄을 줄 것입니다. 그러나 “hello”를 입력하면 에코가 나타나지 않습니다. while cat이 터미널 입력에 연결되어 있기 때문에이 입력이 입력에 연결되지 않았기 때문 입니다. 입력하신 “hello”가에 입력되지 않았습니다 cat. cat도착하지 않은 입력을 기다리고 있습니다.
  • echo "hello" | docker run -t alpine cat또한 당신에게 빈 줄을 줄 것이다에 컨테이너를 종료하지 않습니다 CTRLD하지만 당신은 통과하지 않았기 때문에 당신은 에코 “안녕하세요”를받지 않습니다-i

CTRL+ 를 보내면 C쉘이 다시 돌아 오지만 docker ps지금 시도 하면 cat컨테이너가 여전히 실행중인 것을 볼 수 있습니다 . cat닫히지 않은 입력 스트림을 계속 기다리고 있기 때문 입니다. -t와 결합하지 않고 단독으로 유용한 용도를 찾지 못했습니다 -i.

이제 -it함께. 이것은 cat에게 입력이 터미널임을 알려주고 동시에이 터미널을 입력 인 터미널에 연결합니다 docker run. docker run/exec전달하기 전에 자체 입력이 실제로 tty인지 확인합니다 cat. 이 input device is not a TTY경우 시도 자체가 echo "hello" | docker run -it alpine cat입력 docker run되는 곳 docker run이 아닌 이전 에코의 파이프 이기 때문에 시도 하면 결과를 얻을 수 있습니다.

마지막으로, 당신은 왜 전달해야 할 -t경우 -i에 입력을 연결하는 트릭을 할 것 cat‘의 입력을? 명령이 입력 인 경우 명령이 입력을 다르게 취급하기 때문입니다. 이것은 또한 예제로 가장 잘 설명됩니다.

  • docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -u root -p비밀번호 프롬프트가 표시됩니다. 암호를 입력하면 문자가 표시됩니다.
  • docker run -i alpine sh빈 줄을 줄 것입니다. ls출력 과 같은 명령을 입력하면 프롬프트 나 컬러 출력이 표시되지 않습니다.

마지막 두 경우에, 당신은 때문에이 동작을 얻을 mysql뿐만 아니라 같이 shell입력을 마스킹하거나 출력을 착색처럼 TTY 특정 동작을 사용하지 않은, 따라서 청각 장애로 입력을 처리되지 않은합니다.


답변

-t구글 검색에 따르면 이 주장은 잘 문서화되어 있지 않거나 많은 사람들이 자주 언급하고있다.

dockerBash 프롬프트 (최신 버전 1.8.1) 를 입력하여 모든 도커 클라이언트 인수 목록을 표시 할 때도 표시되지 않습니다 .

실제로 if를 입력하여이 논증에 대한 구체적인 도움을 얻으려고한다면 다음과 docker -t --help같이 모호한 답변을 얻을 수 있습니다.

제공되었지만 정의되지 않은 플래그 : -t

따라서이 논쟁에 대해 혼란스러워한다고 비난받을 수 없습니다!

Docker 온라인 문서에는 “의사 tty 할당”이라고 언급되어 있으며 종종 다음과 함께 사용됩니다 -i.

https://docs.docker.com/reference/run/

훌륭한 jwilder/nginx-proxy도커 컨테이너 의 문서 에서 다음과 같은 방식으로 사용되는 것을 보았습니다 .

docker run -d -p 80:80 --name nginx -v /tmp/nginx:/etc/nginx/conf.d -t nginx

이 경우 출력은이 docker 컨테이너 내의 ‘virtual’tty (Bash 명령 프롬프트 / 터미널)로 출력됩니다. 그런 다음 고정 표시기의 명령을 실행하여이 출력을 볼 수있는 이 컨테이너의 ID 문자의 첫 번째 커플입니다. 이 컨테이너 ID는 다음을 입력하여 찾을 수 있습니다docker logs CONTAINERCONTAINERdocker ps -a

-t다음 링크 에서이 주장을 간략하게 언급했습니다.

-t-i플래그는 의사 청각 장애를 할당하고 연결되지 않은 경우에도 개방 stdin을 유지한다. 이를 통해 bash 프롬프트가 실행되는 한 기존 VM처럼 컨테이너를 사용할 수 있습니다.

https://coreos.com/os/docs/latest/getting-started-with-docker.html

이게 도움이 되길 바란다! 왜 이것이 문서화되거나 많이 사용되지 않는지 잘 모르겠습니다. 실험적이며 향후 버전에서 문서화 된 기능으로 구현 될 수 있습니다.


답변

내가 아는 -t것은 다음과 같습니다.

docker exec -ti CONTAINER bash-컨테이너에 “로그인”할 수 있습니다. 그것은 ssh-ing 느낌입니다 (그렇지 않습니다).

그러나 문제는 데이터베이스를 복원하고 싶을 때였습니다.

일반적으로 나는 docker exec -ti mysql.5.7 mysql컨테이너에서 mysql 명령을 실행하고 대화식 터미널을 얻는다.

<dump.sqlDB를 복원 할 수 있도록 이전 명령에 추가 했습니다. 그러나 실패했습니다 cannot enable tty mode on non tty input.

-t도움을 제거 . 여전히 이유를 이해하지 못합니다.

docker exec -i mysql.5.7 mysql < dump.sql

마지막이 작동합니다. 이것이 사람들을 돕기를 바랍니다.


답변

Linux에서 명령을 실행할 때 명령을 실행하려면 터미널 (tty)이 필요합니다.

따라서 도커에 연결하거나 도커 컨테이너에서 명령을 실행하려면 도커 컨테이너 내부의 터미널을 고려한 -t 옵션을 제공해야합니다.


답변

모든 프로세스에는 세 개의 데이터 스트림이 STDIN/ STDOUT/ STDERR있습니다. 프로세스가 컨테이너에서 실행중인 경우 기본적으로 터미널은 컨테이너에서 실행중인 프로세스의 STDOUT 스트림에 연결됩니다. 따라서 docker run터미널에서 명령 을 실행하는 동안 모든 출력 스트림이 표시됩니다 . 그러나 컨테이너에서 실행중인 프로세스에 입력을 제공하려면 기본적으로 있지 않고 docker run -i명령 으로 수행되는 프로세스의 STDIN 채널에 연결해야합니다 .

-t 대화 형 / 포맷 된 입력 작업에 사용됩니다.


답변

-it컨테이너에서 대화 형 bash 쉘을 생성, 컨테이너의 표준 입력에 연결된 가상 TTY를 할당 할 수 도커 지시합니다.

--interactive, -i falseSTDIN을 부착하지 않은 상태로 열어 두십시오.

--tty, -t false 의사 TTY를 할당

https://docs.docker.com/engine/reference/commandline/run/