diff --git a/libdash/printer.py b/libdash/printer.py index 6c84f2a..d0e26ac 100644 --- a/libdash/printer.py +++ b/libdash/printer.py @@ -393,7 +393,14 @@ def string_of_arg_char (c, quote_mode=UNQUOTED): elif (type == "Q"): return "\"" + string_of_arg (param, quote_mode=QUOTED) + "\""; elif (type == "B"): - return "$(" + to_string (param) + ")"; + body = to_string (param) + # to handle $( () ) + try: + if body[0] == "(" and body[-1] == ")": + body = f" {body} " + except IndexError: + pass + return "$(" + body + ")" else: abort (); diff --git a/ocaml/ast.ml b/ocaml/ast.ml index 80a77d4..3abdfb2 100644 --- a/ocaml/ast.ml +++ b/ocaml/ast.ml @@ -462,8 +462,12 @@ and string_of_arg_char ?quote_mode:(quote_mode=QUnquoted) = function | V (vt,nul,name,a) -> "${" ^ name ^ (if nul then ":" else "") ^ string_of_var_type vt ^ string_of_arg ~quote_mode a ^ "}" | Q a -> "\"" ^ string_of_arg ~quote_mode:QQuoted a ^ "\"" - | B t -> "$(" ^ to_string t ^ ")" - + | B t -> + let s = to_string t in + if String.length s >= 2 && s.[0] = '(' && s.[String.length s - 1] = ')' then + "$( " ^ s ^ " )" + else + "$(" ^ s ^ ")" and string_of_arg ?quote_mode:(quote_mode=QUnquoted) = function | [] -> "" | c :: a -> diff --git a/test/tests/nested_shell_in_subshell.sh b/test/tests/nested_shell_in_subshell.sh new file mode 100644 index 0000000..8bfb75b --- /dev/null +++ b/test/tests/nested_shell_in_subshell.sh @@ -0,0 +1,4 @@ +( (echo abc) ) +echo $( (echo abc) ) +echo `(echo abc)` +echo $()