如何从 bash 脚本提示输入密码?
我收到此错误消息:problem with the agent: Inappropriate ioctl for device
。
#!/bin/bash
fname="/home/user/elist.txt"
while IFS= read -r file
do
tar czf "$file".tar.gz "$file"
gpg --passphrase-fd 0 --no-symkey-cache --symmetric --cipher-algo AES256 "$file".tar.gz
done < "$fname"
答案1
鉴于--passphrase-fd 0
,gpg
正在尝试从文件中读取密码"$fname"
- 因为在while
循环内,这就是文件描述符0
重定向的来源。
您有一些选项可以使其发挥作用:
将整个循环括在大括号中,将标准输入复制到新的文件描述符并将其用作 的
--passphrase-fd
参数:fname="/home/user/elist.txt" { while IFS= read -r file do tar czf "$file".tar.gz -- "$file" gpg --passphrase-fd 3 --no-symkey-cache --symmetric --batch \ --cipher-algo AES256 --pinentry-mode loopback -- "$file".tar.gz done < "$fname" } 3<&0
显式打开一个新的文件描述符
elist.txt
并read
从中重定向 的标准输入(而不是重定向整个循环的标准输入):exec 3<"/home/user/elist.txt" while <&3 IFS= read -r file do tar czf "$file".tar.gz -- "$file" gpg --passphrase-fd 0 --no-symkey-cache --symmetric --batch \ --cipher-algo AES256 --pinentry-mode loopback -- "$file".tar.gz done exec 3<&-
显式打开一个新的文件描述符
/dev/tty
并使用它代替0
该选项的参数--passphrase-fd
(如果您的脚本从终端交互运行,这很好;如果密码短语来自其他内容,则它可能无法按预期工作) :fname="/home/user/elist.txt" exec 3</dev/tty while IFS= read -r file do tar czf "$file".tar.gz -- "$file" gpg --passphrase-fd 3 --no-symkey-cache --symmetric --batch \ --cipher-algo AES256 --pinentry-mode loopback -- "$file".tar.gz done < "$fname" exec 3<&-
作为更简洁的替代方案,您可以使用仅从
/dev/tty
for重定向标准输入gpg
,0</dev/tty gpg --passphrase-fd 0 ...
从而避免使用exec
命令。假设您已正确配置
gpg-agent
(例如,在某些 Linux 发行版上,代理是套接字激活的 systemd 服务,用于pinentry
与用户交互并在虚拟终端和图形会话中开箱即用),只需避免使用--passphrase-fd
:fname="/home/user/elist.txt" while IFS= read -r file do tar czf "$file".tar.gz -- "$file" gpg --no-symkey-cache --symmetric \ --cipher-algo AES256 -- "$file".tar.gz done < "$fname"
请注意,我在命令行中添加了--batch
和 ,其中--pinentry-mode loopback
gpg
--passphrase-fd
,因为引用手册,
--batch
...自版本 2.0 起,仅当也给出了该选项时才使用此密码。从版本 2.1 开始,--pinentry-mode
还需要将其设置为loopback
.