I'm writing Bash wrapper functions that validate inputs, check whether a command is available, and then run programs such as pg_restore. To avoid a long list of parameters, I was considering passing an associative array of option names and values, then constructing arguments like --dbname=test_db and --jobs=8. However, associative arrays do not preserve insertion order. Could that cause problems? Are options generally order-independent, or does each command decide how option and positional-argument ordering works? Also, is passing the constructed command as an array the right approach?
4 Answers
For this kind of wrapper, an indexed array is usually the better fit. For example: `local -a opts=(--dbname=test_db --host=localhost --jobs=8 --port=5432 --username=test_user)`, followed by `pg_restore "${opts[@]}"`. Most option parsers accept the options in any order, and `pg_restore` generally does not require these particular switches to appear in a specific sequence. Still, positional arguments and commands such as `find`, `dd`, or tools with subcommands may have special syntax, so there is no universal rule.
Checking whether a command can be found can be done with Bash’s `type`, such as `type -t pg_restore >/dev/null 2>&1`, but that only checks command lookup. It does not prove that the program is usable or that its arguments are valid. The dependable way to validate options is to let the program parse them and inspect its documented exit status. Also, avoid naming a function `test`, because that shadows Bash’s `test` builtin and can create confusing behavior.
Bash itself does not decide how most command-line options are interpreted. External programs receive an argument vector and implement their own parsing rules. Many programs accept options in almost any order, but some distinguish between global options, subcommands, positional arguments, or later options that modify earlier behavior. You have to check the documentation for each command. Associative arrays are therefore not a reliable representation when ordering matters. Use an indexed array when you need a predictable order, and pass it with array expansion: `command "${args[@]}"`. Do not use `"${args[*]}"`, since that joins everything into one argument.
The usual option convention is that options come before positional operands, and many Unix utilities follow POSIX or GNU parsing conventions. That is only a convention, though—not a guarantee for every program. If a wrapper needs a fixed sequence such as global options, a subcommand, and then subcommand-specific options, store those sections explicitly in indexed arrays instead of trying to recover an order from associative-array keys.

An associative array is still useful for named configuration and validation, but it should be converted into a deliberately ordered argument array before invoking the command. That keeps the lookup convenience separate from the command’s actual syntax.