RosettaCode 페이지에서 다음과 같은 종류의 shebang을 발견했습니다.
--() { :; }; exec db2 -txf "$0"
Db2에서도 작동하며 Postgres에서도 마찬가지입니다. 그러나 나는 전체 라인을 이해하지 못합니다.
이중 대시는 SQL에서 주석이며 그 후에 파일 자체를 파일로 전달하는 일부 매개 변수를 사용하여 Db2 실행 파일을 호출합니다. 그러나 괄호, 중괄호, 콜론 및 세미콜론은 어떻습니까? ?
RosettaCode 페이지에서 다음과 같은 종류의 shebang을 발견했습니다.
--() { :; }; exec db2 -txf "$0"
Db2에서도 작동하며 Postgres에서도 마찬가지입니다. 그러나 나는 전체 라인을 이해하지 못합니다.
이중 대시는 SQL에서 주석이며 그 후에 파일 자체를 파일로 전달하는 일부 매개 변수를 사용하여 Db2 실행 파일을 호출합니다. 그러나 괄호, 중괄호, 콜론 및 세미콜론은 어떻습니까? ?
답변:
관련 : 어떤 쉘 인터프리터가 shebang없이 스크립트를 실행합니까?
스크립트에는 #!
이중 대시가 없기 때문에 shebang / hashbang / 행이 없습니다 #!
.
그러나 스크립트는 쉘 (위의 링크 된 질문 및 답변 참조)에 의해 실행되며 해당 쉘 -
에서 함수 이름에 유효한 문자 인 경우 행은 --
아무 것도하지 않는 쉘 함수를 선언합니다 (잘 실행됩니다 :
. 어느 것도 수행하지 않으며 결코 호출되지 않습니다.
더 일반적인 여러 줄 표기법의 함수 (홀수 이름이 실제로 함수라는 사실을 모호하기 때문에 모양을보다 명확하게하기 위해) :
-- () {
:
}
함수 정의의 유일한 목적은 쉘 스크립트에서 유효하고 동시에 유효한 SQL 명령 (주석)을 갖는 것입니다. 이러한 종류의 코드를 폴리 글롯 이라고합니다 .
가짜 쉘 함수를 선언 한 후, 스크립트는 쉘 스크립트 인터프리터에 의해 실행될 때 exec
현재 쉘을 명령 실행에서 스크립트의 경로명에서 db2 -txf "$0"
사용하는 것과 동일한 실행 결과 프로세스로 대체하는 데 사용 됩니다 db2 -txf
.
이 트릭은 이름이 대시를 포함하는 함수를 허용하지 않기 때문에 dash
또는 다른 ash
기반 쉘, yash
Bourne 쉘 ksh88
또는 ksh93
로 사용되는 시스템에서는 안정적으로 작동 /bin/sh
하지 않을 수 있습니다.
또한 관련 :
다음과 같이 작동한다고 가정합니다 (실제 테스트되지는 않음).
--() { exec db2 -txf "$0"; }; --
@ Kusalananda가 이미 말했듯이 그 트릭은 깨졌으며 모든 쉘에서 작동하지는 않습니다.
다음은 이식 가능하게 수행하는 것입니다.
--/.. 2>/dev/null; exec db2 -txf "$0"
첫 번째 명령은 이름 --
이 지정된 파일 / 디렉토리 가 현재 디렉토리에 존재 하더라도 오류가 발생하고 2>/dev/null
; 그런 다음 쉘은 두 번째 명령 인 exec
.
ENOEXEC
시도하면 반환한다는 사실을 해결하기 위해 여전히 호출 쉘에 의존하고 있습니다. 아래에서 스크립트를 실행하여 strace
의미하는 바를 확인하십시오.
exec()
작동하지 않으면 쉘 스크립트로 스크립트를 실행해야 합니다. "[ENOEXEC] 오류와 동등한 오류로 인해 execl () 함수가 실패하면, 쉘은 첫 번째 피연산자 인 명령 이름으로 쉘을 호출하는 것과 동등한 명령을 실행해야합니다 ..." ( pubs.opengroup 참조) .org / onlinepubs / 9699919799.2018edition / utilities /… )
exec()
쉘 이외의 다른 것에서 직접 작동하면 작동하지 않습니다 . 그러나 그 사건은 무엇입니까? 스크립트를 실행하고 싶을 수도 cron
있지만 어쨌든 셸을 통해 모든 것을 실행한다고 생각하지만 그렇지 않은 경우에도 db2 -txf /path/to/script
한 번만 수행하면되므로 철자를 쉽게 입력 할 수 있습니다. 속기 작업은 대화식 쉘에서 주로 유용합니다. 그러나 별도의 래퍼 스크립트가 더 강력 할 수 있습니다.
echo 'int main(int c,char**a){execvp(a[1],a+1);}' | cc -include unistd.h -xc -; echo echo yeah > a.sh; chmod 755 a.sh; ./a.out ./a.sh; PATH=`pwd` ./a.out a.sh