bash 스크립트 설명 [닫기]

bash 스크립트 설명 [닫기]

이해할 수 없는 다음 스크립트가 있습니다. 누군가 이것을 설명할 수 있나요?

#!/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(오류)로 종료합니다.

관련 정보