실행 중에 my_script.sh
script()를 실행하는 bash 쉘 script()가 있습니다. their_script
내 스크립트( my_script.sh
)는 다음과 같습니다.
THISDIR=`dirname $(readlink -f $0)`
main() {
cd $THISDIR
source their-script
}
main "$@"
their-script
변경해서는 안 되는 파일입니다. their-script
이런 것이 있습니다:
BDIR="$1"
...
BDIR=`readlink -f "$BDIR"
위의 모든 것이 훌륭하게 작동합니다. 몇 가지 옵션을 추가하고 싶어서 my_script.sh
다음과 같이 변경했습니다.
THISDIR=`dirname $(readlink -f $0)`
check_options() {
while [ "$1" != "" ]; do
case $1 in
--username ) shift
OPTIONS_USERNAME=$1
;;
* ) # No more options
;;
esac
shift
done
}
main() {
check_options
cd $THISDIR
source their-script
}
main "$@"
이제 를 실행하면 ./my_script.sh --username example
실행 their-script
중에 실패합니다.
readlink -f --username
그리고 다음 줄을 뱉어보세요.
readlink: unrecognized option '--username'
이런 식으로 스크립트의 위치 매개변수가 다른 스크립트를 손상시키는 것을 방지하려면 어떻게 해야 합니까?
답변1
@roaima가 지적했듯이 별도의 프로세스에서 스크립트를 실행하고 싶을 수도 있습니다. 내부 작동 방식을 완전히 이해하지 않고 코드에 포함시키는 것은 매우 위험할 수 있습니다.
FILE_TO_REMOVE="/tmp/foobar"
source some-cool-script
rm -Rf "$FILE_TO_REMOVE"
분명히 이것은 멋진 스크립트에 다음이 포함될 수 있으므로 올바른 방법이 아닙니다.
FILE_TO_REMOVE=/
스크립트가 언제든지 변경될 수 있다는 점은 말할 것도 없습니다("적극적으로" 유지 관리되지 않더라도).
이 외에도 다음 사항도 고려해야 합니다.
위치 인수 처리는 나머지 인수 수에 따라 더 잘 제어될 수 있습니다.
while [ $# -gt 0 ]; then ... done
""
구분 기호로 사용하려는 경우가 아니면 빈 문자열 like는 완벽하게 유효한 인수가 될 수 있습니다. 이렇게 하더라도(전통적으로--
사용됨) 위의 조건을 유지하고 다음을 사용하는 것이 더 나을 수도 있습니다.case "$1" in ... "") shift break ;; ... esac
이는 유지 관리가 더 쉽습니다.
이
$@
변수는 범위별로 적용됩니다. 즉, 평소와 같이 외부 스크립트를 실행하기로 결정한 경우(예: 코드로 가져오는 대신 호출하여) 매개변수를 전달해야 합니다.their-script "$@"
특히 스크립트가 상승된 권한으로 실행되는 경우 스크립트의 전체 경로를 사용하는 것도 나쁘지 않은 생각일 수 있습니다.
위의 내용은 실제로 명령줄 인수를 확인하지 않는다는 의미이기도 합니다.
main() { check_options } main "$@"
전화해 주셔야 해요
check_options "$@"
그러나 위의 내용은 의 매개변수가
main
어떤 방식으로도 수정되지 않음 을 의미합니다check_options
. 특정 옵션을 필터링하여 외부 스크립트가 충돌하지 않도록(그리고 질문이 주어지는 경우) 다음 두 가지 옵션이 있습니다.옵션 해결을
main
스크립트의 전역 범위에 넣습니다. 코드 청결성 측면에서 보면 더 빠르고 조금 더 지저분합니다.별도의 함수에서 옵션 구문 분석을 유지하고 일부 변수 처리를 수행합니다.
check_options { # parse options magic # what needs to be passed over is # kept in a separate variable PASS_THROUGH_OPTS=... } main { check_options "$@" set -- $PASS_THROUGH_OPTS ... }
이는 위치 매개변수에 공백이나 다른 단어 구분 기호가 포함될 수 있는 가능성을 처리하지 않는다는 점에 유의하세요. 배열(구현에 따라 다름)을 사용하는 것 외에 이를 올바르게 처리하는 다른 방법은 없으며 다음이 포함됩니다.
check_options { ... # parameter should be kept for further use x=( "${x[@]}" "$1" ) ... } check_options "$@" set -- "${x[@]}"
답변2
이 명령은 쉘이 source their-script
스크립트 컨텍스트에서 직접 실행하도록 지시합니다. their-script
즉, 모든 변수에 액세스할 수 있고 변경할 수도 있다는 의미입니다.
해당 단어를 제거 source
하고 their-script
명령으로 실행하면 코드에 영향을 미칠 수 없으며 $1
제공하는 첫 번째 인수가 되므로 이 경우 $1
다음 값을 사용합니다 banana
.
their-script banana