Есть ли опция curl / wget, предотвращающая сохранение файлов в случае ошибок http?

Я хочу загрузить в скрипт много URL-адресов, но не хочу сохранять те, которые приводят к ошибкам HTTP.

Насколько я могу судить по страницам руководства, ни curl, ни wget не обеспечивают такой функциональности. Кто-нибудь знает про другой загрузчик, который знает?

Насколько я понимаю, Окт - единственный человек, который действительно прочитал вопрос и ответил на него. Все остальные давали вам методы, с помощью которых никогда и никогда загружает что угодно, или говорили, что нужно катить свои собственные. Разве вы не должны принять единственный полученный вам ответ настоящий?

iconoclast 05.03.2013 21:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
23
1
28 242
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Я думаю, что опция -f для curl делает то, что вы хотите:

-f, --fail

(HTTP) Fail silently (no output at all) on server errors. This is mostly done to better enable scripts etc to better deal with failed attempts. In normal cases when an HTTP server fails to deliver a document, it returns an HTML document stating so (which often also describes why and more). This flag will prevent curl from outputting that and return error 22. [...]

Однако, если ответ был на самом деле переадресацией 301 или 302, он все равно сохраняется, даже если его пункт назначения приведет к ошибке:

$ curl -fO http://google.com/aoeu
$ cat aoeu
<HTML><HEAD><meta http-equiv = "content-type" content = "text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF = "http://www.google.com/aoeu">here</A>.
</BODY></HTML>

Чтобы проследить перенаправление до его тупика, также укажите параметр -L:

-L, --location

(HTTP/HTTPS) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place. [...]

нет, это связано только с множеством ошибок. после использования ошибки не сообщаются (но сохраняются как обычно) в любом случае спасибо

akiva 18.09.2008 08:29

Это именно то, что я хотел (curl -fO {URL}). Он не сохраняет файл на 404. Спасибо

hypercrypt 25.09.2014 12:20

@hypercrypt Ваш комментарий сбил меня с толку, пока я не понял, что происходит. Отредактировано с важной оговоркой.

Thomas 26.09.2014 21:47

-fLO - мои новые любимые флаги локонов :) curl -fLO http://google.com/aoeu => curl: (22) The requested URL returned error: 404 Not Found

Asfand Qazi 09.09.2015 12:34

ИМО, это должен быть принятый ответ. Спасибо!

Vedran Šego 07.06.2017 14:24

Отличное решение, но имейте в виду, что оно технически небезопасно. Например, URL-адрес может возвращать 200, но содержимое файла на сервере пустое и т. д. Во многих случаях рекомендуется «протестировать» полученный файл либо на заданную строку (например, grep), либо на ненулевой размер файла. (например, чтобы убедиться, что загруженный файл не пустой).

Jesse Nickles 21.02.2021 23:30
Ответ принят как подходящий

Один лайнер, который я настроил именно для этой цели:

(работает только с одним файлом, может быть полезно другим)

A=$$; ( wget -q "http://foo.com/pipo.txt" -O $A.d && mv $A.d pipo.txt ) || (rm $A.d; echo "Removing temp file")

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

Вы хотели сказать «если есть ошибка ан, файл не сохраняется»? В противном случае вы сделали обратное тому, о чем просили.

iconoclast 27.02.2013 01:05

Вы можете скачать файл без сохранения, используя опцию "-O -" как

wget -O - http://jagor.srce.hr/

Вы можете получить дополнительную информацию на http://www.gnu.org/software/wget/manual/wget.html#Advanced-Usage

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

iconoclast 05.03.2013 21:34

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

if [ `curl -s -w "%{http_code}" --compress -o /tmp/something \
      http://example.com/my/url/` = "200" ]; then 
  echo "yay"; cp /tmp/something /path/to/destination/filename
fi

Это загрузит вывод в файл tmp и создаст / перезапишет выходной файл только в том случае, если статус был 200. Мой вариант использования немного отличается .. в моем случае вывод занимает> 10 секунд для генерации ... и я не хотел, чтобы место назначения файл должен оставаться пустым в течение этого времени.

У меня есть обходной путь, он загружает файл, но также удаляет его, если его размер равен 0 (что происходит, если возникает ошибка 404).

wget -O <filename> <url/to/file>
if [[ (du <filename> | cut -f 1) == 0 ]]; then
    rm <filename>;
fi;

Он работает для zsh, но вы можете адаптировать его для других оболочек.

Но он экономит только на первом месте, если вы предоставляете опцию -O.

ПРИМЕЧАНИЕ: Мне известно, что это более старый вопрос, но я считаю, что нашел лучшее решение для тех, кто использует wget, чем любой из приведенных выше ответов.

wget -q $URL 2>/dev/null

Целевой файл будет сохранен в локальном каталоге тогда и только тогда, когда код состояния HTTP находится в диапазоне 200 (Ok).

Кроме того, если вы хотите сделать что-то вроде распечатки ошибки всякий раз, когда запрос встречался с ошибкой, вы можете проверить код выхода wget на ненулевые значения, например:

wget -q $URL 2>/dev/null
if [ $? != 0]; then
    echo "There was an error!"
fi

Надеюсь, это будет полезно для кого-то, кто столкнется с теми же проблемами, что и я.

Обновлять: Я просто поместил это в форму, более подходящую для сценариев для моего собственного проекта, и подумал, что поделюсь:

function dl {
    pushd . > /dev/null
    cd $(dirname )
    wget -q $BASE_URL/ 2> /dev/null
    if [ $? != 0 ]; then
        echo ">> ERROR could not download file \"\"" 1>&2
        exit 1
    fi
    popd > /dev/null
}

Забыл упомянуть: очень важно, чтобы вы не вызывали wget, используя флаг -O. -O всегда будет создавать новый файл, независимо от статуса запроса, хотя обычно он ничего не помещает в файл при ошибке.

user5739133 02.03.2019 10:13

В качестве альтернативы вы можете создать файл временного вращения:

wget http://example.net/myfile.json -O myfile.json.tmp -t 3 -q && mv list.json.tmp list.json

Предыдущая команда всегда загружает файл «myfile.json.tmp», однако только когда статус выхода wget равен 0, файл поворачивается как «myfile.json».

Это решение предотвратит перезапись окончательного файла, когда происходит сбой в сети.

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

Параметр "-t" пытается загрузить файл несколько раз в случае ошибки.

«-Q» - это тихий режим, и его важно использовать с cron, потому что cron будет сообщать о любом выводе wget.

«-O» - это путь и имя выходного файла.

Помните, что для расписаний Cron очень важно всегда указывать полный путь ко всем файлам и, в данном случае, также и к самой программе "wget".

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