checkbashisms: "type"에 무슨 문제가 있나요?

checkbashisms: "type"에 무슨 문제가 있나요?
#!/bin/sh

foo() {
   echo "in foo"
}

type foo

checkbashisms.pl분명 싫은데 type왜?

$ checkbashisms.pl foo.sh
possible bashism in foo.sh line 7(type):
type foo

POSIX 아닌가요? 하지만 모든 일반 쉘은 이를 지원합니다(예: bash, zsh, dash, busybox sh; mksh심지어 ksh; csh지원하지 않을 수도 있음). 이 경고를 억제할 수 있는 방법이 없나요?

답변1

typePOSIX의 일부, 그러나 X/Open Systems Interface Option(XSI)의 일부입니다.매뉴얼 checkbashisms페이지명시적으로

이 맥락에서 bashism의 정의는 "POSIX 지원이 필요하지 않은 쉘 기능"과 거의 동일합니다. 이는 POSIX의 선택적 부분(예: XSI 또는 사용자 이식성)이 일부 문제를 허용할 수 있음을 의미합니다.

type선택적인 기능이므로 표시됩니다 .

checkbashisms스크립트에서 특정 경고를 제거하는 것 외에는 에서 특정 경고를 비활성화하는 방법을 모르겠습니다.

답변2

고려 command -v foo하거나 command -V foo교체하십시오 type foo. 더 안정적이고 내장될 가능성이 더 높다고 들었습니다.

$PATH실행 파일, 내장 기능, 함수 및 별칭에 대해 테스트 해 보겠습니다 .

#!/bin/sh

foo() {
   echo "in foo"
}
alias bar=foo

for cmd in sed command foo bar; do
  type "$cmd"
  command -V "$cmd"
  command -v "$cmd"
done

출력(사용스프린트0.5.11):

sed is /usr/bin/sed
sed is a tracked alias for /usr/bin/sed
/usr/bin/sed
command is a shell builtin
command is a shell builtin
command
foo is a shell function
foo is a shell function
foo
bar is an alias for foo
bar is an alias for foo
alias bar='foo'

(참고: sed별칭이 아닙니다! 어쩌면 이것은 대시를 의미할 수도 있습니다.해시시명령 위치 테이블? )

Bash에서 실행해 보면 Bash가 비대화형 스크립트에서 별칭을 활성화하지 않기 type때문에 오류가 발생합니다. command -VBash는 또한 주어진 여러 줄에 전체 함수 정의를 표시하는데 command -V, 이는 구문 분석하기가 정말 어렵습니다.

POSIX정의된 command옵션처럼:

-pPATH의 기본값을 사용하여 명령 검색이 수행되므로 모든 표준 유틸리티를 찾을 수 있습니다.

-v쉘이 현재 쉘의 실행 환경에서 사용할 경로 이름이나 명령을 나타내는 문자열을 표준 출력에 씁니다(참조쉘 실행 환경), command_name을 호출하지만 command_name은 호출하지 않습니다.

  • 유틸리티, 일반 내장 유틸리티, 문자가 포함된 command_names 및 PATH 변수를 사용하여 찾은 구현 정의 함수(예:명령어 검색 및 실행)은 절대 경로명으로 작성해야 합니다.
  • 쉘 기능, 특수 내장 유틸리티, PATH 검색과 관련되지 않은 일반 내장 유틸리티, 쉘 예약어 등은 이름 그대로 간단하게 작성해야 합니다.
  • 별칭은 별칭 정의를 나타내는 명령줄로 작성되어야 합니다.
  • 그렇지 않으면 출력이 작성되지 않으며 종료 상태에 이름을 찾을 수 없다는 내용이 반영되어야 합니다.

-V현재 쉘 실행 환경에서 command_name 피연산자에 제공된 이름을 해석하는 방법을 쉘에 지시하는 문자열을 표준 출력에 기록합니다(참조쉘 실행 환경), 그러나 command_name은 호출되지 않습니다. 이 문자열의 형식은 지정되지 않았지만 다음 범주 중 command_name이 속하는 범주를 나타내야 하며 설명된 정보를 포함해야 합니다.

  • 유틸리티, 일반 내장 유틸리티 및 PATH 변수를 사용하여 찾은 구현 정의 함수(예:명령어 검색 및 실행)로 식별되어야 하며 문자열에 절대 경로 이름을 포함해야 합니다.
  • 다른 쉘 기능은 기능으로 식별되어야 합니다.
  • 별칭은 별칭으로 식별되어야 하며 해당 정의는 문자열에 포함되어야 합니다.
  • 특수 내장 유틸리티는 특수 내장 유틸리티로 식별되어야 합니다.
  • PATH 검색과 관련되지 않은 일반 내장 유틸리티는 일반 내장 유틸리티로 식별되어야 합니다. ("정규"라는 용어를 사용할 필요는 없습니다.)
  • 쉘 예약어는 예약어로 표시되어야 합니다.

쉘 스크립트를 작성할 때 정의된 출력이 있는 세 가지 중 유일한 것이기 때문에 or command -v대신 사용하는 것이 좋습니다 . 그런 다음 대부분의 스크립트는 명령이 있는지 확인할 때 출력을 완전히 무시하는 자동 도우미 함수를 통해 이를 호출합니다.typecommand -V

we_have() { command -v "$1" >/dev/null 2>&1; }

if we_have obscure-command; then
  osbcure-command …
fi

답변3

이 명령은 1984년 이후부터 포함되지 type않았습니다 .bashismUNIX

그러나 기본적인 호환성만 제공하는 소규모 임베디드 플랫폼을 사용하는 경우 이 type명령이 존재하지 않을 수 있습니다.POSIX

자체적으로 -platform을 호출하는 플랫폼을 사용하는 경우 지원하려면 -platform이 필요 하므로 UNIXtype명령은 필수입니다.UNIX모두XSI표준에 언급된 소위 개선 사항 POSIX.

소규모 임베디드 시스템에서도 지원해야 하는 준유사한 명령을 찾고 있다면 다음을 사용하는 것이 좋습니다.

command -V foo

대신에. 대문자 -V 옵션은 command유사하지만 반드시 동일하지는 않은 출력을 인쇄합니다 type.

또한 참고: 표준은 command -Vfrom 또는 from의 출력 형식을 정의하지 않습니다.typePOSIX

관련 정보