Bash Shell Scripting in 10 seconds
aboutlinux.info
aboutlinux.info
Specifically:
* test and [ ] are fraught with parameter expansion peril. Use [[ ]] instead.
* The author uses single quotes around strings that are demonstrating parameter expansion. Single quotes inhibit parameter expansion, so every one of those examples is wrong.
* select is a better tool than read; case for most of his case-relasted demos.
* Backticks ( ` ` ) are the devil.
At least he points people greg's wiki at the end.
# d=abc
# [ $d -eq 25 ]
-bash: [: abc: integer expression expected
It also looks to me that aboutlinux.info is in fact just a for-SEO-purposes generated site. Anybody knows more?"The KornShell-derived conditional command (double bracket [[]]) was removed from the shell command language description in an early proposal. Objections were raised that the real problem is misuse of the test command ( [), and putting it into the shell is the wrong way to fix the problem. Instead, proper documentation and a new shell reserved word ( !) are sufficient."
The entire section on test is full of advice on the proper use of test(1).
[1] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/te...
Where they are really the evilest evil is in PHP. Such a dangerous things, nearly invisible!
Unless your shell and editor are displaying in courier, or you use extremely small glyphs (I've seen folks doing terrible things to their font scaling on 100dpi mac screens trying to get more lines on the screen) that should not be a problem. Certainly the Vera Mono font family gets this right; a backtick is quite distinct.
for file in .java; do javac $file; done
This will break if the filename contains funky characters like newline or whitespaces. You should prefer using find instead:
find . -name '.java' -exec javac {} \+
Also, I would suggest adding a pragaraph about proper quoting, I usually find it to be an issue beginners struggle with the most.
Agreed on quoting.
for file in *.java; do javac "$file"; done
I'd also like to see something on substitutions which I find useful, like: for file in quad_{upper,middle,lower}_{left,centre,right}.dat; do echo "$file"; done
I'd throw in a line or two about the difference between sourcing and executing a shell script, too. Not that this is sh-specific, but I often encounter folks who don't know how they're different, or why, and are perplexed by the behaviour.Agreed on the difference between sourcing and executing. I would say in general it would be beneficial to include a paragraph on which code is executed in the current process and which will fork a new one.
for file in *.java; do
[[ -f $file ]] || continue
javac "$file"
doneIt works in Bash on Cygwin and OS X.
touch "file with spaces"
for f in *; do if [[ -f $f ]]; then echo file: $f; fi; done;
This echoes one line for "file with spaces". % for blah in *.java; do echo $blah; done
zsh: no matches found: *.java [[ -f "$file" ]] || continueDumb, I know, but sometimes the obvious beginner stuff is easy to overlook.
echo $IFS | od -bc
only makes sense as echo "$IFS" | od -bc42 days is I guess a reasonable estimate for learning Bash if you're really new and coming from Windows -- but perhaps it's a little too much; you could probably get fluent in two weeks if you really focused and already knew the basics of programming.
So the Bash Gods should clearly revise the number down to three seconds.