<span>shift</span> is a built-in command in <span>Bash</span> that shifts the positional parameters to the left, reassigning the values of <span>$1</span>, <span>$2</span>, <span>$3</span>, etc.
$ bash -c "help shift"
shift: shift [n]
The positional parameters from $N+1 ... are renamed to $1 ... If N is
not given, it is assumed to be 1.
It is a core tool for handling <span>command line arguments</span>.
shift [n] # n is the number of positions to shift, default is 1, indexing starts at 1.
1. Quick Start
First, let’s introduce two special variables in <span>Bash</span>: <span>$@</span><span>$#</span>:
| Variable | Meaning | Example (./test.sh a “b c” d) |
|---|---|---|
| $# | Number of parameters | 3 |
| $@ | All parameters | a “b c” d (3 independent parameters) |
<span>test.sh</span> file content is as follows:
# Original parameters
echo "All parameters: $@"
echo "Number of parameters: $#"
echo "\$1: $1, \$2: $2, \$3: $3, \$4: $4"
# Shift left by one position
shift
echo "Parameters after shift: $@"
echo "Number of parameters after shift: $#"
echo "\$1: $1, \$2: $2, \$3: $3, \$4: $4"
<span>Run it like this:</span>
$ work ./test.sh -a 1 -b 2
All parameters: -a 1 -b 2
Number of parameters: 4
\$1: -a, \$2: 1, \$3: -b, \$4: 2
Parameters after shift: 1 -b 2
Number of parameters after shift: 3
\$1: 1, \$2: -b, \$3: 2, \$4:
<span>The effect of the shift command is similar to:</span>
| Command | $1 | $2 | $3 | $4 | $# | $@ |
|---|---|---|---|---|---|---|
| Initial | arg1 | arg2 | arg3 | arg4 | 4 | arg1 arg2 arg3 arg4 |
| shift | arg2 | arg3 | arg4 | empty | 3 | arg2 arg3 arg4 |
| shift 3 | empty | empty | empty | empty | 0 | empty |
2. Template Code for Parsing Command Line Arguments
# Default values
verbose=false
output_dir="."
files=()
# Show help
show_help() {
echo "Usage: $0 [options] [files...]"
echo "Options:"
echo " -h, --help Show help"
echo " -v, --verbose Verbose output"
echo " -o, --output Output directory"
}
# Parse parameters
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
show_help
exit 0
;;
-v|--verbose)
verbose=true
echo "Verbose mode: enabled"
shift
;;
-o|--output)
output_dir="$2"
echo "Output directory: $output_dir"
shift 2
;;
-* )
echo "Error: Unknown option $1" >&2
exit 1
;;
*)
files+=("$1")
shift
;;
esac
done
# Process files
if [ ${#files[@]} -eq 0 ]; then
echo "Error: No files specified" >&2
exit 1
fi
echo "Starting to process ${#files[@]} files:"
for file in "${files[@]}"; do
if [ -f "$file" ]; then
echo "Processing: $file"
# Here you can add actual file processing logic
# For example: cp "$file" "$output_dir/"
else
echo "Warning: File does not exist $file"
fi
done
echo "Processing complete"
Save the above code to a file: <span>util.sh</span>, and then test it:
# Basic usage
./util.sh file1.txt file2.txt
# With options
./util.sh -v -o ./output file1.txt file2.txt
# Show help
./util.sh --help
Ok. I believe you have learned how to use it.