docker / for-linux

Docker Engine for Linux
https://docs.docker.com/engine/installation/
754 stars 85 forks source link

Docker screws up STDIN/STDOUT #172

Open OnkelTem opened 6 years ago

OnkelTem commented 6 years ago

Expected behavior

docker run/exec should react on opened STDIN/STDOUT and pass their states to the command, simply connecting things to be connected.

Actual behavior

Instead it just ignores any streams and makes software relying on streams detection e.g. via stat() unusable.

Steps to reproduce the behavior

In a native Linux shell:

$ bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;'
# returns t0+ t1+

$ echo | bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;'
# returns t0- t1+

$ bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' | cat
# returns t0+ t1-

Now in docker container

$ docker run debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;'
# returns t0- t1- -- ERROR: inverted comparing to a normal shell usage

$ echo | docker run debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;'
# returns t0- t1- -- ERROR: doesn't react on STDIN

$ docker run debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' | cat
# returns t0- t1- -- ERROR: doesn't react on STDOUT

# now with -i
$ echo | docker run -i debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' | cat
# returns t0- t1- -- ERROR: doesn't react on STDIN

# now with -t
$ docker run -t debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' 
# returns t0+ t1+ -- so it's inverted them, ok

$ echo | docker run -t debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' 
# returns t0+ t1+ -- ERROR: no reaction

$ docker run -t debian:stretch bash -c '[[ -t 0 ]] && echo t0+ || echo t0-; [[ -t 1 ]] && echo t1+ || echo t1-;' | cat
# returns t0+ t1+ -- ERROR: no reaction

Output of docker version:

Docker version 17.09.0-ce, build afdb6d4

Output of docker info:

Containers: 35
 Running: 3
 Paused: 0
 Stopped: 32
Images: 1468
Server Version: 17.09.0-ce
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 1076
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
runc version: 3f2f8b84a77f73d38244dd690525642a72156c64
init version: 949e6fa
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.10.0-40-generic
Operating System: Ubuntu 17.04
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.56GiB
Name: nuc
ID: ##########
Docker Root Dir: /var/lib/docker
N:XWN7:7LE6:NKZ6:NUZO:PYBJ:6TCS:I4FI
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: #############
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support

Additional environment details (AWS, VirtualBox, physical, etc.)

Linux Kubuntu 17.04

cpuguy83 commented 6 years ago

I don't think stdin or stdout would ever be a TTY unless -t is set, and stdin is always opened if TTY is set.

Remember that this is configuring the stdio of the process in the container which is asynchronous from the stdio of your terminal.