curlでbashスクリプトの実行が失敗し、ファイルからbashスクリプトの実行が成功しました。

curlでbashスクリプトの実行が失敗し、ファイルからbashスクリプトの実行が成功しました。

install.shデフォルトでは、次のスクリプトがあります。

#!/bin/bash

if [[ ! -f "/usr/bin/jq" ]]; then
  apt-get update && apt-get install -y jq
fi

echo $(date) >> install.log

サーバーに置き、次のように実行すると:

curl -s0 https://myserver.com/install.sh | bash

クレイジーapt-get出力の後echo、最後の行を実行するのではなく、その行を出力echo $(date) >> test.logとして印刷します。一方、install.shディスクに保存して実行すると、./install.sh期待どおりに機能します。エコラインを実行してinstall.log追加します。

問題をさらに再現するために、次のようにローカルで実行しました。

cat install.sh | bash

また、同じ問題があります。

apt-get remove jq各テストの前に手動で実行してください。インストールすると、jq両方が期待どおりに動作します。それでは、ダウンロードで実行するのとローカルファイルで実行するのはなぜ違いますか?

この問題を説明するために短いビデオを記録しました。https://www.youtube.com/watch?v=lYvGXI7AibA

ベストアンサー1

通常bash、ファイル(bash foobash <foo:.しかし、今はapt-getユーザーに尋ねたいコマンド()を起動し、STDINを使用してそれを行います。

だから奇妙なことが起こります。 bashはSTDINからコマンドを読み込み、1つずつ実行します。これで、コマンドの1つがSTDINから読み取られ、ファイルの次の行が読み込まれます。その後、bashはSTDINから次の行を読み取るので、他のコマンドがすでに読み込んだ1つのコマンドをスキップします。

この小さなスクリプトは何が起こっているのかを示しています。

echo "hello"
read -p "how do you do? "
echo "I understand"
echo "you are '$REPLY'."
echo "bye"

ファイルに保存し、bash -x fooまずasを実行してからasを実行しますbash -x <foo

あなたの場合でも同じことが起こります。

1つの解決策は、プロセス置換を使用することです。

bash -x <(cat foo)

またはあなたの場合は単に:

bash <(curl -s0 https://myserver.com/install.sh)

いくつかの注意:

シェルスクリプトが奇妙なことをするたびにbash -x何が起こっているかを確認するために使用します。

書くcat foo| ...ことが呼ばれる猫に役に立たない用途。リダイレクトを使用できます。

おすすめ記事