Understanding Shell Script Position Parameters and Special Variables

Position Parameters

When executing a Shell script, you can pass arguments to it. These arguments are accessible inside the script using the $n syntax—$1 represents the first argument, $2 the second, and so on.

The same mechanism applies to function parameters. Shell handles function arguments differently from most programming languages: you don't declare parameter names or count when defining a function, but you can pass arguments when calling it. Inside the function, these arguments are accessed using $n notation.

For arguments numbered 10 or higher, use ${n} syntax (like ${10} or ${23}). The braces help the interpreter determine where the parameter name ends, similar to variable expansion with braces.

While variable names typical start with letters or underscores (not numbers), position parameters are numeric. This makes them "special variables" distinct from regular variables. Beyond $n, Shell provides several other special parameters: $#, $*, $@, $?, and $$.

Scenario Script Output
Passing arguments to a script ```bash
#demo.sh

#!/bin/bash echo "Framework: $1" echo "Port: $2" | Running `bash demo.sh Python 8080`<br><br>Framework: Python<br>Port: 8080 | | Passing arguments to a function |bash #demo.sh

#!/bin/bash show_info(){ echo "Framework: $1" echo "Port: $2" }

show_info Rust 3000 ``` | Running bash demo.shFramework: RustPort: 3000 |

Other Special Variables

Variable Description
$0 Current script's filename
$n (n≥1) Arguments passed to the script or function. n indicates position (first argument is $1, second is $2)
$# Count of arguments passed
$* All arguments passed
$@ All arguments passed. Differs from $* when enclosed in double quotes (explained below)
$? Exit status of the previous command or return value of a function
$$ Current shell process ID. For scripts, this is the process ID where the script runs

Practical Examples

#!/bin/bash
echo '=========Special Variables Demo========='
echo "Script name: ${0}"
echo "Argument 1: ${1}"
echo "Argument 2: ${2}"
echo "All arguments: $*"
echo "Argument count: $#"
echo "Process ID: $$"
echo "Parent Process ID: $PPID"

Running bash demo.sh golang redis:

=========Special Variables Demo=========
Script name: demo.sh
Argument 1: golang
Argument 2: redis
All arguments: golang redis
Argument count: 2
Process ID: 48291
Parent Process ID: 36102

Difference Between $* and $@

Both $* and $@ represent all arguments passed. Without double quotes, they behave identically—each argument is treated as a separate unit, separated by spaces.

With double quotes, they diverge:

  • "$*" treats all arguments as a single unit (one string)
  • "$@" preserves each argument as a separate unit (multiple strings)

For two arguments, "$*" merges them into one data item; "$@" keeps them as two independent items.

Direct echo output won't reveal this difference. Using a for loop demonstrates it clearly.

#!/bin/bash
echo 'Iterating with "$*"'
for item in "$*"; do
    echo "[$item]"
done

echo 'Iterating with $*'
for item in $*; do
    echo "[$item]"
done

echo 'Iterating with "$@"'
for item in "$@"; do
    echo "[$item]"
done

echo 'Iterating with $@'
for item in $@; do
    echo "[$item]"
done

Running bash demo.sh server db:

Iterating with "$*"
[server db]
Iterating with $*
[server]
[db]
Iterating with "$@"'
[server]
[db]
Iterating with $@
[server]
[db]

The "$*" iteration runs once because it contains one combined string. The "$@" iteration runs twice because it holds two separate strings. In essence, "$*" treats all arguments as a single entity, while $*, $@, and "$@" treat each argument independently.

Using $?

The $? variable retrieves the exit status of the previous command or the return valuee from a function. Exit status is a numeric code indicating command completion: most commands return 0 for success and 1 for failure.

Scenario Script Explanation
Getting command exit status ```bash
#!/bin/bash
if [ "$1" -eq 200 ]; then
exit 0

else exit 1 fi | `exit` terminates the current shell process. Run the script in a subprocess so the terminal session remains open to check the status. <br><br>Execute `bash demo.sh 200`<br>Check `echo $?` → outputs `0`<br><br>Execute `bash demo.sh 404`<br>Check `echo $?` → outputs `1` | | Getting function return value |bash #!/bin/bash multiply(){ return $(($1 * $2)) } multiply 8 9 echo $? ``` | Running the script outputs 72 |

The return keyword in Shell functions specifies the exit status, not a return value in the traditional sense. Shell lacks dedicated syntax for returning values—programs communicate results through exit codes.

Tags: Shell bash position parameters special variables Scripting

Posted on Thu, 22 Oct 2026 16:24:36 +0000 by igorlopez