Як змусити bash скрипт чекати відповіді користувача?


3

Існують вже подібні питання, але я їх публікую, оскільки жодна з відповідей не спрацювала. Я пишу сценарій 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 --необхідний --нередагувати aurman не підказує мені для Так / Ні, але для деяких пакетів він підказує мені номер. Отже, проблема в цьому випадку скрипт не чекає, пакет не встановлюється і aurman видає помилку "EOFError: EOF при читанні рядка". Я спробував призупинити такий сценарій:

aurman ...
wait

або так:

aurman ... &
wait

але жодна з цих робіт.

Отже, як я можу призупинити свій скрипт, коли aurman підказує мені номер? Який загальний підхід у таких випадках? Як я можу дати відповідь на певний пакет з самого початку, коли я запускаю скрипт (наприклад, 1 для пакета x)?


Не знаю aurman але можливо expect це потрібний вам інструмент. Подивитися man 1 expect і це відповідь .
Kamil Maciorowski

Відповіді:


4

Основна проблема полягає в тому, що stdin (який aurman намагається читати з) не надходить від користувача, він спочатку перенаправляється $myfile, а потім з документа тут, що містить команди оболонки для sudo бігти. Один із варіантів полягає в тому, щоб передати ці файли через інший дескриптор файлу, наприклад, # 3 (який зазвичай не використовується). I думаю Ви також можете спростити її, усунувши запуск оболонки sudo - після запуску aurman на передньому плані немає необхідності wait для цього, так що вам не потрібно оболонки (і, отже, не потрібно тут-док).

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

0

Для bash, є сон команда, яка переводить сценарій у сплячий режим, поки не пройде час у секундах. Однак, якщо ви хочете вловити пароль, я рекомендую вам, скоріше, один з двох методів нижче (перевірте сценарій, який я поставив внизу, щоб проілюструвати, як працює сплячий режим, а також 2 альтернативи, згадані нижче).

  • Пароль можна надіслати як параметр під час запуску сценарію.
  • Можна використовувати read команда, це запише входи, поки клієнт не натисне 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 ~]#

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.