对提示输入密码的CLI进行dockerize

对提示输入密码的CLI进行dockerize,docker,stdout,tty,Docker,Stdout,Tty,正在努力让docker应用程序同时将输出输出到文件和读取输入。在bash中运行相同的命令效果良好 该命令是我创建的一个CLI,名为(一个简单的bash脚本,包装在该命令周围) 最容易显示的示例: 局部 在本地(而不是docker内部)运行时,它可以按预期工作: $ ./envwarden --dotenv >/tmp/secrets.txt .envwarden file not found in /home/user ... prompting for credentials ? Ema

正在努力让docker应用程序同时将输出输出到文件和读取输入。在bash中运行相同的命令效果良好

该命令是我创建的一个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.
进一步详情 这是和

问题:
如何使docker与本地运行的行为相匹配?i、 e.在不显示密码的情况下提示输入密码,并将输出重定向到stdout。

您观察到的行为是由于docker run处理标准流的方式造成的

特别是,这与以下方面有关:

  • 如果您将no
    -i
    -t
    标志传递给
    docker run
    :您的终端未连接到主程序的标准输入,因此其行为就像您键入了空字符串作为凭据一样

  • 如果您只将
    -i
    标志传递给
    docker run
    ,则您的终端将连接到程序的stdin,但没有分配伪TTY,这意味着您获得的CLI交互不是非常友好的用户界面(密码输入期间没有隐藏功能,并且可能会重复输出行)

  • 如果您将
    -it
    标志传递给
    docker run
    :分配了一个伪TTY,因此密码提示应该可以工作(隐藏您键入的内容),但同时,stdout和stderr流是混合的,因此当您附加
    /tmp/secrets.txt
    重定向时,您实际上没有看到提示,因为所有内容都被发送到您的
    /tmp/secrets.txt
    文件

总之,为了实现您想要的,我想您应该坚持使用
-it
选项,而是在容器内部(而不是外部)使用bash重定向,并且还依赖于一些绑定装载选项

因此,有以下概念证明:

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"

(这应该可以正常工作,但我没有在您的特定实例上尝试,所以欢迎评论。)

docker entrypoint.sh中有什么内容?(对不起,忘记链接了,这都是回购协议的一部分。编辑了我的问题,也包括在内)谢谢!我仍然对您链接到的问题有点困惑,为什么docker不能将输出拆分为stdout和stderr,但我了解解决方法。不是很遗憾,因为它不允许您使用docker版本作为替代品,但至少它是:)@gingerlime我认为这个问题(事实上,在使用
-it
时,stderr和stdout是纠缠在一起的)不是docker特有的,因为类似的问题出现在
ssh
上,例如:。因此,您要么依赖我建议的解决方法(这确实不能很好地与bash别名组合),要么放弃
-t
选项,做您在第一时间尝试过的事情,
docker run--rm-I envwarden/envwarden envwarden--dotenv>/tmp/secrets.txt
(并失去基于TTY的密码隐藏功能)。再次感谢,埃里克。在这种情况下,密码隐藏是非常关键的。。。但我很高兴至少有一个解决办法。。。我没有想到,但一旦你提到它,它就非常有意义:)。。。我以为docker是在本地进程中运行的,所以它应该能够拆分stderr、stdout,但显然,如果它这么简单,他们早就可以这么做了。所以我显然低估了复杂性。不过,我想这确实妨碍了docker被用作打包应用程序的简单方式。