Похожие вопросы уже есть, но я публикую это, потому что ни один из ответов не сработал. Я пишу скрипт 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 запрашивает у меня номер? Каков общий подход в таких случаях? Как я могу дать ответ для определенного пакета с самого начала, когда я запускаю скрипт (например, 1 для пакета x)?
решение1
Основная проблема в том, что stdin ( aurman
из которого пытаются читать) не поступает от пользователя, он перенаправляется сначала из $myfile
, а затем из here-документа, содержащего команды оболочки для sudo
запуска. Один из вариантов — передать эти файлы через другой файловый дескриптор, например #3 (который обычно не используется). ЯдуматьВы также можете упростить его, исключив оболочку, запущенную в среде выполнения sudo
, — поскольку вы работаете aurman
на переднем плане, в ней нет необходимости wait
, поэтому вам не нужна оболочка (и, следовательно, не нужен here-doc).
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"
Если это не сработает и вам действительно нужно, чтобы оболочка запускалась под управлением 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 ~]#