Skip to content

Instantly share code, notes, and snippets.

@p120ph37
Last active January 2, 2024 23:36
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save p120ph37/4f42a8f3ccc46bd8977e84acbd1b9251 to your computer and use it in GitHub Desktop.
Save p120ph37/4f42a8f3ccc46bd8977e84acbd1b9251 to your computer and use it in GitHub Desktop.
How to test if a remote file exists from a shell script using curl.
url='http://example.com/index.html'
# "HEAD" request
# (most servers support "HEAD", but some don't)
if curl -sfILo/dev/null "$url"; then
echo "URL exists"
else
echo "URL does not exist"
fi
url='http://example.com/index.html'
# "GET" with empty range-request
# (lightweight if the server supports range-requests, ends
# up fetching the whole document if the server doesn't...)
if curl -sfLo/dev/null -r0-0 "$url"; then
echo "URL exists"
else
echo "URL does not exist"
fi
@slycordinator
Copy link

slycordinator commented Apr 8, 2023

Curl needs the L option in case the website has redirects, because in the above, a site that returns a 301 will be result in telling you that the URL exists, even if the remote file you're checking for doesn't. Also, the () subshell is unneeded.

url='http://example.com/index.html'
if curl -o/dev/null -sfIL "$url" 2>&1; then
  echo "URL exists"
else
  echo "URL does not exist"
fi

@slycordinator
Copy link

slycordinator commented Apr 8, 2023

And in case the site doesn't allow checking the header with the I option, you can do:
curl -o/dev/null -sfL -r 0-0 "$url"

@p120ph37
Copy link
Author

p120ph37 commented Apr 11, 2023

True, the -L switch produces what is probably the expected behavior for most people. And the sub-shell was indeed entirely unnecessary. As for the HEAD vs GET difference, in most cases, HEAD will work correctly and is lighter-weight on the network and the server, but it does bear mentioning that it may not work in all cases. The GET-with-range trick is an interesting work-around to try to reduce network load, but it also may not work with all servers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment