我想在执行 curl 命令时安全地读取用户的密码。我做了一个基本的概念证明,它大部分都有效,但 echo 命令的输出与“密码”提示符在同一行,我正在尝试找到一种方法将其放在新行上。当我运行命令时,会打印“密码:”提示符,我输入“test”,然后 echo 命令返回并在同一行上填写“test”。我如何让它在新行上打印 echo 命令?
我正在使用以下输出执行此操作
$ echo "this is a $(read -e -s \?"Password: ")"
Password: this is a test
我想要的是一种执行上述 echo 命令的方法,但当我输入“test”作为密码时会得到以下输出
$ echo "this is a $(read -e -s \?"Password: ")"
Password:
this is a test
我尝试过的一种方法是读取密码后回显换行符,但那没有用。您可以在第二个中看到 echo 命令在 echo 命令之后打印。这几乎就像第一个 echo 启动,等待子进程返回某些内容,然后完成,然后第二个 echo 运行。我不确定如何确定此顺序,以及是否有办法强制子进程中的 echo 首先运行。
$ echo "this is a $(read -e -s \?"Password: " && echo -e '\n')"
Password: this is a test
$ echo "this is a $(read -e -s \?"Password: " && echo 'hello world')"
Password: this is a test
hello world
我在 macOS Ventura 13.1 上使用 zsh 5.8.1 执行此操作。
答案1
看来您只是把换行符放在了\n
错误的位置。使用以下命令您应该可以获得所需的输出:
$ echo -e "\nthis is a $(read -e -s \?"Password: ")"
我认为正在发生的情况是:
- 回声的论点包括命令替换,因此 shell 需要先跨越一个子 shell,来计算完整的参数,即
read
先执行命令,打印“密码:” - 由于您告诉
read
不要将-s
用户输入回显()到终端,因此“光标”仍停留在提示的末尾,即使您在末尾read
按下。Enter
- 现在 echo 命令已准备好执行,接下来会发生以下事情。
- 因此,您需要以换行符开头,以进入新行,然后打印所需的字符串。最后会自动添加换行符,因为这是
echo
的默认行为。
只是作为一个评论,echo -e
是不可移植的(参见例如https://unix.stackexchange.com/q/88307/33390),因此您应该考虑以下选项之一:
使用 shell 扩展
$'\n'
来获取换行符:$ echo $'\n'"this is a $(read -e -s \?"Password: ")"
完全省略
echo
并使用printf
;请注意,现在还需要一个尾随的\n
:$ printf "\nthis is a $(read -e -s \?"Password: ")\n"