用户使用 zshbuiltin read 命令输入密码后,如何打印换行符

用户使用 zshbuiltin read 命令输入密码后,如何打印换行符

我想在执行 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"
    

相关内容