説明
以下を変更せずに実行するThe Scriptと、(正しく) 出力されます。
2 1 スタート
以下のスクリプトのステートメントのコメントを外した後exec
、ファイル記述子 3 は標準出力を指し、ファイル記述子 4 は標準エラーを指します。
exec 3>&1 4>&2
また、すべての標準出力と標準エラーは、コンソールに出力する代わりにファイルに記録されます。
# Two variances seen in the script below
exec 1>"TEST-${mode:1}.log" 2>&1 # Log Name based on subcommand
exec 1>"TEST-bootstrap.log" 2>&1 # Initial "bootstrap" log file
exec ステートメントが配置されると、スクリプトは 3 つのファイル (コンテンツを含む) を作成する必要があります。
TEST-bootstrap.log
(正常に作成されました - 空のファイル)
TEST-one.log
(正常に作成されました)
ワンスタート
TEST-two.log
(作成されません)
2 1 スタート
しかし、代わりに、最初のログ ファイルの後に停止するように見え、作成されませんTEST-two.log
。exec
コメントアウトされたステートメントで機能することを考えると、何が問題になる可能性がありますか?
スクリプト
#!/bin/bash
SELFD=$(cd -P $(dirname ${0}) >/dev/null 2>&1; pwd) # Current scripts directory
SELF=$(basename ${0}) # Current scripts name
SELFX=${SELFD}/${SELF} # The current script exec path
fnOne() { echo "one ${*}"; }
fnTwo() { echo "two ${*}"; }
subcommand() {
# exec 3>&1 4>&2
# exec 1>"TEST-${mode:1}.log" 2>&1
case "${mode}" in
-one) fnOne ${*}; ;;
-two) fnTwo ${*}; ;;
esac
}
bootstrap() {
# exec 3>&1 4>&2
# exec 1>"TEST-bootstrap.log" 2>&1
echo "START" \
| while read line; do ${SELFX} -one ${line}; done \
| while read line; do ${SELFX} -two ${line}; done
exit 0
}
mode=${1}; shift
case "${mode:0:1}" in
-) subcommand ${*} ;;
*) bootstrap ${mode} ${*} ;;
esac
exit 0
このスクリプトは、厳密には、私の別のより複雑なスクリプトで直面している問題の孤立した例です。できるだけ簡潔にまとめましたが、必要に応じて拡張します。
私が達成しようとしていること(興味のある人は余分に読んでください)
上記では、簡単にするためにgnu-parallelThe Scriptの代わりにwhileループを使用しており、デバッグとここでの質問を容易にするために「1」と「2」をエコーする単純な関数を使用しています。
私の実際のスクリプトでは、プログラムは、URL からアーカイブのリストをフェッチし、それらをダウンロードし、それらのコンテンツを抽出し、結果のファイルをそれぞれ処理する次の関数を持ちlist-archives
ます。これらの操作にはさまざまな時間がかかることを考慮して、並行して実行することを計画しました。私のスクリプトの関数は次のようになります。download
extract
process
bootstrap()
# program ./myscript
list-archives "${1}" \
| parallel myscript -download \
| parallel myscript -extract \
| parallel myscript -process
そして、次のように呼び出されます。
./myscript "http://www.example.com"
私が達成しようとしているのは、独自の関数を並行して呼び出し、実行するすべてを記録できるプログラムを開始する方法です。これは、データが最後にいつフェッチされたかを判断したり、エラーをデバッグしたりするのに役立ちます。
また、サブコマンドで呼び出されたときにプログラムにログを記録させたいと思います。
# only list achives
>> ./myscript -list-archives "http://www.example.com"
# download this specific archive
>> ./myscript -download "http://www.example.com/archive.zip"
# ...