0

From POSIX 2013:

A ‘‘simple command’’ is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.

From Bash Manual:

A simple command is the kind of command encountered most often. It’s just words separated by blanks, terminated by one of the shell’s control operators.

I feel the definition from POSIX is better than the one from Bash manual. But still I am not sure about the POSIX's definition:

  • If I am correct, the terminating control operator of a simple command doesn't belong to the command, or does it?

  • Do two "redirections" in the definition belong to the simple command?

  • What does "redirections" do after variable assignments, in "a sequence of optional variable assignments and redirections"? Variable assignments don't write to stdout or stderr, right?

  • What does "in any sequence" in "a sequence of optional variable assignments and redirections, in any sequence" mean?

  • How many possibilities does the definition suggest for a simple command, and what are they?

  • Are POSIX's and Bash's concepts of a simple command the same?

2
  • Just the English by itself says that the first redirections belongs to the simple command, and the other parts (redirections and control operator) do not, since a distinction is made in the sentence. You might find some additional wording in the standard which does not agree with that plain statement however. Mar 22, 2016 at 0:54
  • 2
    If it said the redirections weren't part of the simple command, it would also be saying that the command wasn't part of the simple command (that's what the "words" are). Mar 22, 2016 at 0:58

3 Answers 3

3

Adding to Greg's answer:

  1. Yes, the two groups of redirections belong to the same simple command.

    When I run a command with input (stdin) and output (stdout) redirected, I do it like this:

    cmd  arg1  arg2  < file1  > file2

    Some people (a vocal minority) advocate the

    < file1  cmd  arg1  arg2  > file2

    variation, because they believe that it's more intuitive to specify the input, then the action, and then the output.  But the following are all equivalent:

    < file1  > file2  cmd  arg1  arg2
    > file2  cmd  arg1  arg2  < file1
    cmd  > file2  arg1  < file1  arg2

    Don't use any of the above; they are presented as bad examples.

    The point is that redirections can appear before or after the first word of the command (or any word in the command), but that they are treated the same.

  2. Variable assignment(s) may come before the command, to set environment variable(s) just for the duration (scope) of that command.  For example,

    TZ=GMT0 ls -l

    lists your files, showing modification time in Greenwich Mean Time.  "optional variable assignments and redirections, in any sequence" means that

    TZ=GMT0 ls -l > ls_output_file
    TZ=GMT0 > ls_output_file ls -l
    > ls_output_file TZ=GMT0 ls -l

    are all equivalent.  Again, don't use any of these except for the first.

    The point is that variable assignments cannot appear after the first word of the command; if they do, they will be treated as arguments to the command.  For example, look at the syntax of dd.

    Variable assignments don't write to stdout or stderr, right?

    Simple, constant data assignments do not do any processing (bookkeeping within the shell doesn't count).  But command substitution runs a command; CURRENT_DATE=$(date +%Y%m%d) runs the command date +%Y%m%d with its stdout redirected to a pipe to the shell, which captures the output and embeds it into the command line.  But the stderr of the date command is still the stderr of the shell; if you say OLD_DATE=$(date --date"three days ago"), you will get an error message on the screen, because date doesn't support that syntax for specifying the date.  Of course you can suppress that if you say

    OLD_DATE=$(date --date"three days ago" 2> /dev/null)

    but not if you say

    OLD_DATE=$(date --date"three days ago")  2> /dev/null

    or

    2> /dev/null  OLD_DATE=$(date --date"three days ago")
  3. "in any sequence" refers to the last thing I said, and also the fact that

    TZ=GMT0 COLUMNS=132 ls -l

    is equivalent to

    COLUMNS=132 TZ=GMT0 ls -l

    (There may be bizarre edge cases; let's not venture there.)

1
  • Well, a weird fact, almost never used, and mostly ignored is that the set option -k allows the placement of assignments after the command or arguments. Quote: If the -k option is set (see the set builtin command below), then all parameter assignments are placed in the environment for a command, not just those that precede the command name.. In POSIX, the option is defined but removed, some shells may still carry the option (even if it is a bad idea to use it).
    – user79743
    Mar 22, 2016 at 17:56
2

The bash manual definition is, at least, a more straightforward definition. Redirection is a feature separate from, but related to, the type of command. Redirections belong to the command in the sense that they affect the specific command they are associated with, but they can also appear with complex commands (in subshells or groups or pipes). The POSIX definition is jamming a lot of concepts into a small space, where separating them out (as the bash man page does) might be easier to understand. Having said that...

  • The terminating control operator is not part of the command, it separates the simple command from other simple commands.

  • The redirections belong to the simple command and there there can be more than two.

  • Redirections are somewhat independent of the command text, though the order is important when you start copying descriptors. For your example, I am going to skip that concept.

    a=5 5> out5.file some-command > out.file arg1 2> out2.file arg 3> out3.file

    would be a valid simple command. The redirections can appear interspersed with the arguments and be in any order.

  • How many possibilities? Not sure what you are asking here. There are lots of commands and infinite combinations of arguments and all kinds of redirections, so lots of possibilities.

  • Yes, they are the same, but POSIX is mixing in the concept of redirection into the definition.

The bash man page is a good resource. My favorite resource, though, is the GNU Bash Reference Manual on the GNU.org site. It is a good progression and well-written with very little repetition. Take a look there at the Simple Command definitions and the redirection sections for more details on all of this.

4
  • Thanks. (1) What does "redirections" do after variable assignments, in "a sequence of optional variable assignments and redirections"? Variable assignments don't write to stdout or stderr, right? (2) What does "in any sequence" in "a sequence of optional variable assignments and redirections, in any sequence" mean?
    – Tim
    Mar 22, 2016 at 1:45
  • The variable assignments are not really affected by redirections. To really get a good sense of when order matters with redirections you should do some experiments. See how many permutations you can make for a command that takes its stdin (<) from one file and puts its stdout (>)to another and its stderr (2>) to a third and still get the same output. 10 minutes of programming/scripting is worth an hour of reading.
    – Greg Tarsa
    Mar 22, 2016 at 21:56
  • I guess you misunderstood my questions. I know the order between multiple redirections matters. The questions in my previous comment are not about them.
    – Tim
    Mar 23, 2016 at 4:37
  • Can you amplify on your question, then? Part of the problem here is that Posix is merging redirection into the definition of simple command, where the bash sources treat redirection separately. The bash approach resonates with me as redirection is a concept and its addition IMHO complicates the POSIX definition. Variable assignments are actually named parameters (like $1, $2, $3, etc) and affect the command only. So it makes sense to consider them as part of the simple command.
    – Greg Tarsa
    Mar 23, 2016 at 15:29
1

Just addressing your bulleted questions as they appear:

the terminating control operator of a simple command doesn't belong to the command, or does it?

Well, no. But it is part of the syntax that delimitate the "simple command". A "simple command" without proper control delimiters will not be correctly recognized as such by the shell.
If what you ask is if the delimiter control character is execute when the command is executed, then: no. The delimiters are not part of the executed command.

Do two "redirections" in the definition belong to the simple command?

Technically, no: redirections affect the environment inside which a command is executed, thus: not "exactly" part of the command. But also technically, they do affect the command being executed by changing its environment.

So, someone might say: "sort of".

What does "redirections" do after variable assignments, in "a sequence of optional variable assignments and redirections"? Variable assignments don't write to stdout or stderr, right?

Gee, that's a mouthful. Let's break it in parts:

What does "redirections" do after variable assignments,

Exactly the same as before, in the middle, at the end or on any part of the whole command line. In short: position does not affect how redirections work.

With a BIG caveat: the order of redirections themselves do change the effect they have on the command. In short, it is not the same >file 2>&1 as 2>&1 >file. So: watch out!.

You may want to read:

  1. In the shell, what does “ 2>&1 ” mean?
  2. 8.13 Is It "2>&1 file" or "> file 2>&1"? Why?

in "a sequence of optional variable assignments and redirections"?

Optional here means that there may be one, two, ... five, etc or none.
There may be no redirection or variable assignment in the command line.
It is "optional".

Variable assignments don't write to stdout or stderr, right?

No, of course not, they simply change the value of a shell variable.
And, if they precede a command, they usually affect the environment of the command and then the change is fold back (again, usually) when the command ends.

What does "in any sequence" in "a sequence of optional variable assignments and redirections, in any sequence" mean?

The order from left to right is the sequence. No, it is not exactly the same that assignments and/or redirections are placed in any order.
In a nut-shell: 99.99% of the time you want variable assignments before the command. With the caveat written above that the internal order of redirections does matter. Redirections may (but I do not recommend you to play with them, will make reading the command line confusing) be placed anywhere (inside the limits of the control characters used).

How many possibilities does the definition suggest for a simple command,

Possibilities? Endless. For example, let's assume:

  1. No repetition on any of the options (the smaller count).
  2. Possible command names: 10 (pick only one each time).
  3. Possible redirections: 5 (yes, there are 10 basic ones and, many times, up to 99 possible file descriptors) Let's pick just 5 from the ten (order matters).
  4. Possible arguments: Let's take 3 from just 20 possible (order may matter to the command, not always, lets pick the lowest number of options and say that order does not matter).
  5. Variable assignements? let's take 3 from 10 possible variables. (yes, a very low number).

    1C10 * 5P10 * 3C20 * 3C10 = 10 * 10!/(10-5)! * 20!/((20-3)!*3!) * 10!/((10-3)!3!) = 41,368,320,000

If my math is correct. And that is not counting the intermixing of words that could be done. Just a KISS calculation.

In any case, it is a huge lot of options.

and what are they?

I can not list them in a short answer. But even if I can, is it worth it?

Frankly, Tim, do not try to squeeze every last drop of this lemon, I am sure it will not be beneficial to your health :-). Just saying!.

Are POSIX's and Bash's concepts of a simple command the same?

Probably yes (with variations caused by what language is used by the person interpreting them). Again, not worth the effort of squeezing every drop.

1
  • The possibilities are not endless but finite, limited by the number of different acceptable characters to the power of maximal possible length. It would be better to say "practically" or "virtually endless" or similar. Even if the number of possibilities is extremely huge, it remains negligibly small w.r.t infinity, and even w.r.t. large numbers computer scientists deal with, e.g. Grahams number.
    – Max
    May 3, 2019 at 22:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .