The [[…]] built-in test version was introduced in Peter Korn's korn shell, ksh88 IIRC. As where various other modernized notations like array variables, process substitution or
$(command)
as a much more readable version of the backquotes version.
Here is the part of the test.c source from V7 Unix:
main(argc, argv)
char *argv[];
{
ac = argc; av = argv; ap = 1;
if(EQ(argv[0],"[")) {
if(!EQ(argv[--ac],"]"))
synbad("] missing","");
}
argv[ac] = 0;
if (ac<=1) exit(1);
exit(exp()?0:1);
}
So, if the professor was missing the "[" command, they were missing a link. More likely, they had a weird orthodoxy about using "test" instead of "[" because reasons. One good reason to use "test" instead of "[" in a Bourne shell control statement is if you are running a list of commands between "if" and "then", and the test is the last part of the list.
Another good place to use "test" is if you are not in a control statement and you are just setting $?.
Edit: EQ() is defined as:
#define EQ(a,b) ((tmp=a)==0?0:(strcmp(tmp,b)==0))
char *tmp;
Reminds me of my rather memorable introduction to special characters invoking functions, seeing this dastardly little quip in the email signature of someone in a mailing list (circa '95 or so).
:(){:|:&};:
My curiosity piqued, I pasted it into the shell on my terminal in a pure example of FAFO. The poor little Sparc 5 I was using ground to a halt over the course of about ten seconds. The reboot was as hard as the lesson. xD
A hard reboot is where the power goes all the way off, a soft reboot is where it doesn't. A fork bomb makes it very hard / impossible to trigger a soft reboot, forcing you to do a hard reboot.
As an extra sting, a hard reboot can be damaging if the software and hardware is not correctly handling power interruption, which was much more likely in the 90's.
In college I took a database class, it was pretty basic overall as I had been playing with MySQL for a few years at that point. On the final exam I got a 90/100. The test was 10 questions that just had you write SQL to answer the question. I got all the queries 100% correct... except... I didn't put a ";" after each query. On a written test. I'm still a little bitter about that.
The ultimately sad part was the professor in a Sun OS machine.
In a corner with no where to go, giving demerits because his bash was older than he realized.
Reminds me of my college professor that claimed you don’t have to close HTML tags (some you absolutely do) and I proved that you do. Not all of them, but most of them. (Netscape Navigator Days)
Why do you think the prof even used bash? I highly doubt his ancient SunOS machine had a GNU toolchain. `test` and `[` are both POSIX, but if there was no `/bin/[` I doubt the shell in question (original Bourne? Some proprietary Sun shell? Who knows) had it built in either.
> When I was a young, green, university student, I was forced to use test(1) as the only true way to do testing in shell scripting. […] Yeah, I was also forced to not use semicolons as they were evil (according to my professor, any comment unneeded!).
The author’s professor clearly went overboard, but doesn’t this entire anecdote demonstrate the value of teaching it this way? Having green students call the `test` binary provides more insight into how UNIX operates, and gets them using a UNIX mindset. They can discover the syntactic shortcuts later.
If shipping something that must run on sh, check your life choices and use [ - otherwise [[ is better.
Honestly though I’ve been much happier since I stopped writing anything complex enough to have conditionals in Shell. Using a real scripting language like Ruby, Python, even PHP or Perl if you know them, is better.
In the Ruby case I just use `%x( … )` when I need to run shell commands (there are some things shell does great like passing pipelines of text through 5 programs) and let the logic part be in Ruby.
I personally use ((...)) for arithmetic tests and [[...]] for all other tests as I just target new versions of BASH and don't care much about POSIX compatibility.
[[ ... ]] supports regex comparisons and lets you combine multiple conditions in a single bracket group using && and || instead of remembering to use -a / -o.
I usually default to [ ... ] unless I need features that double brackets provide.
Yeah, if you set the shebang `#!/bin/sh` (which is portable), shellcheck will complain about double brackets. It also helps you do quoting correctly when using single brackets.
A builtin part of the shell, just like `if` and `then` and `fi`. Not all shells have `[[`, the one that doesn't which people unknowingly run into most is probably `dash` as used by Alpine Linux. POSIX doesn't require `[[` in a shell, BASH & Zsh support it but others often don't.
Use ((...)) for arithmetic tests and [[...]] for other tests. [...] is for POSIX compatibility and not as useful as [[...]] though I don't remember the specifics.
https://docs.oracle.com/cd/E36784_01/html/E36870/ksh88-1.htm...
While learning the Bourne shell as acstudent, I was rapidly lured by csh and then tcsh, but Tom Christiansen's pamphlet https://everything2.com/title/csh+programming+considered+har...
and (or?) the appearance of Paul Falstad's Z-Shell saved me ;-0
Another good place to use "test" is if you are not in a control statement and you are just setting $?.
Edit: EQ() is defined as: #define EQ(a,b) ((tmp=a)==0?0:(strcmp(tmp,b)==0)) char *tmp;
I'm confused. What happened on reboot?
As an extra sting, a hard reboot can be damaging if the software and hardware is not correctly handling power interruption, which was much more likely in the 90's.
/bin/[ as a binary looking for it's own "]" closing bracket!
What a nasty syntax hack!
I wonder what the motivation was for doing this rather than just implementing test expression support directly in the shell?
In a corner with no where to go, giving demerits because his bash was older than he realized.
Reminds me of my college professor that claimed you don’t have to close HTML tags (some you absolutely do) and I proved that you do. Not all of them, but most of them. (Netscape Navigator Days)
Precisely because those older systems didn’t link to it!
So my comment still stands.
The author’s professor clearly went overboard, but doesn’t this entire anecdote demonstrate the value of teaching it this way? Having green students call the `test` binary provides more insight into how UNIX operates, and gets them using a UNIX mindset. They can discover the syntactic shortcuts later.
I do think it makes sense to have beginners use `sh` instead of `bash`.
I'm still not sure when to use one or the other. I use double brackets by default until something doesn't work.
Honestly though I’ve been much happier since I stopped writing anything complex enough to have conditionals in Shell. Using a real scripting language like Ruby, Python, even PHP or Perl if you know them, is better.
In the Ruby case I just use `%x( … )` when I need to run shell commands (there are some things shell does great like passing pipelines of text through 5 programs) and let the logic part be in Ruby.
I personally use ((...)) for arithmetic tests and [[...]] for all other tests as I just target new versions of BASH and don't care much about POSIX compatibility.
I usually default to [ ... ] unless I need features that double brackets provide.
When unsure, use shellcheck.
https://mywiki.wooledge.org/BashFAQ/031