4 ms·
Small nitpick: for file in .java; do javac $file; done This will break if the filename contains funky characters like newline or whitespaces. You should prefe
by babarock 15y ago
Small nitpick:
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.
- jgw 15y agoAlthough to further nitpick, your proposed substitution doesn't quite do the same thing, since it searches every directory below the pwd, rather than what's in the pwd. 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.
- babarock 15y agoCorrect about the depth issue. Most find versiosn will present an option to do this, although different versions have different syntaxes (-maxdepth 1 for GNU find, -prune for Solaris). 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.
- nescafe 15y agoFind is overkill for this. for file in *.java; do [[ -f $file ]] || continue javac "$file" done
- waitwhat 15y agoyou need to doublequote $file on your second line: [[ -f "$file" ]] || continue
- babarock 15y agoThis would avoid errors on the files with whitespaces, however it will also avoid compiling them. You cannot make the assumption that a file with a whitespace should not be compiled.
- jcromartie 15y agoIt will compile files with whitespaces. That's what [[]] is for.
- babarock 15y agoNo it won't, [[ -f $file ]] will fail and `continue` will be executed, moving on to the next iteration of the loop. Think of the different successive values the $file variable will have. At no point, will it hold the full name of the file at once.
- jcromartie 15y agoI think you're confused. I just tried this in a few shells. It 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".
- nescafe 15y agoIncorrect. Word splitting does not happen in [[ ]] tests. The only reason I had the [[ -f $file ]] || continue is to handle the case where there are no .java files, which will cause the for loop to iterate once with file set to '*.java'. i could have also used nullglob,but chose not to.
- SageRaven 15y agoWhat if "*.java" expands to something too large? Or is that only a relevant concern on the command line itself ("Argument list too long" error) and not within a script?
- pyre 15y agoI realize that this is specifically for bash, but this won't work in zsh: % for blah in *.java; do echo $blah; done zsh: no matches found: *.java
- cmurphycode 15y agoThat's just the zsh regex quirk; try quoting *.java.