bash スクリプトにユーザーの応答を待機させるにはどうすればよいでしょうか?

bash スクリプトにユーザーの応答を待機させるにはどうすればよいでしょうか?

すでに同様の質問がありますが、どの回答も役に立たなかったので、これを投稿します。Arch システムで pacman と AUR パッケージのインストールを自動化する bash スクリプトを作成しています。アイデアは、パッケージ名を含むファイル (myfile) を最初に 1 行ずつ、次に単語ごとに読み取り、単語ごとにインストールを実行することです。これは 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 は Yes/No を尋ねませんが、一部のパッケージでは番号を尋ねます。この場合、スクリプトが待機せず、パッケージがインストールされず、aurman が「EOFError: 行の読み取り時に EOF が発生しました」というエラーを生成するのが問題です。次のようにスクリプトを一時停止しようとしました。

aurman ...
wait

または次のようになります:

aurman ... &
wait

しかし、どれも機能しません。

では、aurman が数字の入力を要求したときにスクリプトを一時停止するにはどうすればよいでしょうか? このような場合の一般的なアプローチは何ですか? スクリプトを実行するときに、最初から特定のパッケージの答えを出すにはどうすればよいですか (例: パッケージ x の場合は 1)?

答え1

基本的な問題は、stdin(aurman読み込もうとしている)がユーザーからではなく、最初に からリダイレクトされ$myfile、次に を実行するためのシェルコマンドを含むヒアドキュメントからリダイレクトsudoされることです。1つのオプションは、これらのファイルを別のファイル記述子、たとえば #3(通常は使用されない)を介して渡すことです。考えるまた、シェルの実行を排除することで簡素化することもできます。フォアグラウンドでsudo実行しているため、シェルは不要であり、ヒアドキュメントも不要です。aurmanwait

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の場合、寝るコマンドは、一定時間(秒数)が経過するまでスクリプトをスリープ状態にします。ただし、パスワードをキャッチしたい場合は、以下の 2 つの方法のいずれかをお勧めします(スリープの仕組みを説明するために、一番下に記載したスクリプトと、以下で説明する 2 つの代替方法を確認してください)。

  • スクリプトを起動するときに、パスワードをパラメータとして送信できます。
  • 使用できます読むこのコマンドを実行すると、顧客が 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 ~]#

関連情報