Bash 변수 입력 중 통신 실패

Bash 변수 입력 중 통신 실패

두 디렉터리에서 파일 목록을 가져와서 차이점을 파악하고 특정 파일에 대해 일부 코드를 실행하는 스크립트가 있습니다.

다음은 파일 목록을 가져오는 명령입니다.

list_in=$(find input/ -maxdepth 1 - type f | sed 's/input\///' | sort -u);
list_out=$(find output/ -maxdepth 1 - type f | sed 's/output\///' | sort -u);

올바른 디렉터리에서 스크립트를 실행 중이므로 실패해서는 안 됩니다. 처리되지 않은 파일은 다음에 의해 결정됩니다.

list_todo=$(comm -23 <(echo "$list_in") <(echo "$list_out"));

옵션은 -23comm번째 인수에 대한 행만 인쇄하므로 해당 행은 두 인수 모두에 표시되지 않으며 두 번째 인수에 고유하게 나타나는 행은 인쇄되지 않습니다.

그러나 가끔 오류 메시지가 나타납니다.

command substitution: line 3: syntax error near unexpected token `('
command substitution: line 3: `comm -23 <(echo "$list_in") <(echo "$list_out")'

지난 3주 동안 똑같은 스크립트가 제대로 작동했기 때문에 이것은 나를 정말 혼란스럽게 합니다. 나는 이것을 클러스터에서 사용하고 있으므로 여러 프로세스가 동시에 스크립트를 실행할 수 있습니다. 이로 인해 오류가 발생할 수 있습니까?

고쳐 쓰다. 스크립트는 via로 호출되며 ./script분명히 이전에 설정했습니다 chmod +x script.

(면책조항: 클러스터에서 작업 중이고 스크립트의 처음 세 줄에 잠금 메커니즘이 포함되어 있지 않더라도 파일은 두 번 처리되지 않습니다.)

답변1

커널은 기본적으로 실행될 수 있는 특정 파일 형식을 인식합니다. 여기에는 하나 이상의 이진 형식이 포함됩니다. 게다가 #!(셰르본)은 스크립트로 처리됩니다. 예를 들어 파일이 에 있고 /path/to/script로 시작하는 경우 호출할 때 커널이 실행됩니다 #!/bin/bash./bin/bash /path/to/script arg1 arg2/path/to/script arg1 arg2

커널이 파일 형식을 인식하지 못하면 파일에서 ENOEXEC(Execution Format Error)가 반환됩니다.execve시스템 호출. Shebang 기능이 없는 Unix 커널의 고대 전통에 따라 대부분의 프로그램은 ENOEXEC 오류와 함께 첫 번째 시도가 실패할 때 프로그램을 다시 실행하려고 시도합니다. 즉, /bin/sh스크립트 인터프리터로 실행을 시도합니다.

Bash는 주목할 만한 예외입니다. Bash는 NET이 아닌 자체적으로 스크립트를 실행합니다 /bin/sh. 따라서 Bash에서 호출하면 스크립트가 예기치 않게 작동합니다.

shebang 줄을 생략하면 스크립트를 실행하는 프로그램에 따라 스크립트가 /bin/bash아래 또는 아래에서 실행될 수 있습니다. /bin/sh그리고 /bin/sh분명히 시스템의 프로세스 교체는 지원되지 않습니다. 여전히 bash일 수 있지만(오류 메시지는 bash의 오류 메시지처럼 보임) 이름으로 bash를 호출하면 sh프로세스 대체를 지원하지 않는 POSIX 호환 모드로 전환됩니다.

이야기의 교훈은 다음과 같습니다. bash 스크립트를 작성하려면 이를 #!/bin/bash첫 번째 줄에 배치해야 합니다.

답변2

$() 및 <() 구성은 bash에서만 작동합니다. 이는 shebang 줄을 다음과 같이 설정해야 함을 의미합니다.

#!/bin/bash

특히 이것은 것입니다아니요일하다:

#!/bin/sh

작동하기 위해 필요한 경우 sh$() 대신 `를 사용할 수 있습니다.

list_in=`find input/ -maxdepth 1 - type f | sed 's/input\///' | sort -u`

<() 대신 mkfifo를 사용할 수 있습니다.

관련 정보