Skip to main content
added 25 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine (when quoted, of course):

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

See the answer by Stéphane Chazelas on the duplicate question for more background and corner cases.

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

See the answer by Stéphane Chazelas on the duplicate question for more background and corner cases.

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine (when quoted, of course):

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

See the answer by Stéphane Chazelas on the duplicate question for more background and corner cases.

added 153 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

See the answer by Stéphane Chazelas on the duplicate question for more background and corner cases.

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

See the answer by Stéphane Chazelas on the duplicate question for more background and corner cases.

edited body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ "x"'x' = x -a 1 = 1 ] && echo yes
yes
$ [ "'!"' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ "x" = x -a 1 = 1 ] && echo yes
yes
$ [ "!" = x -a 1 = 1 ] && echo yes
bash: [: too many arguments

Even if empty vars and quotes work, some pre-POSIX implementations of test/[ have issues with values that look like operators, like !.

E.g. with heirloom-sh:

Empty vars are fine:

$ var=
$ [ "$var" = "" ] && echo yes
yes

But a ! breaks it:

$ var="!"
$ [ "$var" = "foo" ] && echo yes
test: argument expected

Adding the x to the front prevents that:

$ var="!"
$ [ "x$var" = "xfoo" ] && echo yes || echo no
no

The POSIX specification says that the implementation must check the number of arguments (apart from the final ]), and use that to determine which arguments can be operators and which ones are values. With three arguments, they must always be value-operator-value, so a ! would not be special in the first or last position. (In the middle it would be an invalid binary operator.)

You can still get a similar issue with longer expressions involving -a or -o (which is pretty much why they shouldn't be used). E.g. with Bash 5.2:

$ [ 'x' = x -a 1 = 1 ] && echo yes
yes
$ [ '!' = x -a 1 = 1 ] && echo yes
bash: [: too many arguments
added 531 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441
Loading
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441
Loading