📚
docker で "the input device is not a TTY" のエラーが出ないようにする
docker で "the input device is not a TTY" のエラーが出ないようにする
概略
docker run するときに、cron、CI、nohup などで実行した場合など、標準入力デバイスが TTY ではないときに docker run -it を指定して実行すると、"the input device is not a TTY" のエラーになる。
シェルから実行する場合、Control+C で実行を止めることができるように -it を指定したいが、バックグラウンド処理としても実行したい場合、困る。標準入力デバイスが TTYか判定して -it を指定するかしないかを切り替える。
エラーの例
NG な場合の例
$ echo "" | docker run -it hello-world
the input device is not a TTY
$ nohup docker run -it hello-world
$ cat nohup.out
the input device is not a TTY
OK な場合の例
$ docker run -it hello-world
Hello from Docker!
... 以下略 ...
判定
以下のようなシェルスクリプトを組む。
#!/bin/bash
SELF=$$
ls /proc/$SELF/fd/0 -l | grep /dev/pts > /dev/null
if [ $? -eq 0 ]; then
echo "input device is TTY device"
OPTION=-it
else
echo "input device is non TTY"
OPTION=
fi
docker run $OPTION hello-world
$$
はシェルスクリプト自身の PID を表す。
/proc/PID/fd/0
で指定した PID のプロセスの標準入力の実体を確認できる。
ターミナルから実行された場合、実体が /dev/pts/0
などになっている。
ターミナル以外から実行された場合やパイプで実行された場合などは /dev/pts
を含まない。
grep /dev/pts
でマッチするかどうかで判定することで、docker run -it
を実行したとき the input device is not a TTY
が発生する条件であるか事前に判定できる。
Discussion