58

Is there a way to tell curl to output errors to stderr, and everything else to stdout?

The reason is that I am using curl from the command line (actually a cronjob) to upload a file to an FTP site every evening. Unfortunately because curl outputs status information on stderr, I receive an e-mail about an error when nothing actually went wrong. (I'm redirecting stdout to a log file, but leaving stderr unchanged so that cron will e-mail it to me if there is any output.)

There are options to make curl silent, or output everything to stdout, however both these alternatives prevent errors from appearing on stderr - meaning I won't get an e-mail when there is actually an error I want to know about.

So is there a way to make curl only output errors on stderr, but leave normal output intact on stdout?

4 Answers 4

73

Try this:

# No error messages because it succeeds.
curl  http://www.shikadi.net/        --fail --silent --show-error

# This prints an error message to stderr
curl  http://i.like.you.def.maybe/   --fail --silent --show-error

Thanks to Russell Davis's answer on this page, man curl, and trial and error. For the curious, here is the wget version of the question: https://superuser.com/questions/420120/wget-is-silent-but-it-displays-error-messages

Sign up to request clarification or add additional context in comments.

4 Comments

Won't --silent prevent normal progress messages from being sent to stdout though? I would still like to see these so that I know curl is actually doing something!
There is also another problem with my answer: I've never used curl for FTP upload. This has been a waste of your time. I apologize for overlooking important aspects of your question. I will delete this answer to avoid further confusion.
Don't worry about it - it might help someone else just as Russell Davis' answer gave you some ideas :-)
These are the default args I use every time with curl.
23

curl -s -S

From the man page:

-s Silent or quiet mode. Don't show progress meter or error messages. Makes Curl mute.

-S When used with -s it makes curl show an error message if it fails.

1 Comment

Have a look at the comments under @dgo.a's answer - this also removes the normal progress messages that tell you whether things are working as expected, which I want to keep on stdout.
7

After some more experimentation I have come up with the following workaround, but I'm still open to better alternatives.

It works by temporarily storing all output (stdout and stderr) in a temporary file, and then sending the contents of that file to stderr or stdout depending on curl's exit code. If curl failed the entire output will go to stderr (and be e-mailed to me thanks to cron), but if curl succeeded the output will go to stdout instead (which is redirected to a log file in the cron command, resulting in no e-mail.)

# Get a temporary filename
CURL_LOG=`tempfile`

(
  # Run curl, and stick all output in the temp file
  /usr/bin/curl --verbose ... > "$CURL_LOG" 2>&1
) || (
  # If curl exited with a non-zero error code, send its output to stderr so that
  # cron will e-mail it.
  cat "$CURL_LOG" > /dev/stderr
  rm "$CURL_LOG"
  exit 1
)

# Otherwise curl completed successfully, so send the output to stdout (which
# is redirected to a log file in crontab)
cat "$CURL_LOG"
rm "$CURL_LOG"

1 Comment

It's not short and sweet like the other answers, but it's the only answer that actually gets the job done. Thanks for sharing.
2

curl -f. The documentation says "Fail silently (no output at all) on server errors" but it really means "no output to stdout" -- errors will still be output to stderr.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.