このコードがあります強く打つスクリプト:
r2g(){
echo "executable is: $0" # "/bin/bash"
(
set -e;
r2g_internal "$@" \
2> >( while read line; do echo "r2g error: $line"; done ) \
1> >( while read line; do echo "r2g: $line"; done )
)
exit_code="$?"
if [[ "$exit_code" != "0" ]]; then
echo "something experienced an error, to see log, run: r2g_view_log";
return 1;
fi
}
r2g_internal
shを実行した後、明らかにbash環境にリソースを提供しようとするいくつかのプロセスによって開始され、shで奇妙な構文エラーが発生します。
r2g error: sh: r2g: line 2: syntax error near unexpected token `>'
r2g error: sh: r2g: line 2: ` r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) > >( while read line; do echo "r2g: $line"; done ) );'
r2g error: sh: error importing function definition for `r2g'
問題を説明するために動画を作成しました。 https://www.uselooom.com/share/82f23ebfe6754412a20be057957e45f4
フォローアップビデオ: https://www.uselooom.com/share/0465c2857cc244879b52b7bdb516243e
を実行するとき、npm install
一部のプロセスは..sh
で開始する必要があります。npm
時々、gitコマンドを実行するとgit
プロセスsh
も起動するように見えます。その場合、端末に同じ種類の構文エラーが表示されます。
bashを介して開始されたshプロセスが親シェル/環境からbashコードを取得しようとする理由を理解できません。
この動画で問題がより明確になることを願っています。
に電話すると、unset -f r2g
問題はすぐに解決されます。だから私のr2g関数が呼び出されているようですが、/bin/sh
方法と理由がわかりません。
以下はr2gとr2g_internalのソースコードです。 https://gist.github.com/ORESoftware/0fa7e3d6b75a65b17b6b126a7bec3397
答え1
これで問題が解決しない場合があります。しばらく時間をかけてメモを書いてください。コメントが長すぎます。
これをする必要がなければしないでください。構造コードを一行引用します。
r2g_internal "$@" 2> >( while read line; do echo "r2g error: $line"; done ) 1> >( while read line; do echo "r2g: $line"; done )
他の人にとっては、あなたでさえ読みにくいと思います。
最初から始めます。
私は見なかったシェルボーン良い:
#!/bin/bash
または
#!/bin/sh
など。
Bashは必要ありませんが、このシェルスクリプトがBashを要求しているような場合は、次のようにします。POSIX
sh
移植性を目的としています。一度だけ使用されるので
exit_code
避けられます。必ず数字を引用する必要はありません。この場合は
"$?"
。Bash関連のコマンドを避け、
[[ .. ]]
古典的なテストコマンドを使用してください。この場合:if [ $? -ne 0 ]
行の末尾にセミコロンを追加する必要はなく、次の構造を使用できます。
if [ $? -ne 0 ] then echo "something experienced an error, to see log, run: r2g_view_log" return 1 fi
-r
スイッチを使用してread
このトピックの詳細を学びます。ここ。私も少し調整しましたが、確認してみてください。
これが意図的なものかどうかはわかりませんが、私が
return 1
見ると、あなたがそれを使ったところではそうではありませんexit 1
。これシェルボーン
set -e
以下を含めることができます。#!/bin/bash -e
上記の内容に基づいて書き直しました。
#!/bin/bash -e
r2g()
{
echo "executable name is: $0"
r2g_internal "$@" 2> >( while read -r line; do echo "r2g error: $line"; done ) >( while read -r line; do echo "r2g: $line"; done )
if [ $? -ne 0 ]
then
echo "something experienced an error, to see log, run: r2g_view_log"
exit 1
fi
}
答え2
攻撃する意図はありませんが、エラーメッセージを読んで理解してみましたか?
トークンの近くで予期しない構文エラーが発生しました>'
これは、コードに明白なエラーが含まれていることを明示的に通知します2> >(
。 '>' は標準出力をファイルに直接書き込みます。 r2g_internalの出力を標準入力から読み取るスクリプトに送信しようとしています。 'を使用する必要があります。|'>'の代わりに'.
もう1つのバグ - stdoutとstderrに別々のファイルを指示できますが、簡単に別のスクリプトに指示することはできません。まず、ファイルに書き込んでから個別に処理する必要があります。
r2g_internal "$@" 1> stdout.txt 2> stderr.txt
cat stderr.txt | ( while read line; do echo "r2g error: $line"; done )
cat stdout.txt | ( while read line; do echo "r2g: $line"; done )