In Unix/Linux shells, the difference between single-dash (-
) and double-dash (--
) flags isn't arbitrary - it follows specific conventions:
# Single-letter options (can be combined)
ls -l -a # Equivalent to
ls -la
# Full-word options (must be separate)
git commit --message "Update" # Cannot combine with other options
The single-dash convention originated from early Unix systems where parsing efficiency mattered. Double-dash emerged later for better readability:
# Classic Unix style (single-dash)
tar -xzvf archive.tar.gz
# GNU style (allowing both)
grep --ignore-case --after-context=2 "pattern" file.txt
Most command-line parsers follow these rules:
- Single-dash: Typically followed by single letters (
-h
,-v
) - Double-dash: For full words (
--help
,--version
)
#!/bin/bash
# Example argument parsing
while [[ "$#" -gt 0 ]]; do
case $1 in
-v|--verbose) verbose=1 ;;
-f|--file) shift; filename="$1" ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
shift
done
Modern best practices:
- Use single-dash for common, frequently used options
- Use double-dash for less common, more descriptive options
- Consider implementing both forms for important options
# Good practice example
rsync -avz --progress --delete /source/ user@host:/dest/
Watch for:
- Commands using single-dash for arguments (
find -name
) - Double-dash used as argument terminator (
grep -- -v file
searches for "-v")
# Using -- to stop option parsing
rm -- -filename-with-dash
In Unix/Linux systems, command line flags evolved from two distinct traditions. Single-dash flags (-h) originated from early Unix commands where single letters were used for options. Double-dash flags (--help) came later with GNU utilities, allowing more descriptive option names.
# Single dash examples (traditional)
ls -l -a -h
grep -i "pattern" file.txt
tar -xzvf archive.tar.gz
# Double dash examples (GNU style)
ls --all --human-readable
grep --ignore-case "pattern" file.txt
ssh --verbose user@host
Single-dash flags can often be combined:
ls -lah
is equivalent to ls -l -a -h
Double-dash flags typically require full separation:
git commit --amend --no-edit
cannot be combined
# Short options (single character) use single dash
find . -name "*.txt" -type f -mtime +7
# Long options (descriptive) use double dash
docker run --detach --name my_container image:tag
Some commands implement both styles for the same option:
grep --ignore-case
and grep -i
do the same thing
The double-dash by itself signals end of options:
rm -- -filename-with-dash
Certain commands break these conventions. For example, the ps
command uses BSD-style options without dashes:
ps aux
Meanwhile, X11 applications often use single dash for long options:
xterm -bg black -fg white
- Use single-dash for short, common options you'll type frequently
- Use double-dash for more explicit, self-documenting commands in scripts
- Always check
man
pages for command-specific variations
# Example showing both styles together
ffmpeg -i input.mp4 --video-codec libx264 --crf 23 output.mp4