tee は、Bash スクリプトで誤った順序で出力を表示します。

tee は、Bash スクリプトで誤った順序で出力を表示します。

私は特定のディレクトリで(スクリプトへの引数として)複数のタスクを実行する必要がある大学の課題のためのbashスクリプトを書いています。

  1. 特定の権限を持つすべてのファイル/ディレクトリを表示する(権限は8進形式の引数として提供されます)
  2. 過去日に変更されたファイルをディレクトリツリーに表示します(xはパラメータ)。
  3. 過去日に訪問したツリーのサブディレクトリを表示します。 (xは上記で使用したのと同じパラメータです。)
  4. ディレクトリ内のすべてのパイプ/ソケットタイプファイルを表示する
  5. サブディレクトリではなく、ディレクトリ内のすべての空のファイルを表示する

各操作が完了したら、スクリプトは見つかったファイル(またはサブディレクトリ)の数も表示する必要があります。

このコマンドを使用して目的の出力を印刷しています。(例:タスク1):echo "$files_perms" | tee >(echo "Files found: $(wc -l)")

問題は、tee最初と2番目の操作の後に出力が正しい順序で表示されないことです。

最初の作業(出力正常):

2番目の作業(出力は依然として正常です):

3番目、4番目、5番目のジョブ(出力が無効です。矢印は各ジョブの出力をtee表し、op3-op5は各ジョブの実際の出力です):

各関数のコードは次のとおりです。

#display files in the current directory tree with the specified permissions
sub1 () {
    files_perms=$(ls $1 -l | grep $2 --color=never)
    echo "$files_perms" | tee >(echo "Files found: $(wc -l)")
    echo ""
}

#display files in the current directory tree that were modified within the last $2 days (without hidden files)
sub2 () {
    files_modlastxdays=$(find $1 -not -path '*/.*' -type f -mtime -$2)
    echo "$files_modlastxdays" | tee >(echo "Files found: $(wc -l)")
    echo ""
}

#display subdirectories in the current directory tree that were accessed within the last $2 days (without hidden subdirs)
sub3 () {
    subdirs_acclastxdays=$(find $1 -not -path '*/.*' -type d -atime -$2)
    echo "$subdirs_acclastxdays" | tee >(echo "Subdirectories found: $(wc -l)")
    echo ""
}

#display all files that are of pipe/socket type in the current directory tree
sub4 () {
    ps_files=$(find $1 \( -type p -o -type s \))
    echo "$ps_files" | tee >(echo "Files found: $(wc -l)")
    echo ""
}

#display all empty files in current directory (NOT in subdirectories)
sub5 () {
    empty_files=$(find $1 -maxdepth 1 -type f -empty)
    echo "$empty_files" | tee >(echo "Files found: $(wc -l)")
    echo ""
}

関数呼び出しは次のとおりです。

echo "Files with permission $1 ($rwx_converted):"
sub1 $3 $rwx_converted

echo "Files that were modified within the last $2 days:"
sub2 $3 $2

echo "Subdirectories that were accessed within the last $2 days:"
sub3 $3 $2

echo "Files that are of pipe/socket type:"
sub4 $3

echo "Empty files (NOT in subdirectories):"
sub5 $3

$18進形式のファイル権限パラメータ(rwx_converted8進形式をrwx形式に変換)。

$2タスク2と3のx-dayパラメーター。

/ commandに使用されるディレクトリ引数$3lsfind

スクリプトの実行例:bash labscript2.sh 755 8 /home/na-no

出力が正しい順序で表示されないのはなぜですか(tee各/コマンドとlsfindいいえ複数行の後ろ)?

ベストアンサー1

同時に複数の同時プロセスが実行されています。出力順序は最初に書き込むプロセスによって異なります。

たとえば、4番目はtee出力書き込みを開始したようですが、3番目はwcまだ入力を処理しています。

考慮する:

#!/bin/bash

echo 1 | tee >(sleep 8; echo 1b) >(sleep 4; echo 1c)
echo 2 | tee >(sleep 2; echo 2b) >(sleep 6; echo 2c)
echo 3 | tee >(         echo 3b) >(         echo 3c)

echo done

tee入力をすべての出力にコピーする操作が完了すると終了します。ただし、bashのプロセス置換によって開始されたプロセスは非同期的に実行され、>(...)スクリプト自体が終了した後も実行を続行できます。tee

また、teeどの出力が最初に書き込まれるかは定義されません。すべての出力が実際に同じファイルの場合、出力が混在する可能性が高くなります。たとえば、マイコンピュータでは、上記teeの3行目が出力されます。

3b
3c
3

つまり、 other output 以降にstdout作成されたようです。これは、予想される順序で出力を取得するtee保証がないことを意味します。wc

おすすめ記事