4

ユーザーとの対話を必要としないスクリプトを開発しています。スクリプト内のプログラムでユーザーが何かを入力する必要がある場合、スクリプトは失敗してすぐに終了するはずです。

スクリプトの先頭にある を既に閉じておりSTDIN、これは一部のコマンドで機能しますが、別のファイル記述子 (通常はgitや などのパスワードを要求するものsudo) での入力を期待するものもあります。

現在、私のスクリプトは次のとおりです。

#!/bin/bash

# close STDIN
exec 0<&-

# test that $1 exists and it is a valid folder containing a git repository
# ...

cd "$1"

git fetch
# if git is not correctly configured, it asks for a password and
# my script waits for it :(

では、どうすればこれを回避できますか?

git注:またはsudoまたはでパスワードなしの構成を行う方法を尋ねているのではなく、 (または) のプログラムがユーザー入力を期待して、その場合にすぐに失敗するwhateverのを防ぐためです。bashsh

4

3 に答える 3

3

最初に、これがあなたの問題にアプローチする正しい方法だとは思わないことを言わせてください。まったく。アプリケーション固有のより優れたソリューションが必要であり、実際にそれを見つける必要があります。

主な問題は、どのプログラムを「強制終了」させたいかを知らなければ、それらを「エラーアウト」させる方法がわからないことです。また、プログラムを知っている場合、CodeGnome のソリューションで問題ないようです。

また、すべてのプログラムが STDIN から直接入力を読み取るわけではないことに注意してください。たとえば、Python の getpass モジュールは追加のファイル記述子を に直接開くため、/dev/ttySTDIN を閉じたりリダイレクトしたりしても問題ありません。これはsudoパスワードを受け入れる方法でもあり、ncurses も同様に機能すると思います。このように読み取ると、パスワードを画面に表示せずに取得できます。

/dev/tty(例: bash の)から直接読み取らないプロンプトの場合は、 (例: )readから STDIN をリダイレクトするだけで、どこかへ行けるかもしれません。または、現在行っていることを実行して STDIN を閉じることもできますが、閉じられた STDIN または EOF のみで構成されるリダイレクトされた STDIN に遭遇したときのプログラムの動作は制御できません。 プログラムが思い通りにエラーを出すことを願っていますが、有効な入力を期待してループし続けるかもしれません。知るか?/dev/null./prompt.sh </dev/null

さらに、閉じることもリダイレクトすることも、グローバルに機能する方法ではありません。一部のプログラムは、閉じた STDIN を期待して終了する場合があります。他のプログラムは、からの EOF が必要な場合があります。/dev/null

したがって、これを行う方法は、一般的な包括的なタイプのソリューションではなく、その場所に配置するプログラムに合わせたものです。さらに良いのは、try (プログラムを実行するため) とcatch (プログラムが入力を要求する場合) メソッドを使用せず、入力を要求しないことがわかっている方法でプログラムを呼び出すことです。

とにかく、そうは言っても、うまくいく可能性がある1つの可能性は、STDINを閉じてプロセスをバックグラウンドにすることです。例えば:

#!/bin/bash

exec 0<&-
./prompt.sh &

または、STDIN を /dev/null にリダイレクトし、プロセスをバックグラウンドにします。例えば:

#!/bin/bash

./prompt.sh </dev/null &

次に、プログラムのリターン コード ( を使用$?) をチェックして、プログラムが正しく終了したかどうかを確認する必要があります。(使用しているプログラムの不明なリストが標準の戻り値スキームに従っていることを願っています)

STDIN のクローズ / リダイレクトは、STDIN が入力を受け入れるために使用されるケースを処理し、プロセス/dev/ttyのバックグラウンド処理は (バックグラウンド処理されたプロセスには tty がないため) ケースを処理します。

プログラムが他の方法を使用してプロンプトを表示した場合 (疑似端末に直接 FD を開く、グラフィック入力ボックスをポップアップする、可聴プロンプトを表示するなど)。

于 2012-06-26T11:34:38.080 に答える
2

標準入力または標準エラーを閉じようとするよりも、パスワード プロンプトが表示された場合に回避する短い期待スクリプトを使用する方がよい場合があります。例えば:

#!/bin/bash

cd "$1"

expect -c '
    log_user 0
    spawn git fetch
    expect -timeout 30 -re "ass(phrase|word)" { exit 1 }
    '

# Do something based on the exit status of the expect script.
[[ $? -eq 1 ]] && { echo 'Password prompt detected!' >&2; exit 1; }

パスワードまたはキー パスフレーズのプロンプトが表示された場合、expect スクリプトは終了ステータス 1 で戻ります。その後、bash スクリプトは自由に同様に実行したり、他のアクションを実行したりできます。

それが役立つことを願っています!

于 2012-06-26T09:57:32.153 に答える
0

ほとんどの (すべて?) *NIX にはtty、シェルの名前を出力し、シェルに tty が接続されている場合はtty終了するコマンドがあり、それ以外の場合はエラーで終了します。01

if ! tty>&/dev/null; then echo "Not a terminal; goodbye."; exit 1; fi
于 2012-06-28T18:11:05.360 に答える