已經有類似的問題,但我發布此問題是因為沒有答案有效。我正在編寫一個 bash 腳本來自動在我的 Arch 系統上安裝 pacman 和 AUR 套件。這個想法是先逐行讀取包含套件名稱的檔案(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 提示我輸入號碼時,如何暫停腳本?在這種情況下,一般的做法是什麼?當我運行腳本時,如何從一開始就給出特定包的答案(例如 1 代表包 x)?
答案1
基本問題是 stdin(試圖aurman
從中讀取)不是來自用戶,它首先從 重定向$myfile
,然後從包含要運行的 shell 命令的此處文件重定向sudo
。一種選擇是透過不同的文件描述符傳遞這些文件,例如#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,有睡覺命令,該命令使腳本進入休眠狀態,直到經過一段時間(以秒為單位)。但是,如果您想要捕獲密碼,我會推薦您使用以下兩種方法之一(檢查我放在底部的腳本,以說明睡眠如何工作,以及下面提到的兩種替代方法)。
- 您可以在啟動腳本時將密碼作為參數發送。
- 您可以使用讀命令,這將記錄輸入,直到客戶按 Enter 鍵。
[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 ~]#