스크립트 배포 : shebang에 / bin / gawk 또는 / usr / bin / gawk를 사용해야합니까? 작동합니다. GNU Awk 매뉴얼에는

gawk가 / bin 또는 / usr / bin에 있습니까? 나는 갈 #!/usr/bin/env gawk것이지만 인수를 사용할 수 없습니다. 지금은을 사용하고 #!/bin/gawk -f있습니다. 스크립트는 매우 길며 많은 작은 따옴표를 포함하고 stdin과 함께 작동합니다.

GNU Awk 매뉴얼에는 1.1.4 절의 실행 가능한 awk 프로그램 섹션이 있습니다. 여기서는 예제에서 #! / bin / awk를 사용하지만 다음과 같이 말합니다.

많은 시스템 awk에서에서 /usr/bin대신에 시스템을 찾을 수 있습니다 /bin. Caveat Emptor.

대부분의 사람들은 무엇을합니까? 필자는 sed가 / bin에서 표준화 된 것으로 가정하고 perl은 / usr / bin에서 표준화 된 것으로 가정합니다 (sed 링크와 동일한 페이지이지만이 게시물의 세 번째 링크를 만들 수는 없습니다). awk / gawk는 어떻습니까? 누구가 더 흔하거나 인기가 있는지 알고 있습니까?



답변

Shebang은 그처럼 유연 할 수 없었습니다 . 두 번째 매개 변수가있는 경우가있을 수 있습니다 .FreeBSD가 그중 하나라고 생각합니다.

gawk 및 OS와 함께 제공되는 대부분의 유틸리티는에있을 것으로 예상됩니다 /usr/bin/.

이전의 유닉스 시절에는 /usr/로컬 디스크 공간과 워크 스테이션 당 비용을 절약하기 위해 NFS 나 저렴한 미디어를 통해 마운트 하는 것이 일반적이었습니다 . 단일 사용자 모드/bin/ 로 부팅하는 데 필요한 모든 것이 있어야 합니다 . /usr/신뢰할 수있는 미디어에 마운트되지 않았기 때문에 /bin/일반적인 관리 및 문제 해결에 충분히 사용할 수 있도록 충분한 유틸리티가 포함되었습니다.

이것은 초기에 Linux에서 상속되었지만 디스크 공간은 더 이상 문제가되지 않으며 대부분의 경우 /usr/루트 파일 시스템에 있으므로 현재는 /usr/bin(최소한 Linux 환경에서) 모든 것을 이동시키는 경향이 있습니다. 따라서 배포판으로 설치된 대부분의 유틸리티가 여기에 있습니다. 심지어 가장 기본적인 유틸리티, 같은 cp, rm, ls등 (물론, 아직).

shebang 선택에 관해서. 일반적으로 관리자 나 사용자는 환경에 따라 편집해야합니다. 개발자가 다른 사람의 시스템에서 알고있는 모든 내용은 인터프리터는 어디서든 파일 시스템에있을 수 있습니다 (예를 들어 /usr/local/bin, /opt/gawk-4.0.1/bin). 올바르게 패키지 된 스크립트 (rpm, deb 등)는 배포 패키지 (예 : 인터프리터에 알려진 위치가 있음)에 대한 종속성 또는 설치 중에 적절한 해시 뱅을 설정하는 구성 스크립트와 함께 제공됩니다.


답변

명령에 인수를 전달할 필요가 없다면 #!/usr/bin/env gawk갈 길이지만 Linux를 포함한 많은 커널은 shebang 프로그램에 단일 인수 만 허용합니다.

그렇지 않으면 쉘 랩퍼 및 awk 스크립트 인 폴리 글롯 프로그램을 작성할 수 있습니다 . 여기에 awk가 있습니다.

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

쉘 파싱 :

  • true + /;true두 개의 비활성 인수가 있는 명령 (아무 것도 수행하지 않음) +/.
  • 에 대한 호출 gawk입니다. 이것은 개행 문자를 포함하지 않고 슬래시가 쓰여지는 쉘 스 니펫 일 수 있습니다 \/(쉘은 따옴표를 제외하고는 신경 쓰지 않습니다).
    이 호출은 execgawk를 서브 프로세스로 실행하는 대신 쉘을 gawk로 교체하는 데 사용 됩니다.
  • exit;— gawk를 찾을 수없는 경우 쉘을 종료하십시오. 쉘이 실행하기 전에 전체 행을 구문 분석하려고 시도하는 경우에 유효한 쉘 구문이어야한다는 점을 제외하고 그 이후의 모든 것은 무시됩니다.

awk 파싱 :

  • 슬래시 사이의 비트는 정규식입니다.
  • true + /REGEX/– 조건. true정의되지 않은 변수이므로 숫자 값은 0이며 중요하지 않습니다.
  • {} — 상기 상태가 유지되면 아무 것도하지 마십시오.

답변

Gilles의 제안 된 솔루션은 실제로 매우 좋은 접근 방식입니다 (마지막으로 자신의 입장에서 투표하는 평판을 얻음).

어쨌든 exec명령을 이해하는 exit한 쉘 프로세스가로 대체 되므로 명령 을 불필요하게하고 실제로 도달 할 수 없게됩니다 awk.

또한 awk스크립트가 호출 매개 변수에 액세스 할 수 있도록 제안 된 솔루션의 일부 변경 사항을 제안합니다.

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

-a "$0"그렇지 않으면 항상 얻을 것이다, 그 호출 이름에 액세스 할 수 있도록 스크립트를 허용 awk하거나 gawk액세스하는 경우 ARGV[0]변수를. 마찬가지로, "$@"스크립트가 ARGV[1...N]배열 의 나머지 매개 변수에 액세스 --할 수있게하고 앞의 스크립트 -<something>는이를 해석하지 않고 스크립트가 인수 를 수신 할 수 있도록 합니다.

기억해야 할 한 가지는 스크립트 프로그램 exit(0);BEGIN { ... }블록 끝에 명령문 을 추가하는 것입니다 awk. 그렇지 않으면 awk입력 파일로 스크립트에 전달 된 모든 매개 변수가 위협됩니다. ( exit우리가 true + ...줄 에서 제거한 문장으로 는 아무 것도 할 수 없다는 점에 유의하십시오 . 이 제안 된 종료는 awk 코드에 있지만 도달 할 수없는 쉘 문장이었습니다.