Hacker News new | ask | show | jobs
by intrepidhero 1220 days ago
The number one use case of `for` in shell scripting is over the output of `$(ls .)` And I immediately run into a problem with filenames that have spaces and then I discover that a stringly typed language has lots of sharp edges.

I fall back on `for filename in os.listdir():`

2 comments

If I may humbly offer a suggestion, looping over filenames should [edit: almost] never be done with ls. find can be used with much better fidelity:

https://www.shellcheck.net/wiki/SC2012

"ls is only intended for human consumption: it has a loose, non-standard format and may "clean up" filenames to make output easier to read."

Shells usually do not re-split on whitespace after filename generation. So, you could also just use an asterisk for your number one use case:

    dash$ touch "hi ho"
    dash$ touch "there, buddy"
    dash$ for f in *; do echo $f; done
    hi ho
    there, buddy
(EDIT: That was in a scratch directory.) But as @npongratz alludes to in sibling https://news.ycombinator.com/item?id=34727735

    find . [predicates] -print0 | xargs -0
is bulletproof and directory scanning, output, and input loops all run at full C speed. (One predicate is `-maxdepth 1` to not recurse.)
Try this:

   touch -- -n
I'm sure the full list of shell check rules is in the many dozens.. I was just trying to address one apparent misperception. And here I thought someone would complain about not putting $f in double quotes not * instead of ./* ;-)

Anyway, I did mention find-xargs, but it's also true your leading dash filenames mistaken for options point can cause trouble in naive invocations if find roots begin with dashes. Doubtless, a lotta gotchas..