Вывести корневой каталог в 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. Надеюсь, это может помочь другим.