コードストアからリモートスクリプトを実行すると、無限ループが発生します。

コードストアからリモートスクリプトを実行すると、無限ループが発生します。

私はしばしばGitHubでリモートBashスクリプトのrawバージョンを実行するために次のパターンを使用します。

wget -O - https://raw.githubusercontent.com/<username>/<project>/<branch>/<path>/<file> | bash

通常は問題なく実行できますが、特定のスクリプトに次のコードを追加したため、無限ループが発生しました。echo(GitHubから端末にコピーして貼り付けて直接実行した場合でも頻繁に発生します。):

while true; do
    read -p "Example question: Do you wish to edit the PHP file now?" yn
    case $yn in
        [Yy]* ) nano PROJECT/PHP_FILE; break;;
        [Nn]* ) break;;
        * ) echo "Please answer yes or no.";;
    esac
done

次のことで、問題を少なくとも部分的に解決できました。

cd ACTION_DIRECTORY
wget https://raw.githubusercontent.com/<username>/<project>/<branch>/<path>/<file> &&
source FILENAME &&
rm FILENAME

これは| bash、パイプラインが少なくとも問題を悪化させていることを示唆しています。いつも後ろに来てください。

なぜecho "Please answer yes or no."「無限に」起こるか。 (CTRLC+で停止しましたC。)
1行および/またはでコマンドを実行できませんでしたかwhile true; do case esac done

ベストアンサー1

なぜecho …「無限に」起こるか。

標準入力と一緒に。は同じ標準入力から読み取られますwget … | bashwgetbashbashwgetread

通常、readスクリプトソースから読み取ると、スクリプトの一部が消費される可能性があります。あなたの場合は、完全なbash部分while … doneを読む必要があります(例while … done <whatever:)。働く時はread読むことがありません。最初もread失敗しました。

問題のスクリプトはread失敗を確認しません。

また、read -pプロンプトを標準入力として印刷するため、プロンプトは表示されません。

スクリプトが存在する</dev/tty read …かstdinで読み取られwhile … done </dev/ttyない場合は、コンソールから読み込みます。この方法は機能しますが、この方法を使用するにはスクリプト自体を変更する必要があります。一般的に言えば、別の方法でスクリプトを実行し、スクリプト全体のstdinから読み取る必要がある場合(これは。readbashread/dev/tty

ただし、nano(あなたが答える場合y)、標準入力について文句を言うかもしれません。修正があると、標準入力が(すでに破損している)パイプから出るため、対応する修正が</dev/tty read …生成nanoされます。修正があれば動作します。Too many errors from stdinwgetwhile … done </dev/tty

より大きなスクリプトの場合、この方法で「修正」できる場所が多い場合があります。正しい一般的な解決策は、標準入力をまったく傍受しないことです。

一般的な回避策は、次のいずれかを実行することです。

bash <(wget -O - …)
.    <(wget -O - …)

スクリプトを別のシェルbash(試行のようにwget … | bash …)で実行するのか、現在のシェルで(source FILENAMEソリューションのように)実行するのかによって異なります。

これで、標準入力を独立してリダイレクトできます。たとえば、次のようになります。

yes | bash <(wget -O - …)

文法<(some_command …)と呼ばれますプロセスの交換。効果がある大きな打撃を受けた状態でそしていくつかの他の殻(純粋な殻ではないshバシズム)。以下はいくつかの興味深い観察です。プロセス置換とパイプ(「STDINを保持」セクションこの回答つまり、これはあなたの問題です。)

おすすめ記事