bash, 리디렉션 루프에서 돌아오는 중, 안전합니까?

bash, 리디렉션 루프에서 돌아오는 중, 안전합니까?

리디렉션된 루프에서 돌아옵니다.

"파일"의 쓰기 버퍼에 대해 걱정해야 하는지 모르겠습니다.

function f {
    i=1
    while :
    do
        echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb
        ((i++))
        if [ $i -gt 3 ]
        then
            return    # return while redirected
        fi
    done >> file    # writing to file
}

f

참고: 이 함수는 리디렉션 루프에서 반환되지 않도록 쉽게 다시 작성할 수 있다는 것을 알고 있습니다. 그러나 이는 이 질문의 목적을 위한 단순화된 예일 뿐입니다.

그러니 개선하려고 하지 마세요.이것암호.

나는 해결책에도 관심이 없습니다.

내 유일한 질문은 내가 특별히 알아야 할 것이 있습니까? 파일 설명자가 제대로 닫히지 않은 것 같습니다. 또는 때로는 버퍼의 절반(예: "aaaaaa")만 파일에 기록될 것으로 예상할 수 있습니다.

이것이 정말 나쁜 생각인지, 그리고 그 이유가 무엇인지 궁금합니다. 아니면 예상치 못한 경쟁 조건이나 이와 유사한 상황 없이 작동할 수도 있나요? (하지만 또 "이거, 이 패턴을 써야하니까 이건 나쁘다" 같은 대답은 원하지 않는다.)

답변1

bash에 내장된 명령(또는 내장 여부에 관계없이 동일한 명령을 두 번 호출하는 경우)에도 각 명령에는 자체 쓰기 버퍼가 있을 수 있지만 명령 간에 공유 쓰기 버퍼는 없습니다.

ksh93이 일부 I/O 최적화를 수행하는 것으로 알려져 있음에도 불구하고(예: 미리 읽고 일부 데이터를 공유함)입력하다(약간의 오류가 발생함)), 이러지 마세요.

따라서 그런 점에서는 안전합니다. 명령이 완료되면(예: yours echo aaaaaaaaaaaaabbbbbbbbbbbbbbbbb) 백그라운드에서 실행 중인 무인 프로세스를 분기하지 않는다고 가정하면 모든 I/O가 완료되는 것이 보장됩니다.

하지만 몇 가지 주의 사항이 있습니다. 다음과 같은 함수에서:

f() {
  {
    echo x
    return
    echo y
  } > file
  echo something else
}

Bourne 쉘(및 Bourne 쉘에만 해당)에서는 return내부 명령 그룹의 출력이 손상되지만 고대 쉘에서와 같이 함수에서 반환되는 대신 명령 그룹은 리디렉션으로 인해 하위 쉘에서 실행됩니다(그래서 당신은 볼 것이다 something else).

이와 같은 최신 쉘에서는 이런 일이 더 이상 발생하지 않지만 bash다음과 같이 작성하면 bash에서도 동일한 문제가 발생합니다.

f() {
  (
    echo x
    return
    echo y
  ) > file
  echo something else
}

또는

f() {
  {
    echo x
    return
    echo y
  } | tr xy ab
  echo something else
}

특정 명령이 기다리지 않는 상황이 있다는 점에 유의하세요. 존재하다:

f() {
  {
    echo >(sleep 1; echo x)
    return
  } > file
}
f; cat file

이전에 실행되었기 x때문에 표시되지 않을 수도 있습니다 .catecho x

일부 셸(은 아니지만 bash)은 파이프라인 구성 요소와 유사한 잠재적인 문제를 가지고 있습니다(가장 오른쪽 항목 제외).

관련 정보