File-Descriptors

cryptsetup - 它如何繞過stdout/stdin重定向列印提示?

  • July 18, 2019

我剛剛注意到,無論將哪個cryptsetupFD 轉發給它,/dev/null它仍然會提示輸入密碼。例如這仍然顯示提示:

cryptsetyp luksOpen /dev/sdXY name >/dev/null 2>/dev/null

如何在無法使用標準重定向重定向到文件的終端消息中顯示?

我想在 bash 腳本中獲得這樣的功能,因為我使用 stdout 將結果返回給母腳本,但我仍然想顯示互動式提示 - 是否可以使用 bash 來做到這一點?

據推測,它直接寫入/dev/tty(無論如何,您可以獲得相同的行為)

#!/bin/bash

# set up the new file descriptor
exec 3> /dev/tty

# test
echo "Stdout"
echo "Stderr" >&2
echo "Directly to tty" >&3

或者,您可以簡單地執行以下操作:

echo "Directly to tty" >/dev/tty

$ ./foo.sh >/dev/null 2>/dev/null
Directly to tty 

read如果你這樣做,仍然有效。


exec 需要在目前 shell 的持續時間內保持重定向。

一個簡單命令的重定向:

$ echo yes       3>file

在命令執行期間持續。一旦命令(本例中為 echo)結束,shell 將刪除重定向並恢復到“目前 shell”執行環境。

A:

$ 3>file

仍然是一個“簡單命令”,其中執行的命令是“none”,重定向不會持續很長時間。

取而代之的是:

$ exec 3>file

exec 用包含重定向的新 shell 替換“目前 shell”。只要“目前外殼”存在,這就會使重定向保持活動狀態。這可以通過以下方式撤消(嗯,實際上關閉 fd 3):

$ exec 3>&-

如果您strace使用它,您可能會看到它/dev/tty直接使用。

...
open("/dev/tty", O_RDWR)                = 6
ioctl(6, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(6, "Enter passphrase for .......: ", 30) = 30
ioctl(6, SNDCTL_TMR_CONTINUE or TCSETSF, {B38400 opost isig icanon -echo ...}) = 0
...

在原始碼 ( utils_crypt.c) 中:

static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
               long timeout)
{
[...]
       /* Read and write to /dev/tty if available */
       infd = open("/dev/tty", O_RDWR);
       if (infd == -1) {
               infd = STDIN_FILENO;
               outfd = STDERR_FILENO;
       } else
               outfd = infd;

       if (tcgetattr(infd, &orig))
               goto out_err;

所以它/dev/tty通過打開它進行測試,如果它有效,它就會使用它。如果失敗,它會退回到正常的標準輸入、標準輸出,然後你就不會再看到提示了。

至於/dev/tty,它是程序的終端,更多細節見man 4 tty

引用自:https://unix.stackexchange.com/questions/399604