ARG_MAX
| Shells
| whatshell
| portability
| permissions
| UUOC
| ancient
| -
| ../Various
| HOME
$() vs )
| IFS
| using siginfo
| nanosleep
| line charset
| locale
$( )" command substitution vs. embedded ")" This page doesn't serve any purpose but fun, it's just about a special point concerning the robustness of shell parsers.
2011-03-31 (see recent changes)
In some shells, $( ) collides with other, "unbalanced", yet valid, right parentheses.
And there are some more subtle issues.
The much more famous issue, $( ) vs. `...`,
is mentioned in the additional end notes.
The
SUSv3 rationale
and
SUSv4 rationale
to shell commands, C.2.9, about
"case x in (x)" embedded in "$( )":
$()"
However, there are some cornercases for "$( )"
even in shells which try to implement posix.
The following table lists the results for some testcases.
These tests exploit the case command and here-documents.
They were taken from the above URL or Usenet and the thread
<mailman.20673.1135786095.20277.bug-bash@gnu.org>
in gnu.bash.bug (Dan Jacobson and Eric Blake). Jilles Tjoelker pointed out the problem with '# \'.
$( ) ,
see full testcases
| A.1 | "case x in x)" |
| A.2 | "case x in x)" with a comment |
| A.3 | "case x in (x)" |
| A.4 | "case x in (x)" with a comment |
| A.5 | "case x in (x)" with \n and without ";;" before "esac" |
| B | ) in quotes |
| C | ) after a comment sign |
| D.1 | ) embedded in a here-document |
| D.2 | ) embedded in a here-document, eof and closing ) on same line |
| D.3 | ) embedded in a here-document, with \() inside |
| E | ) as delimiter for an embedded here-document (academic) |
| F | unbalanced quote in an embedded here-document |
| G | \ at end of line |
| H | empty |
| Shell | A.1 | A.2 | A.3 | A.4 | A.5 | B | C | D.1 | D.2 | D.3 | E | F | G | H | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| original ash | + | + | - | - | - | + | + | + | - | + | + | + | + | - | |
| early ash variants | + | + | - | - | - | + | + | + | - | + | + | + | + | + | |
| ash (BSD/OS, NetBSD, FreeBSD, dash, slackware, busybox, Minix) | + | + | + | + | + | + | + | + | - | + | + | + | + | + | |
| bash-1.14.7/2.05/3.0 | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
| bash-3.1.0 | - | - | + | + | + | + | - | - | - | - | - | - | - | + | |
| bash-3.2.0 | - | - | + | + | + | + | + | - | - | - | - | - | - | + | |
| bash-4.0.10 | + | + | + | + | - | + | + | + | - | + | + | + | - | + | |
| bash-4.0.18/-4.0.35 | + | + | + | + | + | + | + | + | - | - | + | + | - | + | |
| bash-4.1.0/-4.1.7 | + | + | + | + | + | + | + | + | +w | + | + | + | - | + | |
| bash-4.2.0 | + | + | + | + | + | + | + | + | +w | + | + | + | + | + | |
| ksh86 | - | - | - | - | - | + | - | - | - | - | - | - | + | + | |
| ksh88-a / e / i | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
| ksh93-d | + | + | + | + | + | + | + | + | - | + | + | + | - | + | |
| ksh93-k / t | + | + | + | + | + | + | + | + | + | + | + | + | + | + | |
| pdksh-5.2.14 | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
| posh-0.5.4/0.6.17 | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
| mksh-R28/R39 | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
| zsh-3.0.0/4.3.9 | - | - | + | + | + | + | - | - | - | - | - | - | + | + | |
case
command yet.
The ash parser doesn't need this workaround. However, this is also an issue of script portability.
$( )" yet and thus had not implemented the opening paren in a case pattern, yet.
$( ) vs. `...`
pro $():
| Without doubt, the "$( )" syntax is the cleaner design because there are no escaping
rules to consider.
And \ is special in `...` so you have to escape it twice.
|
| pro: | Another argument: backquotes are easily confused with apostrophes -- not so
much when actually using them (in terminals with fixed width fonts),
but especially in other sources of documentation using arbitrary fonts. |
| weak: | An often mentioned advantage of the "$( )" syntax:
it allows clean nesting for this reason. However, that's a weak argument:
If you really have to nest command substitution, then you might want to split into separate commands to improve readability and to ease maintencance. |
| contra: | The "$( )" form is not traditionally portable
because traditional Bourne shells only implement the `...` form.
|
| academic contra: | an issue in ksh88, see below |
| academic contra: | parsing problems mentioned on this page... |
In ksh88, at least from release a to i, you have to be aware
of a subtle quoting issue inside $( ).
Single quotes in embedded here-documents are converted to double quotes.
This means that
echo $(cat << EOF
"double quotes"
'single quotes'
EOF
)
results in
"double quotes" "single quotes"This happens for the
$( ) form but not for the `` form.