その内容を tar コマンドで送信してアーカイブを抽出します。

その内容を tar コマンドで送信してアーカイブを抽出します。

自動抽出アーカイブを作成しており、基本が機能しています。

tail -n+$ARCHIVE_START_LINE $0さて、アーカイブ内容を変数として抽出するコマンドを設定したいと思います。この部分を操作できません

私はここでたくさん試しました。そのうちの1つを以下に説明します。 (これは単純化された例なので、パイプなどを理解し、問題を解決することに関する質問です。)

#!/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

Ubuntu 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バイト)のみが含まれます。シェルを使用してバイナリデータを操作することはできません。

おすすめ記事