이러한 특수 left<'는 무엇이며 공백이 왜 중요한가요?

이러한 특수 left<'는 무엇이며 공백이 왜 중요한가요?

내가 아는 가장 간단한 것은 <파일 입력을 허용하는 명령인데 grep search-word <filename grep search-word < filename , 이 경우 공백은 중요하지 않습니다.

그러나 두 경우 모두 하나의 구문만 작동하며 다른 곳에 공백을 넣는 것은 작동하지 않습니다.

(gdb) r < <(python -c "print('\x44\x43\x42\x41')")작동 (gdb) r << (python -c "print('\x44\x43\x42\x41')")하지 않습니다. (gdb) r<<(python -c "print('\x44\x43\x42\x41')")작동하지 않습니다.

아니면 여기

sshpass -f <(printf '%s\n' $PASSWORD)작동 sshpass -f < (printf '%s\n' $PASSWORD)하지 않습니다. sshpass -f<(printf '%s\n' $PASSWORD)작동하지 않습니다.

왜 그런 겁니까? 5살짜리 나에게 이것을 설명해 줄 수 있는 사람이 있나요? 감사해요.

답변1

<, <<세 가지가 <(서로 다른 연산자입니다. 연산자 내에 공백이 있을 수 없지만 어떤 경우에는 쉘이 의미를 올바르게 식별하는 데 도움이 되도록 연산자 사이에 공백이 필요합니다.

어휘 분석기의 일반적인 동작은 유효한 연산자를 생성하는 가장 긴 문자 집합을 먹고 해당 연산자를 나타내는 토큰을 파서에 반환하는 것입니다. 그러면 파서는 언어의 실제 문법을 처리합니다.

예를 들어:

  • cat < filename세 개의 토큰 "word cat", "입력 리디렉션 연산자" 및 "word filename"가 생성됩니다.

  • cat << EOF"word cat", "heredoc 연산자", "word EOF"를 생성합니다.

  • cat < < EOFcat4개의 토큰 "word ", "입력 리디렉션 연산자", "입력 리디렉션 연산자", "word " 를 생성 EOF하지만 이는 구문상 의미가 없으며 오류를 생성합니다.

  • cat<filename<문자는 인용되지 않는 한 단어의 일부가 될 수 없으므로 첫 번째 문자와 동일하게 동작하므로 여기서 마크업이 중단됩니다.

마찬가지로 <(프로세스 대체의 시작이지만 < (두 개의 연산자만 있고 <공백 (으로 구분되기 때문입니다. 그리고 가장 긴 접두사 일치로 인해 <<(here-doc 연산자 <<뒤에는 (and가 옵니다.아니요리디렉션 연산자 <뒤에는 프로세스 교체가 시작됩니다. 아마도 이것이 더 유용한 설명일 것입니다.

가장 긴 접두사를 채택하는 행위는 다른 언어에서도 흔히 볼 수 있습니다. 예를 들어 C에서는 i+++a(or)와 마찬가지로 첫 번째 뒤에 공백이 필요합니다. 둘 다 유효한 표현이지만 의미가 다를 뿐입니다. C++에서는 오랫동안 중첩된 템플릿을 로 작성해야 했습니다. 공백이 없으면 템플릿 구문에서 요구하는 두 가지 연산자 대신 관련 없는 오른쪽 이동 연산자로 처리되었기 때문입니다.i ++ + ai++ + ai + ++a+vector<vector<int> >>>>


즉, 마지막 명령은sshpass -f<(printf '%s\n' $PASSWORD) ~해야 한다와 동일하게 작동 cat<filename하며 실제로 저에게 효과적이었습니다.

$ sshpass -f<(echo password) ssh foo@localhost 'echo hi'
hi

set -x실제 명령 실행은 다음과 같습니다 .

sshpass -f/dev/fd/63 ssh foo@localhost 'echo hi'

즉, 프로세스를 보기 전에 파일 이름으로 바꾸십시오 sshpass. 일부 프로그램의 경우 -f foo및 사이에 차이가 있을 수 있지만 -ffoo이는 쉘 연산자가 구문 분석되는 방식과 동일하지 않습니다.

관련 정보