|
|
Subscribe / Log in / New account

dash/ash

dash/ash

Posted Oct 1, 2014 22:36 UTC (Wed) by Jandar (subscriber, #85683)
In reply to: dash/ash by wahern
Parent article: Bash gets shellshocked

> One lesser-known way is by using the "set -- [...]" construct, which resets your local argument vector.

One global array is hardly a replacement for the bash arrays. Btw the set builtin is well-known.

> A more common method is using read(1).

Do you mean managing arrays in multiple tempfiles and reading (+ writing with ugly escapes) on any usage? Appalling.

The omission of arrays in posix-shell is the major reason for me to ignore it and use bash.


to post comments

dash/ash

Posted Oct 2, 2014 14:23 UTC (Thu) by nix (subscriber, #2304) [Link] (3 responses)

There are things you can do with arrays stored as files that you can't do in any other way -- e.g. high-speed filtration and set-membership queries with comm(1) and grep. Since the primary priority when making a shell script fast enough to be useful is converting all loops into pipelines, and comm(1) is invaluable in that, I'm not sure why you'd ever want to use arrays in any other form, really.

dash/ash

Posted Oct 3, 2014 9:48 UTC (Fri) by Jandar (subscriber, #85683) [Link] (2 responses)

With arrays the construction of an argument-vector is easy.

typeset -a Options Files
Options+=("$option1")
Files+=("$file1")
$UseVerbose && Options+=("-v")
$UseSecondFile && Files+=("$file2")
command "${Options[@]}" -- "${Files[@]}"

How do you prepare (with correct quoting) a dynamic argument-vector without arrays? All other methods are ugly and error-prone beyond any acceptable limit.

dash/ash

Posted Oct 17, 2014 11:12 UTC (Fri) by mgedmin (subscriber, #34497) [Link] (1 responses)

Thank you. I've been reading bash(1) and tearing my hair out, and the only syntax I discovered for appending an item to an array was

paths[${#paths[*]}]="$1"

Rewriting this to use +=() will make my scripts a bit saner.

dash/ash

Posted Oct 17, 2014 12:02 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

Any reason path=( "$path[@]" "$1" ) wouldn't have worked?

dash/ash

Posted Oct 3, 2014 19:30 UTC (Fri) by wahern (subscriber, #37304) [Link]

Positional parameters are scoped to the function. So the set -- construct only changes the function-local argument vector. In the following example, note that invocation of foo doesn't reset the positional parameters of 1 2 3 4 in the outer scope.

foo() {
set -- A B C

printf "$# -> $*\n"
}

printf "$# -> $*\n"
set -- 1 2 3 4
foo
printf "$# -> $*\n"

Also, per POSIX: "Positional parameters are initially assigned when the shell is invoked (see sh), temporarily replaced when a shell function is invoked (see Function Definition Command), and can be reassigned with the set special built-in command."

Obviously this isn't a complete substitute for arrays, neither alone nor in tandem with other alternatives.

But my point is that people use Bash features without understanding the alternatives, and without appreciating the cost of Bash. Bash is a great interactive shell. But if you're serious about shell programming, one should learn POSIX syntax, as well as sed(1), awk(1), and the nuances of other utilities. This isn't hard because the POSIX documentation is infinitely more clear and concise than implementation documentation. A good way to practice is with Solaris, because Solaris' utilities are often annoyingly anachronistic (e.g. grep doesn't even have a recursive mode), but dash isn't a bad place to start, either. And when you do choose to use extended functionality, do so knowingly, having assessed the costs and benefits.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds