Home > OS >  Why ”false -a true“ and "true -a false" in shell return a different results?
Why ”false -a true“ and "true -a false" in shell return a different results?

Time:07-06

IMO, -a and && are all and operation in shell, so I assume true -a false and false -a true would both return "false". Well the fact is

[root@master ~] true -a false
[root@master ~] echo $?
0
[root@master ~] false -a true
[root@master ~] echo $?
1
[root@master ~] a=[ true -a false ]
[root@master ~] echo $a
true
[root@master ~] a=[ false -a true ]
[root@master ~] echo $a
true

Why did this happen, and what should I do if I want to operate and in Shell?

CodePudding user response:

Let's the general syntax of a command in shell is:

[var=val...] cmd [args...]

The var=val are exporting environment variable var with the value val for the duration of command cmd.

Why did this happen

Both commands true and false ignore arguments. true anything exits with 0 exit status, false anything exits with non-zero exit status. true -a false executes command true with two arguments, sting -a and string false. true ignores arguments, exits with zero exit status. The same for false.

a=[ exports a variable a with the value of string [ to the environment of the next command.

$ a=[ env | grep '^a='
a=[

a=[ true -a false ] set's environment variable a to the value of string [ and then executes command true with 3 arguments string -a, the string false and the string ].

  a=[ true -a false ]
  |   |    |  |     \----  third argument
  |   |    |  \----------  second argument
  |   |    \-------------  first argument
  |   \------------------  command to execute
  \----------------------  var=val, exports a variable

true ignores the arguments and true once again, exits with exit status 0. The same is for false, with non-zero exit status.

The value echo $a that shows true is the value that you previously have set in your shell. The a=[ true ... only set's the variable a for the duraction of the command, after that the variable has it's own value.

$ a=anything_here
$ a=anything_here2 true anything_here3
$ echo $?
0               # true exits with 0 exit status
$ echo $a
anything_here   # the variable `a` preserved its value set before the command

Why ”false -a true“ and "true -a false" in shell return a different results?

Because commands false and true exit with different exit status.

Note: the strings true false [ ] -a have no special meaning for shell. These are all strings. The string -a and ] have special meaning when passed as an argument for the command [. It's still the string -a, but when the executable [ is executed, it parses the arguments and acts specially on the string -a. There happen to be executables named true and false. The strings [, ], true, false or -a by itself have no significant for shell, these are all just strings.

-a and && are all and operation in shell,

No, -a is the string -a in shell. && is an "and" operation in shell. -a is the "and" operator for [ or test commands. Note: because of problems with [, prefer to use [ ... ] && [ ... ] instead of [ ... -a ... ].

References: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/test.html , https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Simple-Command-Expansion , https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/true.html , https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/false.html , https://pubs.opengroup.org/onlinepubs/009604499/utilities/xcu_chap02.html#tag_02_09_01 .

CodePudding user response:

Thanks for KamilCuk's answer. After reading that ,here's my shorter version.

true -a false and false -a true is just a command who contains two arguments( -a [false/true]). Its exit code depend on the command itself which return 0 and 1 respectively.

a=[ true -a false is the same but variable a is being set to'[' before execute true -a false.

a shall be unset if not set -a or it's will be '['

  • Related