已经有类似的问题,但我发布这个是因为没有一个答案有效。我正在编写一个 bash 脚本来自动安装 pacman 和 AUR 包在我的 Arch 系统上。这个想法是先逐行读取一个包含包名称的文件 (myfile),然后逐字读取,并针对每个单词执行安装。这对 pacman 很有效,但对 AUR Helper (aurman) 无效。aurman 的部分如下所示:
while read line; do
if [[ "$line" =~ \$[[:space:]]aurman[[:space:]]-S[[:space:]][[:alnum:]]* ]]
then
aurline=$(echo "$line" | awk '{ $1=""; $2=""; $3=""; print}' | sed 's/^ *//')
for aurpkg in $aurline
do
sudo -u "${my_user}" bash << EOF
aurman -S --noconfirm --needed --noedit "$aurpkg"
wait
EOF
done
fi
done < "$myfile"
使用选项--noconfirm --needed --noeditaurman 不会提示我输入是/否,但对于某些软件包,它会提示我输入数字。因此,在这种情况下,问题是脚本不会等待,软件包不会安装,并且 aurman 会产生错误“EOFError:读取一行时出现 EOF”。我尝试过像这样暂停脚本:
aurman ...
wait
或者像这样:
aurman ... &
wait
但这些都不起作用。
那么,当 aurman 提示我输入数字时,我该如何暂停脚本?在这种情况下,一般的方法是什么?当我运行脚本时,如何从一开始就为特定包给出答案(例如,包 x 的答案为 1)?
答案1
基本问题是 stdin(试图aurman
读取)不是来自用户,它首先从 重定向$myfile
,然后从包含以下 shell 命令的此处文档重定向:sudo
运行的 shell 命令的此处文档重定向。一种选择是通过不同的文件描述符传递这些文件,例如 #3(通常不使用)。我思考您还可以通过消除在其下运行的 shell 来简化它sudo
——因为您在前台运行aurman
,所以不需要wait
它,所以您不需要 shell(因此不需要此处的文档)。
while read line <&3; do
if [[ "$line" =~ \$[[:space:]]aurman[[:space:]]-S[[:space:]][[:alnum:]]* ]]
then
aurline=$(echo "$line" | awk '{ $1=""; $2=""; $3=""; print}' | sed 's/^ *//')
for aurpkg in $aurline
do
sudo -u "${my_user}" aurman -S --noconfirm --needed --noedit "$aurpkg"
done
fi
done 3< "$myfile"
如果这不起作用并且您确实需要在下运行 shell sudo
,那么您也可以通过 FD #3 重定向它,并将bash
其读取为脚本,如下所示:
sudo -u "${my_user}" bash /dev/fd/3 3<< EOF
aurman -S --noconfirm --needed --noedit "$aurpkg"
wait
EOF
答案2
对于 bash,有睡觉命令,使脚本进入休眠状态,直到经过一定时间(以秒为单位)。但是,如果您想要获取密码,我建议您使用以下两种方法之一(查看我放在底部的脚本,以说明休眠的工作原理,以及下面提到的两种替代方法)。
- 您可以在启动脚本时将密码作为参数发送。
- 您可以使用读命令,这将记录输入,直到客户按下回车键。
[root@client ~]# cat readPass.sh
#!/bin/bash
# Author: @djcerdas
password="$1"
# Sample sleep command
echo "Hi, I am the PID $$, I am going to sleep 3 seconds"
date&&sleep 3&&date
echo "---------------------------------------"
# Sample method 1: passing password a parameter
echo "Method 1: The password is $password"
password=""
echo "---------------------------------------"
# Sample method 2: using read
echo "Method 2: Please provide your password:"
read password
echo The password is $password
[root@client ~]# ./readPass.sh myPasswordX
Hi, I am the PID 2257, I am going to sleep 3 seconds
Tue Apr 3 01:17:55 CST 2018
Tue Apr 3 01:17:58 CST 2018
---------------------------------------
Method 1: The password is myPasswordX
---------------------------------------
Method 2: Please provide your password:
myNewPassword
The password is myNewPassword
[root@client ~]#