Trả lời muộn, nhưng có thể giúp được ai đó
docker run/exec -i
sẽ kết nối STDIN của lệnh bên trong container với STDIN của docker run/exec
chính nó.
Vì thế
docker run -i alpine cat
cung cấp cho bạn một dòng trống chờ đầu vào. Nhập "xin chào" bạn sẽ nhận được tiếng vang "xin chào". Container sẽ không thoát cho đến khi bạn gửi CTRL + D vì quá trình chính cat
đang chờ đầu vào từ luồng vô hạn là đầu vào cuối của docker run
.
- Mặt khác
echo "hello" | docker -i run alpine cat
sẽ in "xin chào" và thoát ngay lập tức vì cat
thông báo rằng luồng đầu vào đã kết thúc và tự chấm dứt.
Nếu bạn thử docker ps
sau khi thoát khỏi một trong những điều trên, bạn sẽ không tìm thấy bất kỳ container nào đang chạy. Trong cả hai trường hợp, cat
chính nó đã chấm dứt, do đó docker đã chấm dứt container.
Bây giờ cho "-t", điều này cho biết quy trình chính bên trong docker rằng đầu vào của nó là một thiết bị đầu cuối.
Vì thế
docker run -t alpine cat
sẽ cung cấp cho bạn một dòng trống, nhưng nếu bạn cố gắng gõ "xin chào", bạn sẽ không nhận được bất kỳ tiếng vang nào. Điều này là do trong khi cat
được kết nối với đầu vào đầu cuối, đầu vào này không được kết nối với đầu vào của bạn. "Xin chào" mà bạn đã nhập không đạt đến đầu vào cat
. cat
đang chờ đầu vào không bao giờ đến
echo "hello" | docker run -t alpine cat
cũng sẽ cung cấp cho bạn một dòng trống và sẽ không thoát khỏi vùng chứa trên CTRL-D nhưng bạn sẽ không nhận được tiếng vang "xin chào" vì bạn đã không vượt qua -i
Nếu bạn gửi CTRL + C, bạn sẽ lấy lại được vỏ của mình, nhưng nếu bạn thử docker ps
ngay bây giờ, bạn sẽ thấy cat
container vẫn đang chạy. Điều này là do cat
vẫn đang chờ đợi một luồng đầu vào không bao giờ bị đóng. Tôi đã không tìm thấy bất kỳ sử dụng hữu ích cho -t
một mình mà không được kết hợp với -i
.
Bây giờ, cho -it
cùng nhau. Điều này cho mèo biết rằng đầu vào của nó là một thiết bị đầu cuối và đồng thời kết nối thiết bị đầu cuối này với đầu vào docker run
là thiết bị đầu cuối. docker run/exec
sẽ đảm bảo rằng đầu vào của chính nó trong thực tế là một tty trước khi chuyển nó đến cat
. Đây là lý do tại sao bạn sẽ nhận được input device is not a TTY
nếu bạn cố gắng echo "hello" | docker run -it alpine cat
vì trong trường hợp này, đầu vào của docker run
chính nó là đường ống từ tiếng vang trước đó và không phải là thiết bị đầu cuối nơi docker run
được thực thi
Cuối cùng, tại sao bạn cần phải vượt qua -t
nếu -i
sẽ thực hiện thủ thuật kết nối đầu vào của bạn với cat
đầu vào của? Điều này là do các lệnh xử lý đầu vào khác nhau nếu đó là một thiết bị đầu cuối. Điều này cũng được minh họa tốt nhất bằng ví dụ
docker run -e MYSQL_ROOT_PASSWORD=123 -i mariadb mysql -uroot -p
sẽ cung cấp cho bạn một dấu nhắc mật khẩu. Nếu bạn nhập mật khẩu, các ký tự được in rõ ràng.
docker run -i alpine sh
sẽ cung cấp cho bạn một dòng trống. Nếu bạn gõ một lệnh như ls
bạn nhận được một đầu ra, nhưng bạn sẽ không nhận được một dấu nhắc hoặc đầu ra màu.
Trong hai trường hợp cuối cùng, bạn có hành vi này vì mysql
cũng như shell
không coi đầu vào là tty và do đó không sử dụng hành vi cụ thể tty như che dấu đầu vào hoặc tô màu đầu ra.