Выполнить самораспаковывающийся скрипт bash (с присоединенными двоичными данными) без предварительного сохранения

Выполнить самораспаковывающийся скрипт bash (с присоединенными двоичными данными) без предварительного сохранения

У меня есть самораспаковывающийся bash-скрипт (двоичные данные добавляются в конец), например такой:

#!/bin/bash

export TMPDIR=$(mktemp -d)

ARCHIVE_START_LINE=$(...) # <omitted>

# extracting data archive into a temporary directory
tail -n+$ARCHIVE_START_LINE $0 | tar xzv -C $TMPDIR

# <ACCESSING_ARCHIVED_RESOURCES>

exit 0

# <BINARY_DATA_ARCHIVE>

Скрипт размещен удаленно по адресуhttps://<omitted>/script.sh

Я хочу извлечь скрипт и выполнить его локально.

Так как я использую tailскрипт, передавая ему текущее имя файла в качестве аргумента, я не могу сделать:

/bin/bash -c "$(curl -fsSL https://<omitted>/script.sh)"

Конечно, я могу сначала сохранить его во временный файл, например:

TMP=$(mktemp); curl -fsSL https://<omitted>/script.sh > $TMP; sh $TMP; rm $TMP

Но... есть ли более изящный способ?

решение1

Я бы просто немного изменил структуру скрипта, чтобы вам не понадобился tail. Просто сохраните данные как переменную:

#!/bin/bash

## begin data dump
read -r -d '' archive_data <<'EoF'
<BINARY_DATA_ARCHIVE>
EoF
## end data dump

export tmpdir=$(mktemp -d)

# extracting data archive into a temporary directory
printf '%s' "$archive_data" | tar xzv -C "$tmpdir"

exit 0

Комментарии:

  • Это не сработает, если архив данных может содержать NUL ( \0).

  • Обратите внимание на одинарные кавычки вокруг 'EoF', они гарантируют, что никакие переменные $не будут расширены до неправильных имен.

  • Я также изменил ваши переменные на строчные, так как это плохая практика использовать заглавные буквы для переменных оболочки, поскольку по соглашению глобальные переменные окружения пишутся с заглавной буквы, и это может привести к конфликтам имен и неожиданным ошибкам. Используйте строчные буквы для ваших переменных и пишите глобальные env с заглавной буквы только там, где это возможно.

  • Я изменил mktempна , mktemp -dтак как вы, похоже, пытаетесь создать каталог, а без -dкоманды mktempсоздается файл.

Теперь вы сможете сделать что-то вроде этого:

curl -fsSL https://<omitted>/script.sh | bash

Связанный контент