Вывести корневой каталог в tar-архив

Я пытаюсь автоматизировать процесс, который вы выполняете при компиляции чего-то вроде nginx, используя оболочку script. (Я не хочу использовать apt-get)

В настоящее время у меня есть это:

wget http://nginx.org/download/nginx-1.0.0.tar.gz
tar xf nginx-1.0.0.tar.gz

Но потом мне нужно выяснить, что такое имя каталога, откуда оно было извлечено, поэтому я могу запустить configure script.

Ответ 1

Используйте это, чтобы узнать каталог верхнего уровня (-ies) архива.

tar tzf nginx-1.0.0.tar.gz | sed -e '[email protected]/.*@@' | uniq

sed вызывается здесь, чтобы получить первый компонент пути, напечатанный tar, поэтому он преобразует

path/to/file --> path

Он делает это, выполняя команду s. Я использую знак @ как разделитель вместо более обычного знака /, чтобы избежать экранирования / в regexp. Таким образом, эта команда означает: заменить часть строки, которая соответствует шаблону /.* (например, слэш, за которым следует любое количество произвольных символов) с пустой строкой. Или, другими словами, удалите часть строки после (и включите) первую косую черту.

(Он должен быть изменен для работы с абсолютными именами файлов, однако они довольно редки в файлах tar, но убедитесь, что эта теоретическая возможность не создает уязвимости в вашем коде!)

Ответ 2

Использование sed, как описано в другом ответе, является хорошим подходом, но лучше использовать head -1 перед sed вместо uniq после; это значительно улучшает производительность - вы перекачиваете только первую строку через sed, и это также позволяет избежать необходимости uniq загружать весь вывод sed в память. Кроме того, если tar содержит несколько каталогов верхнего уровня, это вернет первый каталог верхнего уровня, тогда как uniq предоставит вам все каталоги верхнего уровня.

tar tzf nginx-1.0.0.tar.gz | head -1 | sed -e 's/\/.*//'

Я лично считаю более читаемым избегать внутреннего/в совпадении шаблонов sed как \/, а не вводить другой разделитель, такой как @, но это только вопрос предпочтения

Ответ 3

Имя каталога должно быть nginx-1.0.0 или независимо от имени tarball без .tar.gz. Попробуйте это после wget и tar:

cd nginx*
./configure
# etc

Вы также можете использовать переменные, если хотите.

name='nginx-1.0.0' # or $1, or whatever works for you
wget "http://nginx.org/download/$name.tar.gz"
tar -xf "$name.tar.gz"
./$name/configure

Однако, самое лучшее, лучшим решением было бы cd в соответствующий каталог после извлечения, используете ли вы глобус или переменную для имени каталога.

Ответ 4

Ответы, приведенные здесь, не подходят для абсолютных путей, поскольку они обрезают их в первую директорию пути. Если вы создали tar-архив с абсолютными путями, следующий фрагмент вернет исходный корень:

tar tf archive.tar | head -1

Для сжатых архивов .tar.gz добавьте опцию c. Надеюсь, это поможет некоторым другим.

Ответ 5

Как насчет этого для получения всех каталогов верхнего уровня (в том числе.):

tar tf nginx-1.0.0.tar.gz | xargs dirname | sort | uniq

Чтобы получить первый каталог верхнего уровня, я бы использовал решение, отправленное @thomas-steinbach:

tar tf nginx-1.0.0.tar.gz | head -1

Ответ 6

Многие из приведенных выше ответов верны, но я столкнулся с ситуацией, когда фактический tar остановился в результате прокладки трубопровода.

Следующая команда в оболочке Borne:

tar -v -zxf plotutils-3.1.tar.gz | head -1 | cut -d "/" -f 1

Создает имя верхнего каталога: plotutils-3.1 Однако результирующий каталог будет либо пустым, либо содержит один элемент. Я использую ubuntu. Чтобы получить фактический результат tar, вам нужно выполнить другую команду

tar -zxf plotutils-3.1.tar.gz  

снова. Я не уверен, что я делаю что-то неправильно здесь; но это следует отметить. Я нашел это при попытке написать оболочку script, чтобы автоматически запускать конфигурацию autotool script. Надеюсь, это может помочь другим.