Brace expansion not working within shell script

kr flag

I'm trying to use brace expansion in a shell script to create a directory structure but I am not getting the desired effect.

With the line sudo mkdir -pv /opt/test/{one,two,three}-way, issuing the command directly to the shell I get the intended result. If I have this within a script, it creates a path opt/test/{one,two,three}-way

Shell result:

jwright@ubuntu-server:/$ sudo mkdir -pv /opt/test/{one,two,three}-way
[sudo] password for jwright: 
mkdir: created directory '/opt/test'
mkdir: created directory '/opt/test/one-way'
mkdir: created directory '/opt/test/two-way'
mkdir: created directory '/opt/test/three-way'

Script result:

jwright@ubuntu-server:~$ sudo sh
[sudo] password for jwright: 
mkdir: created directory '/opt/test1'
mkdir: created directory '/opt/test1/{one,two,three}-way'

You can see from the output that I am running the shell as sudo.

Jonny Wright avatar
kr flag
I have tried with and witout `sudo` actually in the script itself
hr flag
Don't try to run the script with `sh` - brace expansion is not a POSIX shell capability - it's supported by `bash` (and `ksh` and `zsh`) but not by `sh`
hr flag
... see [Why do I get different outputs in case of sh and bash?](
cn flag
Note that the "shell result" example expands the braces in your shell _before_ passing the expanded arguments to sudo.
cn flag

With the command sh, you instruct the dash shell to interpret the script. The dash shell is the system wide default shell in Ubuntu, whereas the more "heavy" (and bash developpers themselves even say "bloated" bash shell is used for interactive shells (your prompt at the terminal).

dash is light and more minimal, and does not support all features of bash. That includes bracket expansion. If you want to use bash specific features in your script, then load it with bash:


If you make the script executable, then the shebang line is what you use to indicate which interpreter should run the script. This is a very first line in a script, included as a comment:


If the script is made executable, then run by typing its name (/path/to/ or ./ if the script is in the current directory, or just if the script is in the PATH searched by the system for executable), this directive will tell it to be run with bash.

The shebang line will not be honored if you start the script as an argument to the interpreter. Thus, even if the shebang line would be there, sh will still be using dash rather than bash.

I sit in a Tesla and translated this thread with Ai:


Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.