일부 명령에서 BASH 프로세스 대체가 작동하지 않는 이유는 무엇입니까?


29

때때로 프로세스 대체가 예상대로 작동하지 않습니다. 예를 들면 다음과 같습니다.

입력:

gcc <(echo 'int main(){return 0;}')

산출:

/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status

입력:

그러나 다른 명령과 함께 사용하면 예상대로 작동합니다.

grep main <(echo 'int main(){return 0;}')

산출:

int main(){return 0;}

다른 명령과 유사한 실패를 발견했습니다 (즉, 프로세스 대체에서 파일을 기대하는 명령은 사용할 수 /dev/fd/63없거나 유사합니다). 이 실패 gcc는 가장 최근의 것입니다. 프로세스 대체가 언제 이런 식으로 실패하고 사용되어서는 안되는지 결정하기 위해 알아야 할 일반적인 규칙이 있습니까?

우분투 12.04 에서이 BASH 버전을 사용하고 있습니다 (아치 및 데비안에서도이를 보았습니다) :
GNU bash, 4.3.11 (1) -release (i686-pc-linux-gnu)


1
illegal seek대답과 같은 모습 일 - |pipebash에 실행 된 프로그램의 포인트는 시크 파일이 아닙니다. 아마도 echo data | command /dev/fd/0프로그램에서 성공적으로 수행 할 수 없다면 비슷한 행운을 얻습니다 <(cmd). 디스크 파일을 제공하지 않습니다. 파이프 파일 디스크립터를 가리키는 인수 만 대체합니다.
mikeserv

2
이 경우 gcc 표준 입력을 받아 들일 있지만 기본적으로 파일 이름 확장자를 사용하여 언어를 결정합니다. 따라서 gcc -xc <(echo 'int main(){return 0;}')언어를 C명시 적으로 설정하십시오 .
steeldriver

나는 내 자신의 질문에 대한 응답으로 여기에 지시되었으며, 이것의 또 다른 예가 될 것 같습니다. superuser.com/questions/1243405 . 내가 할 수 있었던 것보다 질문을 더 잘 표현해 주셔서 감사합니다.
Jonathan Hartley

답변:


33

프로세스 대체 /dev/fd/63는 명명 된 파이프의 읽기 끝과 같이 작동 하는 특수 파일 ( 예 : 예)을 생성합니다. 이 파일은 열고 읽을 수는 있지만 검색 할 수는 없습니다.

인수를 순수 스트림으로 취급하는 명령은 작동하지만 파일에서 탐색하거나 파일에 쓰려고하는 명령은 작동하지 않습니다. : 의지 작업은 일반적으로 필터 간주되는 것을 명령의 종류 cat, grep, sed, gzip, awk, 등 ...없는 일이 같은 편집기입니다하는 명령의 예 vi또는 같은 파일 작업 mv.

gcc입력 파일에 대해 임의 액세스를 수행하여 작성된 언어를 감지 할 수 있기를 원합니다. 대신 gcc입력 파일의 언어에 대한 힌트 를 제공 하면 파일을 스트리밍 할 수 있습니다.

gcc -x c <(echo 'int main(){return 0;}')

프로세스 대체가없는 더 간단한 형태도 작동합니다.

echo 'int main(){return 0;}' | gcc -x c -

이 내용은 특정하지 않습니다 bash. 프로세스 대체를 지원하는 모든 쉘은 동일한 방식으로 작동합니다.


gcc 해결 방법은 +1이지만 파일과 관련된 요점을 잘 모르겠습니다. <()형식은 모든 의도와 목적을 위해 파일처럼 행동해야한다. 사실, 나는 만족스럽지 않은 파일을 기대하는 명령을 모른다 <(). 작동하지 않는 것은 파일이 아닌 파일 이름 을 기대하는 것 입니다. 예를 들어, grep -f파일을 예상하고 잘 작동합니다 <().
terdon

4
@terndon 확실히 <()파일 이름을 생성합니다 (구문은 /proc/self/fd/something시스템에서 확장됩니다 ). 열 때이 이름은, 명명 된 파이프 (의 읽기 끝 같은 역할 S_IFIFO)이 아닌 일반 파일 ( S_IFREG즉 지원합니다에) read()다른 사람이 아닌 seek().
Celada

7
zsh그 목적을 위해 임시 파일을 사용하는 세 번째 형태의 프로세스 대체 를 지원합니다.gcc =(echo 'int main(){return 0;}')
Stéphane Chazelas

아마 관련 이 있지만 작동하지만 작동 <(echo '...')하지 않습니다 <(git show ...). 왜 그런지 알 수 있습니까?
Jörn Hees 2016 년

2
GCC는 "입력 파일에 대한 임의 액세스를 수행하여 작성된 언어를 감지하지 않습니다". 파일 이름의 확장자 만 봅니다. 파일 이름에 확장자가 없거나 (또는 ​​인식되지 않는 확장자가있는 경우) GCC는 파일이 객체 파일 또는 링커 스크립트 인 것으로 가정하여 파일 ld형식을 감지합니다. -x힌트가 아닙니다. 선언입니다. 을 지정 -x f95하면 GCC는 이름이나 내용에 관계없이 파일을 Fortran-95 컴파일러로 전달합니다. 참조 gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overall-Options.html
RICI
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.