ZhengYang Zhao
ZhengYang Zhao

Reputation: 41

Unix & Shell Programming: the "test" built-in and spaces on the command line

this is my first time asking question in stackoverflow. I just started Unix course in this term, and I got pretty confusing about "Space" key in command line. Here are some examples:

% set x1="005"
% test "$x1" = 5
% echo $status
1

The second line I got space key after "$x1" and before 5, and I got result back as 1, which is correct because they are two different string. But if I type my command like this:

% set x1="005"
% test "$x1"=5
% echo $status
0

As you can see, in second line, there are no space after "$x1" and before 5, but the test result back to 0, which is they are same. I have no idea why this happened. Because when I do JAVA or C++, space really doesn't have influence like this. I know this might be dumb, but still hope you guys can help me understand this, thank you very much and have a nice day :)

Upvotes: 1

Views: 72

Answers (2)

Jens
Jens

Reputation: 72707

In the shell, word splitting is performed at spaces. So the first test sees three arguments, 005, =, and 5. If called with these three arguments, test treats the second as an operator, and the first and third as operands.

However, test "$x1"=5 becomes test 005=5 after parameter expansion and quote removal. Since there are no spaces, no further word-splitting is performed (except between test and its single argument).

With just one argument, test checks for an non-empty argument, which in this case is true.

Here's the relevant quote from the POSIX Standard about test:

In the following list, $1, $2, $3, and $4 represent the arguments presented to test:

0 arguments: Exit false (1).

1 argument: Exit true (0) if $1 is not null; otherwise, exit false.

2 arguments:

If $1 is '!', exit true if $2 is null, false if $2 is not null.

If $1 is a unary primary, exit true if the unary test is true, false if the unary test is false.

Otherwise, produce unspecified results.

3 arguments:

If $2 is a binary primary, perform the binary test of $1 and $3.

If $1 is '!', negate the two-argument test of $2 and $3.

[OB XSI] [Option Start] If $1 is '(' and $3 is ')', perform the unary test of $2. [Option End] On systems that do not support the XSI option, the results are unspecified if $1 is '(' and $3 is ')'.

Otherwise, produce unspecified results.

4 arguments:

If $1 is '!', negate the three-argument test of $2, $3, and $4.

[OB XSI] [Option Start] If $1 is '(' and $4 is ')', perform the two-argument test of $2 and $3. [Option End] On systems that do not support the XSI option, the results are unspecified if $1 is '(' and $4 is ')'.

Otherwise, the results are unspecified.

>4 arguments: The results are unspecified.

Upvotes: 2

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799150

The first passes the arguments "005", "=", and "5" to test. This tests if the strings are equal, which they are not. The second passes the single argument "005=5" to test. The behavior of test when passed a single argument is to treat it as a string and to test that it is non-empty. And yes, that is a non-empty string.

Upvotes: 1

Related Questions