Why are bash brace expansions not working for commands?
Your brace expansion is not valid. A brace expansion must be one word in the shell.
A word is a string delimited by unquoted spaces (or tabs or newlines, by default), and the string {chown httpd,chmod 700}
consists of the three separate words {chmod
, http,chmod
and 700}
and would not be recognised as a brace expansion.
Instead, the shell would interpret the line as a {chown
command, executed with the arguments http,chmod
, 700}
and /dir/test1
.
The simplest way to test this is with echo
:
$ echo {chown httpd,chmod 700} /dir/test1
{chown httpd,chmod 700} /dir/test1
$ echo {"chown httpd","chmod 700"} /dir/test1
chown httpd chmod 700 /dir/test1
Note that even if your brace expansion had worked, the command would have been nonsensical.
Just write two commands,
chown http /dir/test1
chmod 700 /dir/test1
because, as mentioned in the man page, bash will perform the brace expansion on each word after splitting a command line into words.
So, that command line will be first split into {chown
, httpd,chmod
and 700}
, and then, since {chown
is not a valid brace expansion pattern, it will be left as is and bash will try to run a command with that name.
This is the quote from the manpage:
Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.
Notice the order, which is different from other shells (in zsh
, the brace expansion will be performed after the arithmetic expansion, and the extra word splitting won't be performed at all).
The following will print 1 2
in zsh
or ksh
, and x y
in bash
:
f=; f1=x; f2=y; echo $f{1,2}