1

I would like to run the below command in a bash script but, it doesn't work.

command:

cp /tmp/first/{abc.conf,xyz.conf} /tmp/backup/

bash script:

firstDir=/tmp/first
#secondDir=/tmp/second
validDir=$firstDir
#validDir=$secondDir
backupDir=/tmp/backup

files='{abc.conf,xyz.conf}'

join=$firstDir/$files
#join=$secondDir/$files

cp $join $backupDir
exit 0
rm -rf $validDir
mkdir $validDir

cp ("$backupDir/*.conf") $validDir

error:

cp: cannot stat '/tmp/first/{abc.conf,xyz.conf}': No such file or directory

The objective is to clean the directory and then put back only those 2 files.

  • 1
    IIRC, brace expansion takes place before parameter expansion (e. g. variables), which is why this is not working as you expect. For an operation this simple, you might be best served just running two individual cp commands for the two files you wish to preserve. – DopeGhoti Apr 16 at 21:53
3

Brace expansion happens before parameters are expanded, so

files='{abc.conf,xyz.conf}'
join=$firstDir/$files

results in literally setting the variable to /tmp/first/{abc.conf,xyz.conf}, and it won't be re-processed when it's expanded in your cp command.

Instead, you could write

cp "$firstDir"/{abc.conf,xyz.conf} "$backupDir"

literally, and it will expand the way you want.

There is no way to force brace expansion to happen out of a variable, but you could use an array to keep the filenames and command separate, even using brace expansion to define it:

files=( "$firstDir"/{abc.conf,xyz.conf} )

and later ${files[@]}.

  • That works great! Cheers! Here is the code: firstDir=/tmp/first secondDir=/tmp/second if true; then validDir=$firstDir else validDir=$secondDir fi backupDir=/tmp/backup files=( "$validDir"/{abc.conf,xyz.conf} ) cp ${files[@]} $backupDir rm -rf $validDir mkdir $validDir cp "$backupDir"/{abc.conf,xyz.conf} $validDir – jtech Apr 16 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.