Fall 2015 - September to December 2015 - Updated 2018-01-21 09:59 EST
Could you explain to me the difference between an option and an argument?
The usage depends on whether you are looking at a command line from the point of view of the Unix shell or from the point of view of the command that the shell is finding and running for you.
For example, you might type this command line into a Unix shell:
$ ls -l -i -s a b c
The shell knows nothing about how the ls
command works. The shell only knows that you want to find and run the ls
command (the first string on the command line) and you are providing six other strings as “arguments” to that ls
command: -l -i -s a b c
. So the correct answer here, from the point of view of the shell, is: the shell is giving the ls
command six arguments from the command line. Each “argument” is separated by one or more blanks from its neighbour; the shell finds six of them.
However, from the point of view of the ls
command receiving the six “arguments”, three of those arguments are interpreted by the ls
command as options; because, three of the arguments start with dashes and dashes are interpreted by the ls
command as options. So the correct answer from the point of view of the ls
command, is: the ls command is interpreting the six command line arguments as three option arguments and three pathname arguments. This is often simplified to say “the ls command is receiving three options and three arguments”, but of course all six strings are really arguments.
So, from the point of view of the shell, there are six blank-separated “arguments” parsed and passed to the ls
command.
From the point of view of the ls
command, three of those received six arguments (the three starting with dashes) are going to be interpreted as option arguments that change how ls
operates, which leaves three pathname arguments to operate on.
To summarize the command line as seen by the shell and then by the ls
command:
$ ls -l -i -s a b c
Shell: six blank-separated arguments on the command line are passed to "ls"
ls: sees three option arguments (leading dashes) and three pathname arguments
It is up to the command to distinguish options from other types of arguments.
Look at this similar command line:
$ echo -l -i -s a b c
The above command line is identical to the ls
command line example above, except that it uses echo
instead of ls
as the command name to be found by the shell, and it has some extra blanks between the six arguments.
In the above echo
example, the number of arguments counted from the point of view of the shell (six) does not change. The command name doesn’t matter to the shell – there are still six blank-separated arguments on the command line that are being passed to whatever command you are typing, whether it be ls
or echo
or anything else. The shell still parses six blank-separated arguments. The extra blanks in the line are ignored by the shell – one blank is the same as a hundred blanks. Blanks simply separate arguments.
However, from the point of view of the echo
command, there are no options in this argument list; because, the echo
command does not treat the strings -l
or -i
or -s
as options! None of those strings is a valid option to the echo
command. All six strings are treated as ordinary “arguments” by the echo
command; all six strings are echoed to your terminal. The blanks aren’t part of the arguments; the echo
command doesn’t even see them because the shell stripped them away when it isolated the six command line arguments.
To summarize the command line as seen by the shell and then by the echo
command:
$ echo -l -i -s a b c
Shell: six blank-separated arguments on the command line are passed to "echo"
echo: sees six arguments received from the command line (no options)
It is up to the command to distinguish options from other types of arguments. The echo
command does not treat any of those arguments as options.
Whether an argument (a string, a token) on the command line is interpreted by a Unix command as an option or a plain argument depends on the command doing the interpretation.
In this course, we will look at command lines from both the point of view of the shell and the point of view of the command being found and run by the shell:
I will ask you “how many arguments is the shell passing to the ls
command in the above example” and you will answer “six arguments”.
I will ask you “how many of the arguments seen by ls
are option arguments in the above example” and you will answer “three”.
I will ask you “how many arguments is the shell passing to the echo
command in the above example” and you will answer “six arguments”.
I will ask you “how many of the arguments seen by echo
are option arguments in the above example” and you will answer “none”.
You asked about the syntax given in the man page for the Unix “who” command:
usage: who [OPTION] . . . [FILE | ARG1 ARG2]
It is using both the words “option” and “arg”. Am I right in assuming that an option is more like a flag to attach to a command to get more specific results? But then, so is an argument.
Yes, an option is a flag (or “switch” in DOS terms). It changes how the command operates. An “argument”, from the point of view of the command, is a thing on which the command operates, such as a pathname, userid, string, etc. For example:
$ ls a b c
From the point of view of both the shell and the ls
command, the above command line has three blank-separated pathname arguments. Now, insert a fourth string (fourth argument) to the command line:
$ ls -i a b c
From the point of view of the ls
command, the new example still has only three pathname arguments. There are still three pathnames that will be shown to you by ls
. There is now one option argument that changes the output of ls
to also include inode numbers.
In short, from the point of view of the Unix shell, because it knows nothing about how a command functions internally, everything on the command line after the command name is called “an argument” – above, the shell parses “four arguments”.
From the point of view of the command ls
that the shell finds and runs, some of those command line arguments may be interpreted as options – it depends on the command. Above, the ls
command sees “one option” and “three pathname arguments”.
Additional material (background for C programmers):
In C programming (the language of Unix), the main()
routine in a program such as ls
receives all the command line arguments as follows:
main(int argc, char **argv){
You may recognize this as a count of how many command-line arguments there are followed by an array of pointers to strings. So, at the programming interface, the command name and all the words that follow the command name on the command line are treated as “arguments” in this array. This is the same point of view as the shell – all the command line arguments are called “arguments”; except, in main()
, even the command name is one of the “arguments” here in the argv
array. At this point, at the beginning of main()
function inside the ls
command, we haven’t yet analysed the argv
strings to see which ones might be options (which ones start with dashes).
For example, you might type this into a Unix shell:
$ ls -l -i -s a b c
and the list of strings passed to the ls
command in the argv
array would contain seven array elements: the command name ls
plus six string “arguments”: -l -i -s a b c
.
The code for ls
will have to loop through the char **argv
list and identify which arguments are options (starting with a dash) and which are plain pathname arguments. This is why options usually start with a dash – it makes them easy to identify on the command line.
Different Unix commands have different rules for interpreting which command line arguments are options and which are not. A leading dash is almost always an option argument and not a plain argument. (The echo
command is one of the common exceptions!) Some commands also use plus signs for options.
To a Unix shell, all the tokens on a command line are “arguments”. To a particular command, some might be option arguments that affect how a command works.