4

I am frequently using a command line program that I provide with arguments that contain parentheses. For simplicity, let's say I'm writing

echo 'bar(1,3)'

I would like to omit the quotes. However, if I do that I get syntax errror near unexpected token '('. I guess this is related to subshells. I am willing to disable those, if that's the only way. (though a subshell cannot be started if it is not at the beginning of the command anyway, so they are no reason to forbid parentheses in the arguments, as far as I can tell)

4
  • 3
    Try echo bar\(1,3\)
    – Siva
    Aug 24, 2018 at 12:10
  • 4
    Why do you want to omit the quotes?
    – Flimm
    Aug 24, 2018 at 12:16
  • 1
    You can not "disable subshells".
    – Kusalananda
    Aug 24, 2018 at 12:26
  • @Flimm I want to omit the quotes out of laziness and because I often forget them and then have to to even more typing
    – Bananach
    Aug 24, 2018 at 12:50

2 Answers 2

6

( and ) are special token characters in the syntax of bash that are used in a number of operators including:

  • (...) subshell construct
  • func() compound-command function definitions
  • $(...) command substitution
  • <(...), >(...) process substitution
  • ((...)) arithmetic evaluation construct
  • $((...)) arithmetic expansion
  • a=(...), a+=(...) array assignment operators
  • @(...), +(...), *(...), ?(...) glob operators (with extglob)
  • [[ (a && b) || (c && d) ]] grouping conditional expression operators
  • [[ ... =~ ...(...)... ]] regexp operator.

echo a=(b) is a syntax error, but not export a=(b).

echo a) is a syntax error, unless there was an opening ( in the previous lines part of one of the constructs above.

While it may be possible to write a readline hook that adds quotes where needed around (, ) to avoid a syntax error, it would be considerable effort as it would mean doing a full parsing of the shell syntax.

A better approach may be to use a shortcut that quotes the current word when you realise too late that it contains characters special to the shell.

With zsh (assuming emacs mode):

bindkey -s '\e#' '\C@\eb\Cx\Cx\e"'

To have Alt+# quote the current word.

Or an approximation with bash (also assuming emacs mode):

bind "\"\e#\": \"'\e \eb'\C-X\C-X\""
2
  • 2
    I agree with your better approach. Thanks for the bash update. If anyone else needs this but has vi-mode enabled as I do, I modified this to bind "\"\e#\": \"'\eF a'". This puts quotes around the current argument as defined by the cursor until the closest space character before it.
    – Bananach
    Aug 24, 2018 at 15:03
  • To the maintainers of this site, I suggest that you have a repository of such answers, so that they can be straightway accessed later on. Aug 25, 2018 at 17:25
0

This might be a bad idea (see the comments), but I had the same problem and I solved it by making a function that changes [ into ( and ] into ) before using it:

echo2() {
    expression=$(echo $@ | tr '[]' '()')
    echo "$expression"
}

input:

echo2 bar[1,3]

result:

bar(1,3)

I don't know if the [ and ] are treated specially by the shell. But if you're ok with using them in place of ( and ) for your function maybe this a solution for you.

4
  • I think when the OP writes "I am frequently using a command line program [...]. For simplicity, let's say I'm writing echo 'bar(1,3)'", it really means the program is not (or at least not necessarily) echo. Mar 30, 2022 at 13:10
  • [ is treated specially since it introduces a globbing pattern. Your string bar[1,3] is a globbing pattern that matches the three filenames bar1, bar,, and bar3. The pattern would be replaced by these names if the existed in the current directory, or the pattern may be removed completely if the nullglob shell option is set, or it may generate a fatal error if the failglob shell option is set.
    – Kusalananda
    Mar 30, 2022 at 14:20
  • Also note that swapping () with [] is more efficiently done with tr '()' '[]', and that echo $@ will have issues if any argument is a pattern or contains whitespace, or starts with a string that is an option to echo, or contains backslashes in certain constellations (e.g. \n).
    – Kusalananda
    Mar 30, 2022 at 14:22
  • @they Thanks for these comments - I didn't know that the square brackets could be used in this way. I guess it's a bad idea to do this...
    – mattb
    Mar 31, 2022 at 0:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .