자동 추출 아카이브를 만들고 있으며 기본 사항이 작동하고 있습니다.
tail -n+$ARCHIVE_START_LINE $0
그런데 아카이브 내용을 변수로 추출하는 명령을 설정하고 싶습니다. 이 부분을 작동시킬 수 없습니다
나는 여기서 많은 것을 시도했습니다. 그 중 하나가 아래에 설명되어 있습니다. (이것은 단순화된 예이므로 파이프 등을 이해하고 문제를 해결하는 것에 대한 질문입니다.)
#!/bin/bash
export TMPDIR=`mktemp -d /tmp/selfextract.XXXXXX`
ARCHIVE_START_LINE=`awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' $0`
# This works...
tail -n+$ARCHIVE_START_LINE $0 | tar xzv -C $TMPDIR
# .. but this is the kind of thing I want. But it doesn't work...
ARCHIVE_CONTENTS=`tail -n+$ARCHIVE_START_LINE $0`
echo $ARCHIVE_CONTENTS | tar xzv -C $TMPDIR
# I get: gzip: stdin is a multi-part gzip file -- not supported
우분투 12.04를 사용하고 있습니다
답변1
귀하의 모든 질문은 다음에 설명되어 있습니다.공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?, 그러나 여기서 관련 부분을 반복하겠습니다.
우선, $var
쉘 스크립트에서는 "변수의 값 var
"을 의미하는 것이 아니라 "변수의 값을 가져와 var
이를 단어로 나누고 각 단어를 와일드카드 패턴으로 해석한다"는 의미입니다. 이러한 추가 단계를 피하려면 변수 대체를 큰따옴표로 묶으십시오. "$var"
이는 "변수의 값 var
"을 의미합니다.변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하세요.왜 그들을 제외해야 하는지 알고 이해하지 않는 한.
둘째, echo
인수를 정확하게 인쇄하지 않습니다. 일부 옵션을 해석하고 일부 쉘에서는 백슬래시 이스케이프 시퀀스를 해석합니다. 추가적으로, echo
후행 줄바꿈이 인쇄되는데, -n
이 옵션을 사용하여 제거할 수 있습니다. Gzip으로 압축된 데이터는 옵션처럼 보이지 않습니다. bash는 echo
기본적으로 백슬래시를 문자 그대로 처리하지만 일반적으로 echo
알 수 없는 데이터에는 사용 하지 말고 printf %s
대신 사용하세요.
printf %s "$ARCHIVE_CONTENTS" | tar xzv -C "$TMPDIR"
ARCHIVE_CONTENTS
이렇게 하면 변수 값이 정확하게 입력됩니다 tar
.
근본적으로 다른 접근 방식을 사용하지 않고는 해결할 수 없는 나머지 문제는 대부분의 셸(zsh를 제외하고 내가 본 모든 것)이 첫 번째 null 바이트에서 변수 값을 자르는 것입니다. 후드 아래에서 종료된 문자열). 따라서 이 변수에는 ARCHIVE_CONTENTS
실제로 아카이브 파일의 시작 부분(최대 첫 번째 null 바이트)만 포함됩니다.셸을 사용하여 이진 데이터를 조작할 수 없습니다.
답변2
이 문서를 이전처럼 사용하면 어떨까요?
#!/bin/bash
export TMPDIR=`mktemp -d /tmp/selfextract.XXXXXX`
## other stuff
base64 -d <<EOF | tar xvf -C $TMPDIR
## base64 encoded
EOF
이런 식으로 base64 인코딩을 생성합니다.
tar cf - my_dir | base64 > /some/place
(독자에게 남겨진 자동 압축 풀림 아카이브 포함)
답변3
실수로 쉘 확장 아카이브 내용이 있을 수 있습니다. 변수를 인용해 보세요.
바꾸다
echo $ARCHIVE_CONTENTS | tar xzv -C $TMPDIR
그리고
echo "$ARCHIVE_CONTENTS" | tar xzv -C $TMPDIR
개행 추가를 피하고 싶을 수도 있습니다.echo -n