정렬 <(ls -l)`은 작동하지만 정렬 <(ls -l)`은 왜 실패합니까?


33

오늘은이 기사 FIFO에 대해 뭔가를 배우고 : 소개 명명 된 파이프에 언급, cat <(ls -l).

을 사용하여 몇 가지 실험을 sort < (ls -l)했는데 오류가 발생합니다.

-bash: syntax error near unexpected token `('`

그런 다음 명령에 여분의 공간을 잘못 추가했습니다.

그러나 왜이 추가 명령이 실패로 이어질까요? 리디렉션 기호가 (?


* nix 쉘은 공백을 기준으로 항목을 분할하여 Alec이 언급 한 토큰을 생성합니다.
병아리

답변:


46

<그것이 아니기 때문에 <()완전히 다른 것입니다. 이것을 프로세스 대체 라고 하며 특정 쉘의 기능으로 한 프로세스의 출력을 다른 프로세스의 입력으로 사용할 수 있습니다.

><연산자에서 출력 및 입력 리디렉션 파일을 . <()운영자는, 파일이 아닌 명령 (프로세스)를 다룬다. 달릴 때

sort < (ls)

ls서브 쉘 에서 명령을 실행 (괄호가 의미하는 것) 한 다음 해당 서브 쉘을 입력 파일로에 전달하려고합니다 sort. 그러나이 구문은 허용되지 않으며 사용자가 본 오류가 발생합니다.


3
당신의 대답은 좋지만 then sort is attempting to read the subshell as its input fileBash는 구문을 파싱하지 않기 때문에 → 이것은 분명히 잘못되었습니다. 실제로도 실행 되지 ls않습니다 sort.
sleblanc

1
@sebleblanc 페어 포인트, 답변을 고맙게 생각합니다.
terdon

1
이 경우 하위 셸이 없습니다. < (ls)유효한 토큰이 아닙니다.
cuonglm

bash는 구문 오류로 처리하므로 @cuonglm no입니다. 내 요점은 그것이 서브 쉘에서 (ls)실행될 것이라는 점이다 ls.
terdon

22

그것이 의도 된 방식이기 때문입니다.

<(...)in bash은 프로세스 대체 구문입니다. 의 동일한 연산자에서 복사되었습니다 ksh.

<, (, ), |, &, ;특수 어휘 토큰입니다 bash서로 다른 조합으로 특별한 연산자를 형성하는 데 사용됩니다. <, <(, <<, <&... 각각 자신의 역할을한다. <리디렉션을위한 것입니다. <file, < file파일에서 입력을 리디렉션합니다. <'(file)'이라는 파일에서 입력을 리디렉션 (file)하지만 <(file)리디렉션 연산자가 아닌 다른 연산자입니다.

< (file)<다음에 (file). 그런 맥락에서,에서 bash, (file)유효하지 않습니다. (...)다음과 같은 일부 상황에서 단일 토큰으로 유효 할 수 있습니다.

(sub shell)
func () {
  ...
}
var=(foo bar)

그러나

sort < (cmd)

에서 fish쉘, 그것은 다릅니다. 이어 fish, (...)명령 대체 (동등위한 $(...)에서 bash). 그리고 <본쉘처럼 입력 리디렉션을위한 것입니다.

그래서 fish:

sort <(echo file)

다음과 같습니다.

sort < (echo file)

그건:

sort < file

그러나 그것은 bash프로세스 대체와 완전히 다른 것 입니다.

에서 yash쉘 다른 POSIX 쉘 <(...)위해없는 프로세스 교체 되지만위한 프로세스 재

거기에,

sort <(ls -l)

짧게 :

sort 0<(ls -l)

리디렉션 연산자입니다. 다음과 다소 비슷합니다.

ls -l | sort

에있는 동안 bash은이 <(ls -l)때문에 더 많은처럼, 파이프의 경로로 확장됩니다

ls -l | sort /dev/fd/0

에서 zsh, (...)글 로빙 연산자 오버로드 ( (*.txt|*.png)로 확장 할 txtpng과 (글로브 규정 자로 파일) *(/)디렉토리 파일에 인스턴스가 확장 용).

에서 zsh의 :

sort < (ls -l)

그것은 (ls -l)glob 한정자로 취급 될 것입니다. l링크의 수에 일치하는 것입니다 후 번호를 기대 예선 글로브 l(같이하는 것은 ls -ld ./*(l2),이 개 링크가있는 파일을 나열 것이다) 그래서 당신이 얻는 이유의 zsh: number expected오류가.

sort < (w)쓰기 가능한 빈 이름을 가진 파일과 일치하는 zsh: no matches found: (w)대신 오류가 발생 했을 것 (w)입니다.

sort < (w|cat)현재 디렉토리에서 파일 w및 / 또는 cat파일 의 내용을 정렬했을 것입니다 ...


sort < $(ls -l)이 오류를 제공합니다 :bash: $(ls -l): ambiguous redirect
에드워드 토발즈

@edwardtorvalds, $(ls -l)둘 이상의 단어로 확장 되기 때문 입니다. split + glob ( sort < "$(echo file)") 를 방지하려면 따옴표를 사용하십시오 . bashbash는 비 대화식 일 때 (그렇게 호출 될 때가 아니라) 스플릿 + 글로브를 수행한다는 점에서 POSIX sh 의 동작 또는 동작이 다릅니다 sh.
Stéphane Chazelas

를 보면 ls -l | sort /dev/fd/0출력 ls -l이 저장되어 /dev/fd/0있고 sort명령이 그것을 읽고 원하는 출력을 제공 한다고 말할 수 있습니다 . tail -f --retry /dev/fd/0해당 파일을 모니터링하는 데 사용 하고 있지만 출력이 없습니다. 왜? 그 파일을 어떻게 읽을 수 있습니까?
Edward Torvalds

물고기에서는 (foo | psub)입력 프로세스 대체를 달성 하는 데 사용할 수 있습니다 . 출력 프로세스 대체를위한 대체 (ha)는 아직 없습니다.
Zanchey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.