LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   why it becomes if [ "" = "1" ]; then when the problem is fixed ? (https://www.linuxquestions.org/questions/programming-9/why-it-becomes-if-%5B-%3D-1-%5D%3B-then-when-the-problem-is-fixed-4175728841/)

tangara 09-11-2023 12:48 AM

why it becomes if [ "" = "1" ]; then when the problem is fixed ?
 
i refer to the tutorial on staying out of trouble

http://linuxcommand.org/lc3_wss0090.php

i do not understand why when you fix the problem on line 5, then

Now when the shell performs the expansion it will see:

if [ "" = "1" ]; then

I can't wrap around my head why when the line is changed to if [ "$number" = "1" ]; then the shell will see it to be [ "" = "1" ];

Furthermore, when it is else, shouldn't it be using "" = "1" or the number != "1" so why it is still ["$number" = "1"] which is same as the condition on line 3 ?

astrogeek 09-11-2023 01:04 AM

Welcome to LQ!

What that is telling you is that if the variable $number is empty, and the test is [ $number = 1 ], then when the shell expands it, the test will be...

Code:

[ = 1 ]
... so there is nothing at all to compare to the number 1, which is an error!

When you surround the variable in quotes like this...

Code:

[ "$number" = 1 ]
... and the variable $number is empty, then the shell still sees the empty quotes...

Code:

[ "" = 1 ]
... and the empty quoted string is not nothing, and it can be compared to 1, so the test is valid.

Hope that helps!

MadeInGermany 09-11-2023 06:08 AM

The " " enforce one string, and $ expressions are evaluated+substituted before the string is handed to the [ ]
Compare with ' ' that enforce one string without substitution.

An empty variable without quotes is nothing, not even an empty string.

Redo the exercise with
number="1 3"
Missing quotes will split it to two strings, "too many arguments" error for the [ ]

And compare it with
[[ $number == 1 ]]
where an unquoted $number is always seen as one string, i.e. $number is like "$number".

chrism01 09-11-2023 11:27 PM

As per post 3, prefer [[ ]] to [ ] : https://tldp.org/LDP/abs/html/testco...ml#DBLBRACKETS.

As an aside, '==' is string comparison, ' -eq ' is numeric comparison; easy to get wrong, esp when comparing '0' (zero).


See also
https://tldp.org/LDP/abs/html/compar...l#ICOMPARISON1

pan64 09-12-2023 02:20 AM

" is not part of the variable, $number does not contain it. "$number" means whatever is in the variable number should be kept in one. Otherwise " is "only" used to visualize the expression
Code:

[ "" = 1 ]
means you compare the empty string to 1
Code:

[ = 1 ]
means there is nothing on the left side, you compare nothing to 1, which is just syntactically incorrect.
This is all called quotation, and you can find a lot about it here: https://www.gnu.org/software/bash/ma...e/Quoting.html

tangara 09-13-2023 08:46 AM

Quote:

Originally Posted by MadeInGermany (Post 6452965)
The " " enforce one string, and $ expressions are evaluated+substituted before the string is handed to the [ ]
Compare with ' ' that enforce one string without substitution.

An empty variable without quotes is nothing, not even an empty string.

Redo the exercise with
number="1 3"
Missing quotes will split it to two strings, "too many arguments" error for the [ ]

And compare it with
[[ $number == 1 ]]
where an unquoted $number is always seen as one string, i.e. $number is like "$number".

I just want to confirm my understanding.

I tried out the following :

Code:

tangara@DESKTOP-SB41UI7:~$ #!/bin/bash
tangara@DESKTOP-SB41UI7:~$
tangara@DESKTOP-SB41UI7:~$ number=
tangara@DESKTOP-SB41UI7:~$
tangara@DESKTOP-SB41UI7:~$ if [ $number = "1" ]; then
>    echo "Number equals 1"
> else
>    echo "Number does not equal 1"
> fi
-bash: [: =: unary operator expected
Number does not equal 1
tangara@DESKTOP-SB41UI7:~$

is this test trying to tell us not to use "" since "" is for String, thus it is giving Number does not equal 1 ?

pan64 09-13-2023 08:54 AM

no
#!/bin/bash
should only be used at the beginning of scripts, otherwise it is a comment line, does nothing

number=
will declare a variable named number and will assign the empty string to it

[ $number = "1" ]
here $number will be replaced with the value stored in that variable, the result will be:

[ = 1 ]
which is just syntactically incorrect, = is not an unary operator, cannot be used directly after [

[ "$number" = "1" ]
will be translated to:

[ "" = "1" ]
so the shell will compare the empty string to 1 (as string, not number)

teckk 09-13-2023 08:54 AM

Quote:

-bash: [: =: unary operator expected
number is false
Code:

n=
if [ "$n" = "1" ]; then
    echo "Number equals 1"
else
    echo "Number does not equal 1"
fi


sundialsvcs 09-13-2023 08:58 AM

Remember that a lot of what "the shell" does is text substitution. It is presented with a text string – having utterly no idea "what it is" – and mechanically performs its substitutions. This is not what "a programming language compiler or interpreter" would do. (The only shell which actually has "a built-in true language interpreter" is Dr. Korn's ksh, which unfortunately is rarely used.)

MadeInGermany 09-13-2023 05:45 PM

In the early minimalistic Bourne shell there were external commands /usr/bin/test and /usr/bin/[
/usr/bin was in the PATH, and
test 1 = 2
and
[ 1 = 2 ]
was like
/usr/bin/test 1 = 2
and
/usr/bin/[ 1 = 2 ]

Later they were replaced by internal (builtin) commands, for better performance.
Still the shell, after doing the usual expansions, invokes the command without knowing what it will do.

The error
-bash: [: =: unary operator expected

is from the bash-internal [ command.

Most Unix and Linux distros still have the external commands for compatibility.
Try the explicit external commands with your border cases! The message text might be different - it's a different implementation.

Later the [[ ]] was introduced; this is directly handled by the bash syntax/parser. It is implemented in a way that it is mostly compatible with a [ ]
But it does less expansions and behaves more like other languages.
And it can do some additional things, that a command cannot do.

sundialsvcs 09-15-2023 10:31 AM

It’s also very worth mentioning the #! shebang” feature. If the first line of a “shell script” begins with a line such as #!/usr/bin/perl, the shell will silently transfer control to that script interpreter. (The env command is provided to generalize this.) Therefore, you are not limited to bash’s very limited built-in scripting capabilities. If you look at the source code of most of the “distro-provided shell commands that you use every day,” you will see that nearly all of them use this.

MadeInGermany 09-15-2023 12:52 PM

The kernel (not the shell) will run the #! script interpreter!
The shell is one of the possible interpreters.
If you want to read more:
https://stackoverflow.com/questions/...e-shebang-work

astrogeek 09-15-2023 01:38 PM

OT Trivia: Shebang!

A friend who was part of the original Santa Cruz Operation and transitioned into the early days of the SCO we are familiar with once passed a small collection of SCO documents to me, including some training materials (which were actually quite good overall).

Among those the #! is consistently referred to as the "hash-pling" - a singularly unmemorable term. I had seen hash-bang, but that was the first and only time I encountered the -pling variant, although wikipedia makes mention of it as an alternate.

Doesn't quite roll off the subvocalized tongue as easily as shebang!

GazL 09-15-2023 06:34 PM

I've never liked the "shebang" term myself: it just seems wrong. I'm ok with the other two, though "hash-bang" sounds more American and "hash-pling" feels more natural to my British ears.

Maybe there's a cultural or age element to whether one considers a '!' as a "pling" or a "bang".


All times are GMT -5. The time now is 11:51 PM.