我正在撰寫一個腳本來執行我喜歡在全新安裝 Linux 時執行的常見任務。它具有從更新系統到安裝常用軟體的各個階段的功能。
現在我正在嘗試讓腳本從文本檔案中讀取軟體串列,詢問用戶是否要安裝它。如果他們說“是”,它將很容易安裝該軟體。該軟體的當前草案包含帶有命令的 echo 陳述句,以避免在我測驗腳本時進行更改。這是我要設定的功能。
InstallAptSW () {
file="./apps/apt-apps"
while read -r line; do
read -p "Would you like to install $line? [Y/n]" yn
yn=${yn:-Y}
case $yn in
[Yy]* ) echo "sudo apt install -y $line";;
[Nn]* ) printf "\nSkipping";
break;;
* ) echo 'Please answer yes or no.';;
esac
done < $file
}
應用程式檔案只是一個軟體串列,例如
code
gparted
snapd
neofetch
etc...
這是函式的當前結果:
$USER@$HOSTNAME:~/Documents/popOS-post-install$ ./PopOS-Post-Install.sh
Please answer yes or no.
Please answer yes or no.
Please answer yes or no.
Please answer yes or no.
Please answer yes or no.
Please answer yes or no.
Please answer yes or no.
Goodbye
uj5u.com熱心網友回復:
因為while; do...done < "$file"代碼塊的輸入是從包含要安裝的軟體名稱的檔案中處理的;沒有給read -rp "Would you like to install $line? [Y/n]" yn定特定的輸入處理程式,只是從其外部代碼塊繼承檔案輸入。
它不是讀取用戶輸入,而是從軟體串列檔案中讀取(使用)行。
需要有不同的輸入處理程式來讀取檔案和讀取用戶輸入。
根據John Kugelman的建議進行編輯
這是其他幾個修復:
#!/usr/bin/env bash
InstallAptSW() {
file='./apps/apt-apps'
# Reads from File Handler 3 which gets input from "$file"
while read -r line <&3; do
# printf before read -r avoid using the read -p bashism
printf 'Would you like to install %s [Y/n]? ' "$line"
# Default file handler is not used by "$file",
# so it takes user input without interference
read -r yn
yn=${yn:-Y}
case $yn in
[Yy]*) echo sudo apt install -y "$line" ;;
[Nn]*)
# Single-quotes are better
# when no expansion occurs within string
printf '\nSkipping'
break
;;
*) echo 'Please answer yes or no.' ;;
esac
# Double quote the "$file" variable to prevent
# word splitting and globing pattern matching
# Get "$file" input at the File-Handler 3
done 3< "$file"
}
InstallAptSW
uj5u.com熱心網友回復:
我會使用一個新的檔案描述符來讀取檔案;這樣您就可以在回圈中獲取用戶輸入:
InstallAptSW () {
local file="./apps/apt-apps"
local fd appname yn
while IFS='' read -r appname <&$fd
do
while true
do
read -N 1 -p "Would you like to install '$appname'? [Y/n] " yn
[[ $yn ]] && echo
yn=${yn:-Y}
case $yn in
[Yy]) echo "sudo apt install -y $(printf %q "$appname")"
# sudo apt install -y "$appname"
break
;;
[Nn]) echo "skip"
break
;;
esac
done
done {fd}< "$file"
}
編輯:在評論中首先應用了@JohnKugelman 建議。
如果您的 bash 版本不支持存盤在變數中的檔案描述符,那么您將不得不對其進行硬編碼,即使用大于或等于的數字3(我不知道上限,999應該是安全的):
while IFS='' read -r appname <&3
do
# ...
done 3< "$file"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/412226.html
標籤:
