[shell] shebang (예 : #!)과 함께 awk에 여러 인수를 사용하는 방법은 무엇입니까?

shebang 을 사용하여 gawk 스크립트 를 실행하고 싶습니다 --re-interval. “순진한”접근 방식

#!/usr/bin/gawk --re-interval -f
... awk script goes here

gawk가 첫 번째 인수 "--re-interval -f"(공백 주위로 분할되지 않음 )로 호출 되었기 때문에 작동 하지 않습니다. 이에 대한 해결 방법이 있습니까?

물론 gawk를 직접 호출 할 수는 없지만 첫 번째 인수를 분할하는 쉘 스크립트로 래핑하거나 gawk를 호출하고 스크립트를 다른 파일에 넣는 쉘 스크립트를 만들 수 있지만, 할 방법이 있는지 궁금합니다. 이것은 하나의 파일 내에 있습니다.

shebang 라인의 동작은 시스템마다 다릅니다. 적어도 Cygwin 에서는 인수를 공백으로 분할하지 않습니다. 나는 그저 그렇게 동작하는 시스템에서 그것을 어떻게하는지에 관심이 있습니다. 스크립트는 이식 할 수 없습니다.



답변

이것은 (g) awk와 함께 작동하는 것 같습니다.

#!/bin/sh
arbitrary_long_name==0 "exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"


# The real awk program starts here
{ print $0 }

#!실행에 유의하십시오. 따라서이 /bin/sh스크립트는 먼저 쉘 스크립트로 해석됩니다.

처음에는 간단히 시도 "exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"했지만 awk는이를 명령으로 처리하고 모든 입력 행을 무조건 인쇄했습니다. 그것이 내가 넣은 이유 arbitrary_long_name==0입니다. 항상 실패해야합니다. 횡설수설 문자열로 바꿀 수 있습니다. 기본적으로, 쉘 스크립트에 악영향을 미치지 않는 awk의 잘못된 조건을 찾고있었습니다.

쉘 스크립트에서 arbitrary_long_name==0변수가 호출을 정의 arbitrary_long_name하고 세트가 같음 =0.


답변

shebang 라인은 POSIX, SUS, LSB 또는 기타 사양의 일부로 지정되지 않았습니다. AFAIK, 제대로 문서화되지도 않았습니다.

사이 모든 것을 가지고 : 그것은 무엇을하는지에 대한 대략적인 합의가 !\nexec그것. 가정은 사이의 모든 것 !하고는 \n인터프리터에 전체 절대 경로입니다. 공백을 포함하면 어떤 일이 발생하는지에 대한 합의가 없습니다.

  1. 일부 운영 체제는 단순히 전체를 경로로 취급합니다. 결국 대부분의 운영 체제에서 공백이나 대시는 경로에서 합법적입니다.
  2. 일부 운영 체제는 공백으로 분할되어 첫 번째 부분을 인터프리터의 경로로 취급하고 나머지는 개별 인수로 취급합니다.
  3. 일부 운영 체제는 첫 번째 공백 에서 분할되어 앞 부분을 interpeter의 경로로 취급하고 나머지 부분은 단일 인수로 취급합니다 (이는 여러분이보고있는 것입니다).
  4. 일부는 심지어 shebang 라인 을 전혀 지원하지 않습니다 .

고맙게도 1.과 4.는 사라진 것처럼 보이지만 3.은 꽤 널리 퍼져 있으므로 둘 이상의 인수를 전달할 수 있다는 것에 의존 할 수 없습니다.

명령의 위치도 POSIX 또는 SUS에 지정되지 않기 때문에, 당신은 일반적으로 실행 파일의 전달하여 하나의 인자 것을까지 사용할 이름env수 있도록 그것을 실행 파일의 위치를 확인할 수 있습니다; 예 :

#!/usr/bin/env gawk

[분명히 이것은 여전히에 대한 특정 경로를 가정 env하지만이 위치에있는 시스템이 거의 /bin없으므로 일반적으로 안전합니다. 의 위치는 또는 또는 같은 env위치보다 훨씬 더 표준화되어 있습니다 .]gawkpythonrubyspidermonkey

어떤 당신이 실제로 사용할 수 없음을 의미 있는 인수를 전혀 .


답변

정확하게 이식 할 수는 없지만 coreutils 8.30부터 설명서에 따라 다음을 사용할 수 있습니다.

#!/usr/bin/env -S command arg1 arg2 ...

그래서 주어진 :

$ cat test.sh
#!/usr/bin/env -S showargs here 'is another' long arg -e "this and that " too

당신은 얻을 것이다 :

% ./test.sh
$0 is '/usr/local/bin/showargs'
$1 is 'here'
$2 is 'is another'
$3 is 'long'
$4 is 'arg'
$5 is '-e'
$6 is 'this and that '
$7 is 'too'
$8 is './test.sh'

그리고 당신이 궁금한 경우 showargs:

#!/usr/bin/env sh
echo "\$0 is '$0'"

i=1
for arg in "$@"; do
    echo "\$$i is '$arg'"
    i=$((i+1))
done

여기에 원래 답변 .


답변

나는 공백이 shebang에서 처리되는 방식 (적어도 Linux에서) 때문에 명백한 해결책이없는 동일한 문제를 발견했습니다.

그러나 짧은 옵션 이고 연결될 수있는 한 (GNU 방식) shebang에서 여러 옵션을 전달할 수 있습니다 .

예를 들어, 당신은 가질 수 없습니다

#!/usr/bin/foo -i -f

하지만 당신은 가질 수 있습니다

#!/usr/bin/foo -if

분명히 그것은 옵션에 짧은 등가물이 있고 인수가 없을 때만 작동합니다.


답변

Cygwin과 Linux에서는 shebang 경로 이후의 모든 것이 하나의 인수로 프로그램에 구문 분석됩니다.

awkshebang 내부에 다른 스크립트 를 사용하여이 문제를 해킹 할 수 있습니다 .

#!/usr/bin/gawk {system("/usr/bin/gawk --re-interval -f " FILENAME); exit}

이것은 {system("/usr/bin/gawk --re-interval -f " FILENAME); exit}awk에서 실행 됩니다.
그리고 이것은 /usr/bin/gawk --re-interval -f path/to/your/script.awk시스템 쉘에서 실행 됩니다.


답변

#!/bin/sh
''':'
exec YourProg -some_options "$0" "$@"
'''

위의 쉘 shebang 트릭은 /usr/bin/env.


답변

gawk 매뉴얼 (http://www.gnu.org/manual/gawk/gawk.html)에서 섹션 1.14의 끝 부분에서는 shebang 라인에서 gawk를 실행할 때 단일 인수 만 사용해야한다는 점에 유의하십시오. OS는 gawk 경로 이후의 모든 것을 단일 인수로 취급한다고 말합니다. --re-interval옵션 을 지정하는 다른 방법이 있습니까? 아마도 스크립트는 shebang 줄에서 쉘을 참조 gawk하고 명령으로 실행 하고 스크립트 텍스트를 “here document”로 포함 할 수 있습니다.