web-dev-qa-db-ja.com

コマンドラインに入力を自動的に入力する

各操作で「y」を入力するように要求するスクリプトを実行しています。すべての入力を一度に渡すために、$ ./script < echo 'yyyyyyyyyyyyyy'などのソリューションを探しています。

136
NewMrd

その場合のために特別に作成されたコマンドがあります:yes

$ yes | ./script

これは、yesの出力を./scriptの入力に接続します。したがって、./scriptがユーザー入力を要求すると、代わりにyesの出力を取得します。 yesの出力は、yとそれに続く改行の無限ストリームです。基本的に、ユーザーが./scriptのすべての質問に対してyと入力しているようです。

Yes(n)ではなくno(y)と言いたい場合は、次のようにできます。

$ yes n | ./script

一部のツールには、yesを常に回答と見なすオプションがあることに注意してください。例についてはこちらをご覧ください。 「apt-get upgrade」でyes/noプロンプトをバイパスする


入力を入力する他の方法:

スクリプトが期待するyの数が正確にわかっている場合は、次のようにできます。

$ printf 'y\ny\ny\n' | ./script

改行(\n)はEnterキーです。

printfの代わりにyesを使用すると、入力をよりきめ細かく制御できます。

$ printf 'yes\nno\nmaybe\n' | ./script

まれに、このコマンドでは、ユーザーが文字の後にEnterキーを押す必要がないことに注意してください。その場合、改行は省略します。

$ printf 'yyy' | ./script

完全を期すために、 here document を使用することもできます。

$ ./script << EOF
y
y
y
EOF

または、シェルがそれをサポートしている場合 ここでは文字列

$ ./script <<< "y
y
y
"

または、1行に1つの入力があるファイルを作成できます。

$ ./script < inputfile

コマンドが十分に複雑で、上記の方法では不十分な場合は、 expect を使用できます。

以下に、非常に単純なexpectスクリプトの例を示します。

spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof

技術的な選択:

質問で指定した架空のコマンド呼び出しは機能しません。

$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory

これは、シェルの文法により、コマンドラインの任意の場所にリダイレクト演算子が許可されているためです。シェルに関する限り、仮想コマンドラインは次のラインと同じです。

$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory

つまり、./scriptは引数'yyyyyyyyyyyyyy'で呼び出され、stdinはechoという名前のファイルから入力を取得します。また、ファイルが存在しないため、bashは文句を言います。

251
lesmana

コマンドyesを使用します。

yes | script

Manページからの抜粋:

NAME
       yes - output a string repeatedly until killed

SYNOPSIS
       yes [STRING]...
       yes OPTION

DESCRIPTION
       Repeatedly output a line with all specified STRING(s), or 'y'.
11
Peter W. Osel

いくつかのもの(apt-getなど)は、サイレントモードで実行する特別なフラグを受け入れます(デフォルトを受け入れます)。 apt-getの場合、-yフラグを渡すだけです。ただし、これはスクリプトに完全に依存します。

さらに複雑なものが必要な場合は、スクリプトをexpectスクリプトにラップできます。 expectを使用すると、出力を読み取って入力を送信できるため、他のスクリプトでは許可されない非常に複雑な処理を実行できます。 Wikipediaページの例の1つ

# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username Prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password Prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a Shell Prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another Shell Prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
9
Oli

シェルスクリプトでは、次のspawn、expect、sendのトリックも使用できます。

spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

ただし、上記のシーンでは、スクリプトの実行中に取得する予定のフレーズを指定する必要があります。他の例については、次のリンクを参照してください。

Bash内に期待

7
Tarun

さて、これは非常に洗練されたソリューションではないかもしれませんが、別のファイルにオプションを記述し、それをスクリプトへの入力として渡すと、同様に機能します。したがって、すべてのオプションを使用して新しいファイルを作成する場合(このファイルを「options.in」と呼びます)、./script.sh < options.inを使用してスクリプトを簡単に実行し、必要に応じてさまざまなオプションファイルを編集/作成できます。

2
Sidhha

私はDialogでbashスクリプトを書いていましたが、これも自動的に行われる必要がありました。私はこれをしました、そして、それは魅力のように働きました。

# -Wy force signaturewipe (if exists)
echo "y" | Sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog
0
Benjamin West