努力让docker应用程序将输出输出到文件并读取输入。在bash中运行相同的命令可以正常工作。
该命令是我创建的CLI,名为envwarden(包裹在Bitwarden CLI上的简单bash脚本)。
最容易显示示例:
在本地运行(不在docker内部),它按预期运行:
$ ./envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /home/user ... prompting for credentials
? Email address: my@email.addr
? Master password: [hidden]
提示工作正常。我可以输入我的电子邮件(显示),密码(隐藏),然后输出进入/tmp/secrets.txt
就好了。
使用docker,事情的表现会有所不同。
使用docker run -ti
(或仅docker run -t
),根本没有提示输入电子邮件或密码...
$ docker run --rm -ti envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
# ... no output ...
使用docker run -i
,会显示提示,但是会重复输入所有内容,并同时显示密码! :-/
$ docker run --rm -i envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: my@email.address
? Email address: my@email.address
? Master password: [input is hidden] my password
? Master password: [hidden]
docker run
,不带-t
或-i
,它显示提示,但无法获取输入
$ docker run --rm envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: unable to login or sync with bitwarden.
这里是Dockerfile和docker-entrypoint.sh
如何让docker匹配与本地运行相同的行为?即提示输入密码而不显示密码,然后将输出重定向到stdout。
答案 0 :(得分:1)
您观察到的行为归因于docker run
处理标准流的方式。
尤其是,这与moby/moby#725和PR moby/moby#741有关:
如果您没有向-i
传递-t
或docker run
标志:您的终端未连接到主程序的标准输入,则其行为就好像您有输入空字符串作为凭据。
如果仅将-i
标志传递给docker run
,则您的终端将附加到程序的stdin,但未分配伪TTY,这意味着您获得的用户界面不太友好CLI交互(在密码键入过程中没有隐藏功能,并且可能会重复输出行)。
如果将-it
标志传递给docker run
:分配了一个伪TTY,因此密码提示应该起作用(隐藏您键入的内容),但同时< strong> stdout和stderr流是混合的,因此,当您附加>/tmp/secrets.txt
重定向时,由于所有内容都已发送到/tmp/secrets.txt
文件中,因此您实际上看不到提示!
总而言之,要实现您想要的功能,我想您应该坚持使用-it
选项,而应在容器内部(而不是外部)使用bash重定向,并且还依赖于某些bind-mount选项
因此有以下概念证明:
export out="/tmp/secrets.txt" # absolute path to the output file in the host
docker run --rm -it -v "$out:$out" envwarden/envwarden \
/bin/bash -c "envwarden --dotenv >$out"
cat "$out"
(这应该可以正常工作,但是我没有在您的特定实例上尝试过,因此欢迎发表评论。)