tee는 Bash 스크립트에서 잘못된 순서로 출력을 표시합니다.

tee는 Bash 스크립트에서 잘못된 순서로 출력을 표시합니다.

나는 특정 디렉토리에서 (스크립트에 대한 인수로) 여러 작업을 수행해야 하는 대학 과제를 위한 bash 스크립트를 작성하고 있습니다.

  1. 특정 권한이 있는 모든 파일/디렉터리 표시(권한은 8진수 형식의 인수로 제공됨)
  2. 지난 x일 동안 수정된 파일을 디렉토리 트리에 표시합니다(x는 매개변수).
  3. 지난 x일 동안 방문한 트리의 하위 디렉터리를 표시합니다. (x는 위에서 사용된 것과 동일한 매개변수입니다.)
  4. 디렉토리의 모든 파이프/소켓 유형 파일 표시
  5. 하위 디렉터리가 아닌 디렉터리의 모든 빈 파일 표시

각 작업이 끝나면 스크립트는 발견된 파일(또는 하위 디렉터리) 수도 표시해야 합니다.

이 명령을 사용하여 원하는 출력을 인쇄하고 있습니다.(예: 작업 1):echo "$files_perms" | tee >(echo "Files found: $(wc -l)")

문제는 tee첫 번째와 두 번째 작업 후에 출력이 올바른 순서로 표시되지 않는다는 것입니다.

첫 번째 작업(출력 정상):

두 번째 작업(출력은 여전히 ​​정상):

세 번째, 네 번째 및 다섯 번째 작업(출력이 잘못되었습니다. 화살표는 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 에 사용되는 디렉터리 인수입니다 $3.lsfind

스크립트 실행 예:bash labscript2.sh 755 8 /home/na-no

출력이 올바른 순서로 표시되지 않는 이유는 무엇입니까( tee각 / 명령 및lsfind아니요여러 줄 뒤에)?

답변1

동시에 여러 개의 동시 프로세스가 실행되고 있습니다. 출력 순서는 먼저 쓰는 프로세스에 따라 달라집니다.

예를 들어, 네 번째는 tee출력 쓰기를 시작한 것으로 보이지만 세 번째는 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위의 세 번째 줄이 출력됩니다.

3b
3c
3

즉 , other output 이후에 stdout작성된 것 같습니다. 이는 예상한 순서대로 출력을 얻을 tee것이라는 보장이 없음을 의미합니다 .wc

관련 정보