리눅스 명령행 인자: 명령어 옵션과 따옴표, 옵션 끝 표시, $1, $# 받기
Linux command-line arguments are values you pass to a program by writing them after the command name, separated by spaces. We passed options, quotes, wildcards, and -- to a test script that prints back the arguments it receives on an AlmaLinux 9 server: splitting the arguments was done by the shell, and reading the options was done by each command.
The output below is exactly what we got running bash 5.1 as root on an AlmaLinux 9.8 server. The test scripts and sample files were created in a separate working folder, and the path /home/user/www is an example value.
1️⃣ What Are Linux Command-Line Arguments?
When you type something like [command arg1 arg2] on the command line, the shell splits it into words at the spaces. The first word becomes the program to run, and the remaining words are passed to that program as its arguments, in order.
To see the passed arguments, we created args.sh in the working folder. $0 holds the name used to run it, $# holds the number of arguments, and $1 onward hold the arguments in order. The square brackets were added to show where each argument begins and ends.
#!/bin/bash
echo "\$0 = $0"
echo "\$# = $#"
i=1
for a in "$@"; do
echo "\$$i = [$a]"
i=$((i+1))
doneWe gave the script execute permission and ran it with three words: a, b, and c.
./args.sh a b c$0 = ./args.sh
$# = 3
$1 = [a]
$2 = [b]
$3 = [c]The three words went into $1, $2, and $3, and $# was 3. If you run the script by writing its name after bash, $0 holds the name exactly as written, args.sh.
bash args.sh a b c$0 = args.sh
$# = 3
$1 = [a]
$2 = [b]
$3 = [c]Only $0 changed to args.sh; the three arguments and the count were the same as before.
2️⃣ Command-Line Arguments and Command Options
Linux commands are usually written in the order [command -option argument]. Options change how the command behaves, and arguments specify the files, paths, or values the command works on.
ls -l /home/user/wwwTo the shell, -l is just another argument. When we passed the same words to args.sh, -l went into $1 and the path into $2.
./args.sh -l /home/user/www$0 = ./args.sh
$# = 2
$1 = [-l]
$2 = [/home/user/www]Reading -l as an option is the job of ls. That is why the same letter means different things in different commands: -n in head sets the number of lines to print, while -n in ls prints owners as numbers instead of names.
Some options take the word right after them as their own value. In the find command, -type takes f and -name takes "*.txt" as its value; a value attached to an option like this is called an option argument.
find . -type f -name "*.txt"In this command, the leading . is an argument not attached to any option, and it sets the folder where the search starts.
3️⃣ Linux Command Option Formats
Short options start with a single dash and are one letter long, and several of them can be written together. First, we listed the site folder in the working folder with [ls -l -a].
ls -l -a sitetotal 8
drwxr-xr-x 3 root root 52 Oct 28 16:00 .
drwxr-xr-x 3 root root 137 Oct 29 01:20 ..
-rw-r--r-- 1 root root 17 Oct 28 16:00 .htaccess
drwxr-xr-x 2 root root 23 Oct 28 16:00 css
-rw-r--r-- 1 root root 14 Oct 28 16:00 index.htmlNext, we compared it with diff against the output of [ls -la], which joins the two letters.
diff <(ls -l -a site) <(ls -la site) && echo samesameThe two outputs did not differ by a single character. Long options start with two dashes and are written as words; --all in ls is the same option as -a, so [ls -l --all site] gave the same result as well.
Long options are accepted even if you write only the beginning, as long as it matches just one option. --al matched two options, --all and --almost-all, so ls printed no listing and exited with code 2.
ls --al sitels: option '--al' is ambiguous; possibilities: '--all' '--almost-all'
Try 'ls --help' for more information.Options that take a value can be written in several forms. When printing the first two lines of a.txt with head, a short option can have its value attached, as in [-n2].
head -n2 a.txtalpha
betaA long option joins its value with an equals sign, as in [--lines=2].
head --lines=2 a.txtalpha
betaAll four forms, including the space-separated [-n 2] and [--lines 2], printed the two lines alpha and beta.
ls, head, and cat read their options with the getopt_long function of the C library. Looking at the three program files with strings showed that each contained this function name.
To check the same rules from the shell, use the getopt command from util-linux. Write the short options after -o and the long options after -l; a colon after a letter means the option takes a value.
getopt -o lan: -l all,lines: -- -la -n 2 --all a.txt -l -a -n '2' --all -- 'a.txt'The joined -la was split into -l and -a, and -n 2 was grouped as -n with the value 2. a.txt, which is not an option, was moved to the end after --.
4️⃣ Quoted Command-Line Arguments and Wildcards
A file name containing a space must be wrapped in quotes to be passed as a single argument.
./args.sh "my file.txt" report.txt$0 = ./args.sh
$# = 2
$1 = [my file.txt]
$2 = [report.txt]Without quotes, my and file.txt were split apart and $# became 3. If you pass it this way to ls or cat, they will look for two files named my and file.txt.
./args.sh my file.txt report.txt$0 = ./args.sh
$# = 3
$1 = [my]
$2 = [file.txt]
$3 = [report.txt]Wildcards are turned into file names by the shell before the program receives them. When we passed *.txt in the working folder, the four files ending in .txt went in, sorted by name.
./args.sh *.txt$0 = ./args.sh
$# = 4
$1 = [a.txt]
$2 = [b.txt]
$3 = [my file.txt]
$4 = [report.txt]The quoted "*.txt" was not expanded by the shell and became a single argument, character for character. For options such as find's -name, where the program compares the pattern itself, pass the pattern quoted like this.
./args.sh "*.txt"$0 = ./args.sh
$# = 1
$1 = [*.txt]Empty quotes are also passed as one empty argument. Running [./args.sh '' b] gave $# as 2, with $1 empty.
5️⃣ End of Command Options (--)
An argument that starts with a dash, such as a file named -n, is read by the command as an option. When we ran [ls -n] in the dash folder, which holds only that one file, ls took -n not as a file name but as the numeric-output option and listed the folder.
ls -ntotal 4
-rw-r--r-- 1 0 0 10 Oct 28 16:00 -nArguments written after -- are not read as options, even if they start with a dash. [ls -- -n] printed only the file name -n.
ls -- -n-nWithin a single command, the same characters are read differently before and after --. When we passed -n to cat twice, the first -n was read as the line-number option and the -n after -- as a file name, so the file's contents came out with line numbers.
cat -n -- -n 1 dash fileYou can also add a path and write it as ./-n; then the argument does not start with a dash and is read as the same -n file.
Reading -- as the end of options is also a rule on the command's side. When we passed it to args.sh, which does not read options, -- went into $1 as is.
./args.sh -- -a$0 = ./args.sh
$# = 2
$1 = [--]
$2 = [-a]The POSIX Utility Conventions specify that the first -- that is not an option argument is accepted as the end of options. That is why, with commands that follow these conventions, file names starting with - are written after --.
6️⃣ Reading Command-Line Arguments in a Shell Script
A shell script reads the arguments it receives through positional parameters and special parameters. The main(int argc, char *argv[]) of a C program receives the same arguments, so placing the two side by side looks like this.
| Parameter | Value it holds | C main function |
|---|---|---|
| $0 | Name of the script that was run | argv[0] |
| $1 ~ $9 | First through ninth arguments | argv[1] ~ argv[9] |
| ${10} | From the tenth argument on, wrap in braces | argv[10] |
| $# | Number of arguments, not counting $0 | argc - 1 |
| "$@" | All arguments, each one separate | argv[1] through the end |
| "$*" | All arguments joined into one with spaces | — |
A Python program receives the same arguments as the sys.argv list. Passing three arguments with [python3 -c] showed the quoted my file.txt going into a single item of the list, and -c going into the first item.
python3 -c 'import sys; print(sys.argv)' a "my file.txt" -l['-c', 'a', 'my file.txt', '-l']"$@" and "$*" give different results when wrapped in double quotes. To see the difference, we created star.sh, which prints the two forms one after the other.
#!/bin/bash
echo 'with "$@"'
printf ' [%s]\n' "$@"
echo 'with "$*"'
printf ' [%s]\n' "$*"We ran star.sh with three arguments: a, "b c", and d.
./star.sh a "b c" dwith "$@"
[a]
[b c]
[d]
with "$*"
[a b c d]"$@" passed the three arguments separately, while "$*" joined them with spaces and passed them as one.
So when you pass the received arguments on to another command unchanged, use "$@".
shift discards $1 and moves the remaining arguments forward by one position. It is used in scripts that read one option first and treat the rest as a list of files.
We created shift.sh, which prints $1 and $# before and after shift.
#!/bin/bash
echo "before shift: \$1 = $1, \$# = $#"
shift
echo "after shift: \$1 = $1, \$# = $#"We ran shift.sh with three arguments: -v, a.txt, and b.txt.
./shift.sh -v a.txt b.txtbefore shift: $1 = -v, $# = 3
after shift: $1 = a.txt, $# = 2From the tenth argument on, wrap the number in braces, as in ${10}. We created ten.sh, which prints $10 and ${10} side by side.
#!/bin/bash
echo "\$10 = $10"
echo "\${10} = ${10}"We passed 11 arguments, a through k, to ten.sh.
./ten.sh a b c d e f g h i j k$10 = a0
${10} = j$10 came out as a0, $1 followed by a 0, while ${10} came out as the tenth argument, j.
🔲 Command-Line Argument Simulator
In the simulator below, you can pass quotes, wildcards, and -- to args.sh, and also type commands yourself to see how ls and getopt read options and how star.sh and shift.sh receive arguments.
🔢 FAQ & Recommended Content
Wildcards
[Shell Special Characters] Linux Wildcards (Metacharacters)
A summary, with examples, of how to pick out file names with wildcard matching characters such as * and ? and with character classes.
Multiple commands
[Linux] 5 Ways to Chain Commands (Semicolon, Pipe, Ampersand..)
A summary of five ways to run several commands on one line with semicolons, pipes, &&, ||, and &.
Printing strings
echo Command: From Expansion and Quoting
A summary of how to print strings and variable values with echo, and of its options.
ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.