command
저는 함수라면 무언가를 실행하는 Bash 내장 기능과 비슷한 것을 찾고 있습니다 . 따라서 현재 안전하지 않은 접근 방식이 있습니다.
# Go through arguments in order
for i in $*; do
if [ -z `which $i` ]; then
# Run function
$i && echo -n ' '
fi
done
이 if 문은 제대로 작동하지 않습니다. 어쨌든, 그것이 함수가 아닌 명령인지 확인할 수 있다고 해도 명시적으로 함수를 실행할 수는 없습니다. 이는 누군가 $PATH에 내 함수와 동일한 이름을 가진 프로그램이 있으면 실행되기 때문에 좋지 않습니다. PATH를 취소하거나 다른 것으로 설정해도 누구나 $i를 사용하여 명시적으로 프로그램을 실행할 수 있으므로 이 역시 해결책이 아닙니다.
내 쉘 스크립트를 "보호"할 수 있는 방법이 있습니까?
답변1
를 사용하면 bash
다음을 수행할 수 있습니다.
for f do
if declare -F -- "$f" >/dev/null 2>&1; then
: "$f" is a function, do something with it
fi
done
declare -F -- "$f" >/dev/null 2>&1
$f
bash 함수인 경우 성공 코드가 반환되고 아무것도 출력되지 않습니다.
bash
POSIX 모드에서 실행할 때 builtin enable -n -- "$f"
.
답변2
Bash가 제공하는 공식적인 방법은 type
내장된 as of를 사용하는 것입니다 type -t
.
function fun() {
: foo bar
}
if [ function = $(type -t fun) ]; then
echo fun is a function.
fi
인수 목록의 함수 이름이 의심스러우면 큰따옴표로 묶으십시오.$(type -t "$arg")
답변3
bash
쉘에 이미 설정되어 있을 수도 있지만 이와 같은 이식 가능한 작업을 수행하려면 다음과 같은 것을 사용할 수 있습니다.
eval " for c in $(unalias -a
for c do case ${c#function} in
(*[!_[:alnum:]]*) ;; (?*)
PATH= command -v "$c" >&2 &&
PATH= command -V "$c" &&
printf '\n'"'$c'"'\\\0'
esac 2>/dev/null; done |
tr '\t\n\0' ' \n' |
sed -ne's/.* function .* / /p')"'
;do "$c"; printf %02s
done'
그것은 단계적으로 진행됩니다:
- 먼저 먼저 쉘 이름으로 부적격하게 만드는 문자가 포함된 매개변수를 모두 지우십시오.
- 현재 인수가 유효한 이름인 경우그리고유효한 쉘 내장 또는 함수는 이름과 유형을 표준 출력에 인쇄합니다. 쉘은 출력 방식을 변경할 수 있으므로
command -V
출력을 한 줄로 처리할 수 없습니다. 따라서 출력 뒤에는 우리가 검증한 이름과 null 바이트가 옵니다. tr
모든 줄 바꿈과 탭을 공백으로 변환하고 모든 null 바이트를 줄 바꿈으로 변환합니다.- , 모든 줄의 마지막 공백 문자를 바꾸고 줄도 문자열과 일치하면
sed
결과를 인쇄합니다.s///
function
. - 모든
sed
출력은 외부 루프의 반복자로 반올림되고 , 각 반복자는 차례로 실행되며,for
각 실행 후에printf
두 개의 공백이 기록됩니다 .