Как загрузить и извлечь архив с помощью скрипта (как я могу надежно указать файл, который был загружен в следующую команду)?

Я хочу написать сценарий, который загружает архив из URL (используя wget) и извлекает этот архив (например, используя atool, см. здесь).

К сожалению, я не знаю где wget сохраняет загруженный файл. Мой скрипт параметризуется URL-адресом, поэтому я не знаю URL-адреса во время написания сценария.

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

В общем, трудно / невозможно предсказать местоположение, которое wget сохраняет , В качестве нескольких примеров,

wget example.com создает файл index.html Запуск wget example.com второй раз создает файл index.html.2 wget http://dis.images.s3.amazonaws.com/105024.jpeg создает файл 105024.jpeg wget "https://go.microsoft.com/fwlink/?LinkID=760868" создает файл index.html?LinkID=760868 wget --content-disposition "https://go.microsoft.com/fwlink/?LinkID=760868" создает файл code_1.19.1-1513676564_amd64.deb
0
задан 31 December 2017 в 18:40

6 ответов

Сначала сделайте вывод wget во временный файл. Посмотрите на mktemp, который позволяет безопасно создать временный файл:

[~]$ filename=$(mktemp)
[~]$ echo $filename
/tmp/tmp.DglaA1x2Z0
[~]$ wget -O $filename www.example.com
--2017-12-29 22:15:28--  http://www.example.com/
Resolving www.example.com (www.example.com)... 93.184.216.34, 2606:2800:220:1:248:1893:25c8:1946
Connecting to www.example.com (www.example.com)|93.184.216.34|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1270 (1.2K) [text/html]
Saving to: ‘/tmp/tmp.DglaA1x2Z0’

100%[======================================>] 1,270       --.-K/s   in 0s      

2017-12-29 22:15:30 (156 MB/s) - ‘/tmp/tmp.DglaA1x2Z0’ saved [1270/1270]

mktemp гарантирует, что имя файла уникально и что разрешения обрабатываются так, что мы надеваем 't заканчивает запись в файл, который принадлежит другому пользователю. Файл создается с помощью mktemp с безопасными разрешениями:

[~]$ ls -la $filename
-rw------- 1 vidarlo users 1270 Aug 10  2013 /tmp/tmp.DglaA1x2Z0

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

Теперь, когда у вас есть файл с определенным именем файла, вы можете запустить file, чтобы определить, какой архив он is:

[/tmp]$ file -i foo.tar
foo.tar: application/x-tar; charset=binary
[/tmp]$ file -i foo.7z
foo.7z: application/x-7z-compressed; charset=binary

Это не зависит от того, что нам сообщает удаленный сервер. Сервер может сказать вам расширение - или нет. Скрипт php может служить абсолютно корректным tar-архивом, даже не сообщая вам, что это tar-архив.

Кроме того, мы сохраняем контент в безопасном месте, избегая условий гонки.

Поддержка большого количества форматов архивов может стать громоздкой с использованием этого подхода, но это, безусловно, лучше, чем просто использовать расширение имени файла с веб-сервера, предоставляя нам архив.

Обратите внимание: вы никогда не должны разбирать ls, так как это может имеют очень много непредвиденных последствий.

4
ответ дан 22 May 2018 в 15:51
  • 1
    Это звучит как проблема X-Y. Зачем вам имя файла? Зачем вам нужны метаданные, сохраненные в имени файла? Это альтернатива для анализа URL-адреса или проверки заголовка для имени файла? – vidarlo 30 December 2017 в 02:17
  • 2
    В качестве уточнения: создайте временную директорию и загрузите там wget. Затем вы должны получить только один файл с именем, которое вам нужно. См. [F1] – Patrick Mevzek 30 December 2017 в 02:17
  • 3
    Ах! Но вы этого не сделаете! Используйте команду file, чтобы получить тип архива. Это far более надежно, чем полагаться на имя файла. Что, если я передам вам URL example.com/download.php? Это именно то, что я имею в виду под X-Y проблемой ... – vidarlo 30 December 2017 в 02:23
  • 4
    Спасибо, это работает! Я даже заметил, что atool может извлекать архивы на основе информации из file. Так, например, wget -O $filename "www.example.com/archive.zip"; atool -x $filename работает отлично. – Peter 1 January 2018 в 22:42
  • 5
    Чтобы declutter, я удалил свои комментарии, ссылаясь на предыдущую версию вопроса. – Peter 1 January 2018 в 22:42

Сначала сделайте вывод wget во временный файл. Посмотрите на mktemp, который позволяет безопасно создать временный файл:

[~]$ filename=$(mktemp) [~]$ echo $filename /tmp/tmp.DglaA1x2Z0 [~]$ wget -O $filename www.example.com --2017-12-29 22:15:28-- http://www.example.com/ Resolving www.example.com (www.example.com)... 93.184.216.34, 2606:2800:220:1:248:1893:25c8:1946 Connecting to www.example.com (www.example.com)|93.184.216.34|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 1270 (1.2K) [text/html] Saving to: ‘/tmp/tmp.DglaA1x2Z0’ 100%[======================================>] 1,270 --.-K/s in 0s 2017-12-29 22:15:30 (156 MB/s) - ‘/tmp/tmp.DglaA1x2Z0’ saved [1270/1270]

mktemp гарантирует, что имя файла уникально и что разрешения обрабатываются так, что мы надеваем 't заканчивает запись в файл, который принадлежит другому пользователю. Файл создается с помощью mktemp с безопасными разрешениями:

[~]$ ls -la $filename -rw------- 1 vidarlo users 1270 Aug 10 2013 /tmp/tmp.DglaA1x2Z0

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

Теперь, когда у вас есть файл с определенным именем файла, вы можете запустить file, чтобы определить, какой архив он is:

[/tmp]$ file -i foo.tar foo.tar: application/x-tar; charset=binary [/tmp]$ file -i foo.7z foo.7z: application/x-7z-compressed; charset=binary

Это не зависит от того, что нам сообщает удаленный сервер. Сервер может сказать вам расширение - или нет. Скрипт php может служить абсолютно корректным tar-архивом, даже не сообщая вам, что это tar-архив.

Кроме того, мы сохраняем контент в безопасном месте, избегая условий гонки.

Поддержка большого количества форматов архивов может стать громоздкой с использованием этого подхода, но это, безусловно, лучше, чем просто использовать расширение имени файла с веб-сервера, предоставляя нам архив.

Обратите внимание: вы никогда не должны разбирать ls, так как это может имеют очень много непредвиденных последствий.

4
ответ дан 18 July 2018 в 00:13

Сначала сделайте вывод wget во временный файл. Посмотрите на mktemp, который позволяет безопасно создать временный файл:

[~]$ filename=$(mktemp) [~]$ echo $filename /tmp/tmp.DglaA1x2Z0 [~]$ wget -O $filename www.example.com --2017-12-29 22:15:28-- http://www.example.com/ Resolving www.example.com (www.example.com)... 93.184.216.34, 2606:2800:220:1:248:1893:25c8:1946 Connecting to www.example.com (www.example.com)|93.184.216.34|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 1270 (1.2K) [text/html] Saving to: ‘/tmp/tmp.DglaA1x2Z0’ 100%[======================================>] 1,270 --.-K/s in 0s 2017-12-29 22:15:30 (156 MB/s) - ‘/tmp/tmp.DglaA1x2Z0’ saved [1270/1270]

mktemp гарантирует, что имя файла уникально и что разрешения обрабатываются так, что мы надеваем 't заканчивает запись в файл, который принадлежит другому пользователю. Файл создается с помощью mktemp с безопасными разрешениями:

[~]$ ls -la $filename -rw------- 1 vidarlo users 1270 Aug 10 2013 /tmp/tmp.DglaA1x2Z0

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

Теперь, когда у вас есть файл с определенным именем файла, вы можете запустить file, чтобы определить, какой архив он is:

[/tmp]$ file -i foo.tar foo.tar: application/x-tar; charset=binary [/tmp]$ file -i foo.7z foo.7z: application/x-7z-compressed; charset=binary

Это не зависит от того, что нам сообщает удаленный сервер. Сервер может сказать вам расширение - или нет. Скрипт php может служить абсолютно корректным tar-архивом, даже не сообщая вам, что это tar-архив.

Кроме того, мы сохраняем контент в безопасном месте, избегая условий гонки.

Поддержка большого количества форматов архивов может стать громоздкой с использованием этого подхода, но это, безусловно, лучше, чем просто использовать расширение имени файла с веб-сервера, предоставляя нам архив.

Обратите внимание: вы никогда не должны разбирать ls, так как это может имеют очень много непредвиденных последствий.

4
ответ дан 24 July 2018 в 17:10

По умолчанию wget сохраняет каталог .. Однако вы можете переопределить это, используя опцию -P или --directory-prefix. Итак, чтобы сохранить файлы в /tmp/some_folder, вы должны использовать wget ... -P tmp/some_folder ....

Подробности для использования wget можно найти локально в команде man wget или здесь.

0
ответ дан 22 May 2018 в 15:51
  • 1
    Тем не менее, это не говорит мне имя загруженного файла. Или вы предлагаете мне использовать ls для определения имени, надеясь, что «префиксная папка» была пуста до моей загрузки? – Peter 30 December 2017 в 01:23
  • 2
    @Peter, вы можете отредактировать свой вопрос, когда я прочитаю ваш запрос " Я хочу знать, где wget сохранил файл в " буквально. – richbl 30 December 2017 в 01:40
  • 3
    Спасибо за подсказку. Теперь ясно (er)? – Peter 30 December 2017 в 01:47
  • 4
    @Peter, чтобы ответить на вопрос в вашем комментарии: если папка префикса не существует, wget создаст ее. Вы можете использовать это в своих интересах. Тем не менее, я был бы осторожен в разборе вывода ls (вместо этого используйте glob оболочки или даже find). – richbl 30 December 2017 в 01:47

По умолчанию wget сохраняет каталог .. Однако вы можете переопределить это, используя опцию -P или --directory-prefix. Итак, чтобы сохранить файлы в /tmp/some_folder, вы должны использовать wget ... -P tmp/some_folder ....

Подробности для использования wget можно найти локально в команде man wget или здесь.

0
ответ дан 18 July 2018 в 00:13

По умолчанию wget сохраняет каталог .. Однако вы можете переопределить это, используя опцию -P или --directory-prefix. Итак, чтобы сохранить файлы в /tmp/some_folder, вы должны использовать wget ... -P tmp/some_folder ....

Подробности для использования wget можно найти локально в команде man wget или здесь.

0
ответ дан 24 July 2018 в 17:10
  • 1
    Тем не менее, это не говорит мне имя загруженного файла. Или вы предлагаете мне использовать ls для определения имени, надеясь, что «префиксная папка» была пуста до моей загрузки? – Peter 30 December 2017 в 01:23
  • 2
    @Peter, вы можете отредактировать свой вопрос, когда я прочитаю ваш запрос & quot; Я хочу знать, где wget сохранил файл в & quot; буквально. – richbl 30 December 2017 в 01:40
  • 3
    Спасибо за подсказку. Теперь ясно (er)? – Peter 30 December 2017 в 01:47
  • 4
    @Peter, чтобы ответить на вопрос в вашем комментарии: если папка префикса не существует, wget создаст ее. Вы можете использовать это в своих интересах. Тем не менее, я был бы осторожен в разборе вывода ls (вместо этого используйте glob оболочки или даже find). – richbl 30 December 2017 в 01:47

Другие вопросы по тегам:

Похожие вопросы: