#!/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
type
예POSIX의 일부, 그러나 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 -V
Bash는 또한 주어진 여러 줄에 전체 함수 정의를 표시하는데 command -V
, 이는 구문 분석하기가 정말 어렵습니다.
POSIX정의된 command
옵션처럼:
-p
PATH의 기본값을 사용하여 명령 검색이 수행되므로 모든 표준 유틸리티를 찾을 수 있습니다.
-v
쉘이 현재 쉘의 실행 환경에서 사용할 경로 이름이나 명령을 나타내는 문자열을 표준 출력에 씁니다(참조쉘 실행 환경), command_name을 호출하지만 command_name은 호출하지 않습니다.
- 유틸리티, 일반 내장 유틸리티, 문자가 포함된 command_names 및 PATH 변수를 사용하여 찾은 구현 정의 함수(예:명령어 검색 및 실행)은 절대 경로명으로 작성해야 합니다.
- 쉘 기능, 특수 내장 유틸리티, PATH 검색과 관련되지 않은 일반 내장 유틸리티, 쉘 예약어 등은 이름 그대로 간단하게 작성해야 합니다.
- 별칭은 별칭 정의를 나타내는 명령줄로 작성되어야 합니다.
- 그렇지 않으면 출력이 작성되지 않으며 종료 상태에 이름을 찾을 수 없다는 내용이 반영되어야 합니다.
-V
현재 쉘 실행 환경에서 command_name 피연산자에 제공된 이름을 해석하는 방법을 쉘에 지시하는 문자열을 표준 출력에 기록합니다(참조쉘 실행 환경), 그러나 command_name은 호출되지 않습니다. 이 문자열의 형식은 지정되지 않았지만 다음 범주 중 command_name이 속하는 범주를 나타내야 하며 설명된 정보를 포함해야 합니다.
- 유틸리티, 일반 내장 유틸리티 및 PATH 변수를 사용하여 찾은 구현 정의 함수(예:명령어 검색 및 실행)로 식별되어야 하며 문자열에 절대 경로 이름을 포함해야 합니다.
- 다른 쉘 기능은 기능으로 식별되어야 합니다.
- 별칭은 별칭으로 식별되어야 하며 해당 정의는 문자열에 포함되어야 합니다.
- 특수 내장 유틸리티는 특수 내장 유틸리티로 식별되어야 합니다.
- PATH 검색과 관련되지 않은 일반 내장 유틸리티는 일반 내장 유틸리티로 식별되어야 합니다. ("정규"라는 용어를 사용할 필요는 없습니다.)
- 쉘 예약어는 예약어로 표시되어야 합니다.
쉘 스크립트를 작성할 때 정의된 출력이 있는 세 가지 중 유일한 것이기 때문에 or command -v
대신 사용하는 것이 좋습니다 . 그런 다음 대부분의 스크립트는 명령이 있는지 확인할 때 출력을 완전히 무시하는 자동 도우미 함수를 통해 이를 호출합니다.type
command -V
we_have() { command -v "$1" >/dev/null 2>&1; }
if we_have obscure-command; then
osbcure-command …
fi
답변3
이 명령은 1984년 이후부터 포함되지 type
않았습니다 .bashism
UNIX
그러나 기본적인 호환성만 제공하는 소규모 임베디드 플랫폼을 사용하는 경우 이 type
명령이 존재하지 않을 수 있습니다.POSIX
자체적으로 -platform을 호출하는 플랫폼을 사용하는 경우 지원하려면 -platform이 필요 하므로 UNIX
이 type
명령은 필수입니다.UNIX
모두XSI
표준에 언급된 소위 개선 사항 POSIX
.
소규모 임베디드 시스템에서도 지원해야 하는 준유사한 명령을 찾고 있다면 다음을 사용하는 것이 좋습니다.
command -V foo
대신에. 대문자 -V 옵션은 command
유사하지만 반드시 동일하지는 않은 출력을 인쇄합니다 type
.
또한 참고: 표준은 command -V
from 또는 from의 출력 형식을 정의하지 않습니다.type
POSIX