Why is this working:
mkdir /dir/test{1,2,3}
and this not?
{chown httpd,chmod 700} /dir/test1
-bash: {chown: command not found
My Bash Version is: GNU bash, version 4.2.46(2)-release
Why is this working:
mkdir /dir/test{1,2,3}
and this not?
{chown httpd,chmod 700} /dir/test1
-bash: {chown: command not found
My Bash Version is: GNU bash, version 4.2.46(2)-release
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
mkdir test{,2," three",\ four} (creates directories "test", "test2", "test three", "test four")
– Freddy
Feb 11 '19 at 13:40
eval {'chown http','chmod 0666'}' /tmp/foo;'.
–
Feb 11 '19 at 15:13
eval and with very careful quoting, it would be possible to do what the user wanted.
– Kusalananda
Feb 11 '19 at 15:22
PATH.
– JoL
Feb 11 '19 at 16:29
eval {'"chown http"', ...}
– Kusalananda
Feb 11 '19 at 16:31
{"chown httpd","chmod 700"} /dir/test1 and got bash: chown httpd: command not found.
– JoL
Feb 11 '19 at 16:33
eval.
– JoL
Feb 11 '19 at 16:36
bash's history expansion to use the last command line argument as in !#:1. https://askubuntu.com/a/1109025/295286
– Sergiy Kolodyazhnyy
Feb 11 '19 at 22:12
bash-like shell in which that simply doesn't work, whether sensical or nonsensical.
–
Feb 12 '19 at 08:16
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}
a variable contains the string x y, then a command line like echo $a will be 1st split into echo and $a, then $a will be expanded into x y, and then split again into x and y, giving echo, x and y as separate arguments. The latter step will be done using the value of IFS ( not necessarily containing spaces) and does not happen in zsh.
–
Feb 11 '19 at 13:39
The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable from bash reference guide.
– LRDPRDX
Jun 04 '20 at 13:06
Other answers have explained why the brace expansion doesn't work. Ignoring that question for a moment, you probably want to avoid repeating the filename, and there are other ways to do that. Either assign the file name to a variable, or use the $_ special variable (it contains the last shell word of the previous command):
f="some long and ugly filename"
chown httpd "$f"
chmod 700 "$f"
or
chown httpd "some long and ugly filename"
chmod 700 "$_"
tee+xargscan help if you have a very long path which you don't want to repeat each time:tee >(xargs chown httpd) >(xargs chmod 700) <<< /dir/test1. – jimmij Feb 11 '19 at 12:53