![bash 스크립트 설명 [닫기]](https://linux55.com/image/218094/bash%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%84%A4%EB%AA%85%20%5B%EB%8B%AB%EA%B8%B0%5D.png)
이해할 수 없는 다음 스크립트가 있습니다. 누군가 이것을 설명할 수 있나요?
#!/bin/sh
skip=14
tmpdir=`/bin/mktemp -d ${TMPDIR:-/tmp}/gzexe.XXXXXXXXXX` || exit 1
prog="${tmpdir}/`echo \"$0\" | sed 's|^.*/||'`"
if /usr/bin/tail -n +$skip "$0" | "/bin"/gzip -cd > "$prog"; then
/bin/chmod 700 "$prog"
trap '/bin/rm -rf $tmpdir; exit $res' EXIT
"$prog" ${1+"$@"}; res=$?
else
echo "Cannot decompress $0"
/bin/rm -rf $tmpdir
exit 1
fi;
exit $res
답변1
Cas와 kcmakwana가 말했듯이 이 스크립트는 자동 추출됩니다.
#!/bin/sh
이것은 유닉스 쉘 스크립트임을 나타내는 shebang입니다.
skip=14
$skip
문자열 값으로 변수를 선언합니다.14
tmpdir=`/bin/mktemp -d ${TMPDIR:-/tmp}/gzexe.XXXXXXXXXX` || exit 1
여기서 액센트는 콘텐츠를 실행하고 이를 새 명령 문자열에 넣는 것을 의미합니다. (이것은) $(my command)
? 여기서는 임시 디렉터리의 이름을 선언하려고 합니다. 이 ${TMPDIR:-/tmp}
코드는 환경 변수가 $TMPDIR
존재하는 경우 해당 값을 가져오고, 그렇지 않으면 /tmp
문자열을 사용하여 /gzexe.XXXXXXXXXX
생성 중인 경로에 추가한다는 의미입니다. 이는 || exit 1
명령이 실패하면 레벨 1 오류(레벨 0은 성공을 나타냄)와 함께 이 스크립트를 종료한다는 의미입니다. 바라보다이 문제종료 코드에 대한 추가 정보.
prog="${tmpdir}/`echo \"$0\" | sed 's|^.*/||'`"
여기서는 파일 경로에 대한 또 다른 변수를 정의합니다. $0
이 스크립트의 이름을 확장합니다 . sed
해당 문자열을 파이프하는 명령은 경로의 앞부분을 자르는 것입니다 ./
. 여기에서 sed를 파이프로 연결한 문자열에 대한 검색 및 바꾸기 기능으로 생각하세요. 따라서 이 스크립트의 이름 을 지정 myscript.sh
하고 .$0
./myscript.sh
$prog
/tmp/myscript.sh
if /usr/bin/tail -n +$skip "$0" | "/bin"/gzip -cd > "$prog"; then
여기에서는 스크립트의 14번째 줄에서 출력을 시작 $0
하고 플래그를 통해 해당 콘텐츠를 gzip으로 파이프하여 -c and -d
들어오는 텍스트의 압축을 풀고 결과를 표준 출력으로 인쇄합니다. 다음으로, 표준 출력은 $prog
앞서 선언한 파일 경로 로 리디렉션됩니다 . 이것이 최선의 행동인가? 예상되는 내용을 명시적으로 에코하는 것이 더 안전할까요 $prog
?
/bin/chmod 700 "$prog"
여기에서는 소유자가 읽기/쓰기/실행을 할 수 있지만 다른 사람은 파일에 대해 아무것도 할 수 없도록 생성된 파일에 대한 권한을 설정합니다.
trap '/bin/rm -rf $tmpdir; exit $res' EXIT
Trap 명령을 사용하는 일반적인 시나리오는 SIGINT 신호를 캡처하는 것입니다. 이 신호는 사용자가 Ctrl+C를 눌러 스크립트 실행을 중단할 때 전송됩니다. 따라서 사용자가 ctrl-c 명령을 보내면 스크립트는 에 있는 파일을 삭제하려고 시도하고 다음 줄에서 선언한 $tmpdir
수준에서 종료합니다.$res
"$prog" ${1+"$@"}; res=$?
exit $res
여기서는 스크립트를 실행 $prog
하고 인수를 전달합니다. ${1+"$@"}
이는 기본적으로 해당 스크립트에 전달된 인수를 확장한다는 의미입니다 "$1" "$2" "$3" ...
. 이 구문에 대한 설명을 참조하세요.여기. 마지막으로 명령의 종료 상태 결과를 저장하고 이를 $res
( $?
가장 최근의 전경 파이프 종료 상태)에 저장합니다. 마지막으로 동일한 종료 수준으로 종료합니다.
else
echo "Cannot decompress $0"
/bin/rm -rf $tmpdir
exit 1
fi;
매우 간단합니다. if
위 명령이 작동하지 않으면 임시 스크립트 복사본을 삭제 $tmpdir
하고 상태 1(오류)로 종료합니다.