一部のWebサイトからインポートされたスクリプトがあります。実行すると「Hello」が出力されますが、スクリプトがどのように機能するのか理解できません。
このスクリプトが実際に何をしているのかを説明できる人はいますか?
#!/bin/bash
echo hello
if test -t 1; then
# Stdout is a terminal.
exec >log
else
# Stdout is not a terminal.
npipe=/tmp/$$.tmp
trap "rm -f $npipe" EXIT
mknod $npipe p
tee <$npipe log &
exec 1>&-
exec 1>$npipe
fi
echo goodbye
答え1
このスクリプトは、より多くのタスクを実行するために変更する必要がある例かもしれませんecho goodbye
。
スクリプトdemo
を実行すると、ご覧のように最初に「hello」が出力されます。次に、実行中であるかどうかを判断するために、出力が端末に送信されることを確認します。
demo
または
demo | some other program
前者の場合、残りのファイルの出力を名前付きパイプに送信しますlog
。後者の場合は、名前付きパイプに書き込まれたすべての内容をスクリプトの出力にコピーするプロセスをnamed pipe
開始します。次に、残りのファイルの出力が対応する名前付きパイプに送信されるようにスケジュールします。また、完了時に名前付きパイプを削除する準備をします。tee
demo
some other prog
log
demo
exec 1>&-
この行は必須ではありません。
これらすべての最終結果は、「log」ファイルに「goodbye」という単語を書き込むことです。実行すると、demo | cat
画面に「Hello」と「Bye」が表示されます。
@derobertがコメントで指摘したように、名前付きパイプは予測可能な名前を持ちます。この設定によっては、誰かが出力を読み取ったり(したがって表示されない)、追加のコンテンツを追加してコピーして出力を破損する可能性がありますumask
。これは、既知のまたは予測可能な名前に使用できる多くの標準攻撃に追加されます。他のファイルが開かれるか切り取られるようにソフトリンクまたはハードリンクを事前設定できます。私のLinuxシステムでは、ファイルがすでに存在する場合、mknodは失敗しますが、スクリプトはこのエラーを無視してファイルを実行します。demo
tee
tee
exec 1>$npipe