하나 있다유제cd
내장 호출을 대체하려는 경우와 같은 "래퍼" 시나리오를 처리합니다 cd
.
그러나 shellshock 등을 고려하고 bash가 환경에서 함수를 가져오는 것을 알고 몇 가지 테스트를 수행했지만 cd
스크립트 내에서 내장 함수를 안전하게 호출하는 방법을 찾을 수 없었습니다.
이것에 대해 생각하다
cd() { echo "muahaha"; }
export -f cd
이 환경에서 사용법 호출을 사용하는 모든 스크립트 cd
는 중단됩니다(유사한 효과 고려 cd dir && rm -rf .
).
명령어의 종류를 확인하는 명령어(편의상 이라고 함 )와 함수( 및 ) type
대신 내장된 버전을 실행하는 명령어가 있습니다. 그러나 보라, 이것들은 함수를 사용하여 재정의될 수도 있다.builtin
command
builtin() { "$@"; }
command() { "$@"; }
type() { echo "$1 is a shell builtin"; }
다음과 같은 결과가 생성됩니다.
$ type cd
cd is a shell builtin
$ cd x
muahaha
$ builtin cd x
muahaha
$ command cd x
muahaha
bash가 내장 명령을 사용하도록 안전하게 강제하거나 적어도 전체 환경을 지우지 않고 명령이 내장 명령이 아니라는 것을 감지할 수 있는 방법이 있습니까?
누군가가 귀하의 환경을 제어하면 문제가 발생할 수 있지만 최소한 별칭을 사용하면 \
별칭 앞에 를 삽입하여 별칭을 호출하지 않도록 선택할 수 있습니다.
답변1
올리비에 D.거의정확합니다. 하지만 POSIXLY_CORRECT
실행하기 전에 설정 해야 합니다 unset
. POSIX에는 개념이 있습니다특수 내장, 그리고배쉬는 이것을 지원합니다. unset
그것은 단지 내장되어 있습니다. , 및 가 포함 된 찾기 목록 SPECIAL_BUILTIN
에서 bash 소스를 검색합니다 .builtins/*.c
set
unset
export
eval
source
$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset
이제 불량은 환경에서 제거 되며 , unset
설정을 해제하면 계속할 수 있지만 나중에 POSIX가 아닌 동작이나 고급 bash 기능에 의존하는 경우에는 계속할 수 없습니다.command
type
builtin
unset POSIXLY_CORRECT
이것확실히하지만 주소는 별칭이므로 다음을 사용해야 합니다 \unset
(또는어떤 형태의 인용/이스케이프대화형 셸에서 작동하는지 확인하기 위해(또는 expand_aliases
작동하는 경우를 대비해 항상)
편집증 환자에게 이것은~해야 한다모든 문제를 해결하려면 다음과 같이 생각합니다.
POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do
[[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]};
done < <( \help -s "*" )
( while
, do
, done
및 [[
는 예약어이므로 주의가 필요하지 않습니다. =
별칭이나 함수 이름에는 사용할 수 없으므로 설정 시 주의가 필요하지 않습니다 .) 변수와 함수가 공유하더라도 함수가 설정 해제되었는지 확인하기 위해 POSIXLY_CORRECT
사용한다는 점에 유의하세요. unset -f
동일한 명명 공간이 있으면 둘 다 동시에 존재할 수 있습니다(Etan Reisner 덕분에). 이 경우 설정을 두 번 해제하면 문제가 해결됩니다. 너할 수 있는기능을 읽기 전용으로 표시하세요. bash는 bash-4.2 및 이전 버전에서 읽기 전용 기능을 설정 해제하는 것을 막지 않습니다. bash-4.3은 여러분을 막지만, POSIXLY_CORRECT
설정할 때 특수 내장 기능을 여전히 존중합니다.
읽기 전용은 POSIXLY_CORRECT
실제 문제가 아니며 부울이나 플래그도 아닙니다.현재의POSIX 모드를 활성화하므로 읽기 전용으로 존재하는 경우 값이 비어 있거나 0이더라도 POSIX 기능을 사용할 수 있습니다. 위와는 다르게 문제가 되는 기능을 설정 해제하면 됩니다. 아마도 잘라내기와 붙여넣기를 사용하면 됩니다.
\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done
(그리고 오류를 무시하거나) 다른 일에 참여하십시오.문자론.
기타 참고사항:
function
예약어이며 별칭으로 사용할 수 있지만 함수로 재정의할 수는 없습니다. (앨리어싱은function
조금 귀찮습니다.\function
아니요이 문제를 해결하는 방법으로 허용됩니다)[[
,]]
예약어이며 별칭을 지정할 수 있지만(무시됨) 함수에 의해 재정의될 수 없습니다(함수 이름은 그렇게 지정될 수 있음)((
함수 또는 별칭의 유효한 이름이 아닙니다.
추가 제안을 해주신 아래 댓글 작성자에게 감사드립니다.
답변2
나는 누군가가 당신의 환경을 통제한다면 당신은 망할 수도 있다는 것을 깨달았습니다.
그래 그거야. 알 수 없는 환경에서 스크립트를 실행하면 LD_PRELOAD
스크립트를 읽기 전에 쉘 프로세스가 임의의 코드를 실행하는 것부터 시작하여 다양한 문제가 발생할 수 있습니다 . 스크립트 내에서 적대적인 환경으로부터 보호하려는 시도는 소용이 없습니다.
10년 넘게 Sudo는 bash 함수 정의처럼 보이는 모든 것을 제거하여 환경을 위생적으로 유지해 왔습니다. ~부터쉘 쇼크, 완전히 신뢰할 수 없는 환경에서 쉘 스크립트를 실행하는 다른 환경도 이에 따랐습니다.
신뢰할 수 없는 엔터티가 설정한 환경에서는 스크립트를 안전하게 실행할 수 없습니다. 따라서 함수 정의에 대해 걱정하는 것은 비생산적입니다. 환경을 정리하면 bash는 변수를 함수 정의로 해석합니다.
답변3
이 명령을 사용하여 함수 및 을 unset -f
삭제할 수 있습니다 .builtin
command
type