When using cURL in scripts, downloaded files default to the current working directory. This becomes problematic when you need organized file storage or when running scripts from different locations.
The primary method involves using the -o
or --output
flag to specify both path and filename:
curl -o /path/to/directory/filename.ext https://example.com/file.ext
When scripting, it's wise to first ensure the target directory exists:
mkdir -p /path/to/directory
curl -o /path/to/directory/filename.ext https://example.com/file.ext
For cases where you want to preserve original filenames:
curl -O --output-dir /path/to/directory https://example.com/file.ext
Note: --output-dir
requires cURL 7.73.0 or later.
When downloading multiple files to the same directory:
for url in \
https://example.com/file1.zip \
https://example.com/file2.zip
do
curl -O --output-dir /path/to/directory "$url"
done
Add robust error checking to your download script:
download_dir="/path/to/directory"
mkdir -p "$download_dir" || exit 1
if ! curl -f -o "$download_dir/file.ext" https://example.com/file.ext; then
echo "Download failed" >&2
exit 1
fi
Here's a complete script example with all best practices:
#!/bin/bash
# Configuration
DOWNLOADS_DIR="$HOME/downloads/$(date +%Y-%m-%d)"
DOWNLOAD_URL="https://example.com/large-file.zip"
# Create directory if it doesn't exist
mkdir -p "$DOWNLOADS_DIR" || {
echo "Error: Failed to create directory $DOWNLOADS_DIR" >&2
exit 1
}
# Download with progress bar
echo "Downloading to $DOWNLOADS_DIR..."
if ! curl -# -o "$DOWNLOADS_DIR/large-file.zip" "$DOWNLOAD_URL"; then
echo "Download failed" >&2
exit 1
fi
echo "Download completed successfully"
When using cURL to download files, the default behavior saves them to your current working directory. This becomes problematic when scripting automated downloads that need organization. The challenge lies in controlling the output location while maintaining cURL's other functionality.
The fundamental solution involves combining the -o
or --output
flag with your target path:
# Absolute path example
curl -o /path/to/destination/filename.ext https://example.com/file.ext
# Relative path example
curl -o ../relative/path/filename.ext https://example.com/file.ext
For more complex scenarios, consider these approaches:
1. Preserving Remote Filenames
# Using -O with directory prefix
(cd /target/directory && curl -O https://example.com/file.ext)
# Alternative method
curl https://example.com/file.ext --output-dir /target/directory -O
2. Automated Directory Creation
# Combine with mkdir
mkdir -p /custom/path && curl -o /custom/path/file.ext https://example.com/file.ext
3. Handling Multiple Files
# Using xargs with directory specification
echo -e "url1\\nurl2" | xargs -I {} curl -o /target/directory/{} {}
Always verify directory permissions and existence:
#!/bin/bash
TARGET_DIR="/data/downloads"
if [ ! -d "$TARGET_DIR" ]; then
echo "Creating directory $TARGET_DIR"
mkdir -p "$TARGET_DIR" || exit 1
fi
curl -o "$TARGET_DIR/package.zip" https://example.com/package.zip || {
echo "Download failed" >&2
exit 1
}
On Windows, pay attention to path formatting:
# Windows path example (note forward slashes still work)
curl -o C:/Downloads/file.zip https://example.com/file.zip