Escape command parameters for re-use in Bash? [duplicate] - bash

This question already has answers here:
Why do bash parameter expansions cause an rsync command to operate differently?
(2 answers)
How can I store a list of arguments in a variable in bash?
(2 answers)
Closed 1 year ago.
I want to save command parameters for re-use in a variable in Bash. The reason is they are very long and I use them multiple times.
SRC_FOLDER="src folder"
DST_FOLDER="dst folder"
PARAMS="--dry-run \"$SRC_FOLDER\" \"$DST_FOLDER\""
rsync $PARAMS
The problem is the space in the src and dst folder. Rsync thinks there are 4 folders instead of 2. I think I somehow have to escape the variables in line 3.
I cannot escape the folders in line 1 and 2 because they might have been passed to my bash script by parameter and I don't know the content.
Please also note that the src and dst folders may have other special signs like *, $, \, ", '.
Is this possible without using separate variables like this:
rsync $PARAMS "$SRC_FOLDER" "$DST_FOLDER"
Is there a solution?

#!/bin/bash
rsync_args=(
--dry-run
"src folder"
"dst folder"
)
rsync "${rsync_args[#]}"
About the problem that I mentioned in my comment:
The remote path in rsync commands is subject to word splitting.
The following example is wrong:
rsync -av ~/ user#server:'home backup 2021-12-04/'
You have to write it like this:
rsync -av ~/ user#server:'home\ backup\ 2021-12-04/'
A way for fixing it automatically is:
#!/bin/bash
remote_path='home backup 2021-12-04/'
qq="'\''"
rsync -av ~/ user#server:"'${remote_path//\'/$qq}'"

Related

bash cp filenames with spaces [duplicate]

This question already has answers here:
Tilde in path doesn't expand to home directory
(5 answers)
Closed 4 years ago.
I'm using variables in bash script to hold folder names (to iterate over multiple folders).
I'd like to copy files from one to another, the files exist in source directory. Folders and filenames contain spaces, so I must use double quote.
For instance:
#!/bin/bash
inpath="~/foo bar/"
outpath="~/temp basket/
cp "$inpath*" "$outpath"
The copy fails as: '~/foo bar/*' No such file or directory
Is there any consistent way to do that?
Only quote the parts you don't want expanded or split:
inpath=~/'foo bar'
outpath=~/'temp basket'
cp -- "$inpath/"* "$outpath"

I want to move all files from one folder to other folder using shell script [duplicate]

This question already has answers here:
Command not found error in Bash variable assignment
(5 answers)
Closed 4 years ago.
I want to move all files from one folder to other folder using shell script.
This is my code but it throws error
#!/bin/sh
SRC = '/home/xxx/test1/'
DESTN = '/home/xxx/test/'
mv SRC DESTN
Error:./move.sh:2:./move.sh:SRC:not found
./move.sh:2:./move.sh:SRC:not found
mv:cannot stat 'SRC': No such file or directory
When declaring shell variables, you cannot add spaces between the variable name and the = sign, nor between the = and the value.
Also remember to add $ before the variable name when using it after its declaration.
Your script should look like this one:
#!/bin/sh
SRC="/home/xxx/test1/*"
DESTN="/home/xxx/test"
mv "$SRC" "$DESTN"

Bash Wildcard and Variable Usage [duplicate]

This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed 4 years ago.
What I'm trying to achieve is copying everything at source directory to destination directory by excluding the workspace directory, I have the following command to do so:
rsync -av --exclude='directory-name*/workspace' sourceDir destinationDir
which is working well, but if I try to use variable for the "directory-name":
VARIABLE_NAME="directory-name"
rsync -av --exclude='$VARIABLE_NAME*/workspace' sourceDir destinationDir
Variables are not expanded when put inside single quotes, use double quotes instead:
rsync -av --exclude="$VARIABLE_NAME"'*/workspace' sourceDir destinationDir

mkdir: omit leading pathname when creating multiple directories? [duplicate]

This question already has answers here:
Bash mkdir and subfolders [duplicate]
(3 answers)
Closed 6 years ago.
I'm sure this question has been asked elsewhere but I can't seem to phrase it in a way that returns a useful Google result.
I am creating a dozen directories that all have the same root path and I don't want to have to cd into it to be able to make these directories. The current command looks like something like, which is awful and repetitive:
$ mkdir frontend/app/components/Home frontend/app/components/Profile \
frontend/app/components/Post frontend/app/components/Comment
An ideal syntax would be something along the lines of:
$ mkdir frontend/app/components/{Home, Profile, Post, Comment}
Is there something like this already that I just haven't found? I don't want to have to run a for loop just to make a few directories.
Your wish is granted :-).
mkdir doesn't know and doesn't have to, but shells like bash or zsh understand the syntax {...,...,...}.
Just remove the spaces from your "along the lines of" and it works:
mkdir frontend/app/components/{Home,Profile,Post,Comment}
The shell will expand it to
mkdir frontend/app/components/Home frontend/app/components/Profile frontend/app/components/Post frontend/app/components/Comment
Since it is done by the shell, it works with any command.
Remove spaces around comma and use -p option:
mkdir -p frontend/app/components/{Home,Profile,Post,Comment}

rsync in shell for loop [duplicate]

This question already has answers here:
Getting "command not found" error in bash script
(6 answers)
Closed 3 years ago.
I have this shell script
#!/bin/sh
PATHS=( a b c d )
for PATH in ${PATHS[#]}
do
rsync -avziP /home/user/$PATH $SERVER:$server_folder -b --backup-dir=$backup_folder/backup_$date --delete --exclude=.* --log-file=$HOME/rsync.log
done
And I always get this error:
rsync: command not found
What is driving me crazy is that if I delete the for loop, and just run the rsync command, the script works perfectly
PATH is a reserved variable!
It is the variable specifying where to search tools (like rsync)
$ set | grep ^PATH=
PATH=/home/user/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Use another variable name!

Resources