Вывести корневой каталог в архив tar - PullRequest
10 голосов
/ 17 апреля 2011

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

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

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

Но затем мне нужно выяснить, каково имя каталога, откуда он тоже извлечен, такЯ могу запустить скрипт настройки.

Ответы [ 6 ]

12 голосов
/ 17 апреля 2011

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

tar tzf nginx-1.0.0.tar.gz | sed -e 's@/.*@@' | uniq

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

path/to/file --> path

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

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

7 голосов
/ 30 ноября 2012

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

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

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

0 голосов
/ 25 апреля 2017

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

Следующая команда в оболочке 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  

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

0 голосов
/ 11 мая 2016

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

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

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

tar tf nginx-1.0.0.tar.gz | head -1
0 голосов
/ 14 мая 2015

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

tar tf archive.tar | head -1

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

0 голосов
/ 17 апреля 2011

Имя каталога должно быть nginx-1.0.0 или любое другое имя тарбола без .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

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

...