Hello, On Thu, 27 May 2010, David C. Rankin wrote:
On 05/27/2010 04:47 AM, Jon Clausen wrote:
Indeed... however:
Now I *have* tested, and somewhat surprisingly (to me at least) filenames with whitespace are not a problem: [..] Old dog, new trick! That's pretty cool:
09:55 alchemy:~/tmp> ( myarray=(*); for ((i=0;i<${#myarray[@]};i++)); do printf "myarray[%2d]: %s\n" ${i} "${myarray[${i}]}"; done ) myarray[ 0]: 2010 Narrative Update.txt [..] What I am uncomfortable with is the spaces issue, despite having proven it to myself, but as long as globbing holds, then there should be no reason this wouldn't be as safe as 'for i in *; do ...xyz...; done. In fact, it is probably preferred over my usual: SARRAY=( $(ls $SEARCHDIR) ), ^^^^^^^^^^^ *SLAP* Just for the unquoted "$SEARCHDIR"!.
though I can't lay my hand on a rule telling me which is preferred.
The former is a 'no-brainer' to be preferred. Using 'ls' in such context is just plain stupid (or evil). Equivalent to (being forced to be) playing russian roulette with statistically about 5.952 bullets (in 6 chambers) or something. Oh, and BTW: bash-internal globbing as above or with 'for x in GLOB; do' will never result in a "too long" command line error. You might run out of memory putting the result into the array-variable, though.
With my usual method, setting IFS to newline is definitely required. What i like about (*) is that globbing handles all the spaces for you when loading the array. However, you would still need IFS set to newline (or religious quoting) for any subsequent processing of names with spaces later on in the script.
ALWAYS QUOTE VARIABLES! is also a no-brainer! I can't stress that enough. With proper quoting, even newlines and what-not are a non-problem! $ ls -b a a\ "b"\ c"\ d a\ '"b'\ c"\ d\ and\ e a\ b a\ b\nc d $ A=(*) $ echo "${#A[@]}" 6 $ for f in "${A[@]}"; do echo "-A»$f«"; done-b -A»a«-b -A»a "b" c" d«-b -A»a '"b' c" d and e«-b -A»a b«-b -A»a b-b c-A«-b -A»d«-b Note the embedded newline and quotes in the output. Can't get much worse than that (filenames containing '*' or '!' or stuff like that are no problem either). It really _IS_ very simple: _ _ __ _____ _____ ___ _ _ ___ _____ ___ _/\_/_\ | |\ \ / /_\ \ / / __|/\_ / _ \| | | |/ _ \_ _| __|
< _ \| |_\ \/\/ / _ \ V /\__ > < | (_) | |_| | (_) || | | _| \/_/ \_\____\_/\_/_/ \_\_| |___/\/ \__\_\\___/ \___/ |_| |___|
__ _____ _ _ ___ __ ___ ___ ___ _ ___ _ ___ ___ _ \ \ / / _ \| | | | _ \ \ \ / /_\ | _ \_ _| /_\ | _ ) | | __/ __| | \ V / (_) | |_| | / \ V / _ \| /| | / _ \| _ \ |__| _|\__ \_| |_| \___/ \___/|_|_\ \_/_/ \_\_|_\___/_/ \_\___/____|___|___(_) ___ ___ ___ ___ ___ ___ _ | _ \ __| _ \_ _/ _ \| \| | | _/ _|| /| | (_) | |) |_| |_| |___|_|_\___\___/|___/(_) That's not "religious", that's a no-brainer standard behaviour[1]. That's "defensive" scripting. ;) Set IFS only if you want to deliberately split at non-standard-IFS places. Or if reading non-standard-IFS seperated stuff with 'read' or when using the 'set' builtin. That's basically it, IIRC. Oh, and BTW, using "${VAR}" instead of just "$VAR" is also very much encouraged, even if more often superfluous (than using quotes). Can't hurt though, so use "${var}" instead of "$var" routinely. Happy Slapsgiving ;) HTH, -dnh [1] yes, there are cases where you can't quote, but those are catering for not being able to use arrays, i.e. writing for 'sh' compatibility. -- Get your acts together, guys. Stop blathering and frothing at the mouth. -- Linus Torvalds -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org