MacO에서 동일한 프로세스 대체 파일에 반복적으로 쓰기

MacO에서 동일한 프로세스 대체 파일에 반복적으로 쓰기

다음 bash-fu 코드는 Linux에서는 잘 실행되지만 MacOS에서는 충돌이 발생합니다.

files="foo bar"

echo PROG 1
for file in $files
do
  echo $file | tee -a tempfile.txt
done

sort -u tempfile.txt

echo PROG 2
function trick {
  for file in $files
  do
    echo $file | tee -a $1
  done
}

trick >(sort -u)

오류는 다음과 같습니다

PROG 1
foo
bar
bar
foo
PROG 2
tee: /dev/fd/63: Bad file descriptor
foo
tee: /dev/fd/63: Bad file descriptor
bar

Linux에서도 PROG 2동일한 줄이 PROG 1오류 없이 작성됩니다. MacOS에서는 파이프 핸들이 닫혀 있거나 상속되지 않은 것처럼 보입니다.

위의 내용은 문제를 재현하는 최소한의 예입니다. 사실 저는 연결 출력과 리디렉션 핸들을 많이 다룹니다. 뭔가 영적인 것

function trick {
  for file in $files
  do
     echo $file | tee -a $1 | grep -Eo "^.."
  done
}

trick >(sort -u | sed 's|o|x|g')

이 코드는 Bash 4.1에서는 실행되지 않지만 여러 배포판(Arch, Ubuntu 및 Debian)의 Bash 4.4에서는 작동합니다.

답변1

macOS는 매우 오래된 버전과 함께 제공됩니다 bash. 버그(프로세스에 의해 대체된 파일 설명자가 tee이 컨텍스트에서 호출되기 전에 닫혔음)가 최신 버전에서 수정되었습니다. Linux에서 /dev/fd/xbash 3.2를 사용할 때 동일한 문제(구현이 다르기 때문에 다른 오류 메시지가 표시됨)가 발생합니다 .

zsh여기에서는 or를 대신 사용할 수 있습니다 ksh93. bash아무튼 여기는 피하는 게 좋은 것 같아요.프로세스 교체 중 프로세스를 기다리지 않습니다.(zsh가 이를 기다리고 있으며 ksh93에 알릴 수 있습니다 wait).

최신 버전(작성 당시 4.4.12)에도 bash여전히 다음과 같은 몇 가지 버그가 있습니다.

$ bash -c 'eval cat <(echo test)'
test # OK but:
$ bash -c 'eval "echo foo;cat" <(echo test)'
foo
cat: /dev/fd/63: No such file or directory
$ bash -c 'eval f=<(echo test) "; cat \$f"'
cat: /dev/fd/63: No such file or directory

일부는 여전히 다음과 같은 파이프에 의해 트리거됩니다.

$ cat file
echo "$1"
cat "$1"
$ bash -c 'source ./file <(echo test)'
/dev/fd/63
test  # OK but:
$ cat file2
echo "$1" | wc -c
cat "$1"
$ bash -c 'source ./file2 <(echo test)'
11
cat: /dev/fd/63: No such file or directory

1 파이프가 존재하면 bash는 파일 설명자를 닫습니다. 더 짧은 재생기:

$ bash -c 'f() { :; cat "$1"; }; f <(echo OK)'
OK
$ bash -c 'f() { :|:; cat "$1"; }; f <(echo test)'
cat: /dev/fd/63: No such file or directory

관련 정보