简体   繁体   中英

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

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?

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 .

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 '['

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM