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 ? |
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 ] When you surround the variable in quotes like this... Code:
[ "$number" = 1 ] Code:
[ "" = 1 ] Hope that helps! |
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". |
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 |
" 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 ] Code:
[ = 1 ] This is all called quotation, and you can find a lot about it here: https://www.gnu.org/software/bash/ma...e/Quoting.html |
Quote:
I tried out the following : Code:
tangara@DESKTOP-SB41UI7:~$ #!/bin/bash |
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) |
Quote:
Code:
n= |
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.)
|
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. |
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.
|
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 |
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! |
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. |