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 1MacOS에서는 파이프 핸들이 닫혀 있거나 상속되지 않은 것 같습니다.

위의 내용은 문제 재현을 위해 최소화된 샘플입니다. 실제로 저는 연결 출력과 리디렉션된 핸들을 모두 많이 처리합니다. 뭔가의 정신으로

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) 1이 최신 버전에서 수정되었습니다. /dev/fd/xbash 3.2를 사용하면 Linux에서도 동일한 문제가 발생합니다(다른 방식으로 구현된 것과 다른 오류 메시지 포함 ).

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

¹ 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

관련 정보