2

I am struggling to get the syntax correct when using rsync paths that have spaces.

I get the following error...

rsync: [sender] link_stat "/media/plex/TV" failed: No such file or directory (2)
    rsync: [sender] change_dir "/home/username/Series" failed: No such file or directory (2)
    rsync: [sender] link_stat "/media/username/backup/TV" failed: No such file or directory (2)
    rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1330) [sender=3.2.3]

I have tried various combinations of brackets, quotations etc but cannot get it to work.

Below is the cut down version of my bash script which is causing the issue:

    source=/media/plex
    destination=/media/username/backup
    
    sub_folders=('Action' \
                    'Comedy' \
                    'Drama' \
                    'Horror' \
                    'SciFi' \
                    'TV Series' \
                    )
    
    array_length=${#sub_folders[@]}

rsync_cmd="/usr/local/bin/rsync"
rsync_options="-a -l --dry-run" 
    
    for (( i=0; i<${array_length}; i++ )) ; do
        rsync_src="$source/${sub_folders[$i]}/"
        rsync_dest="$destination/${sub_folders[$i]}"
    
        if [ ! -d "$rsync_dest" ] ; then
            mkdir -p "$rsync_dest"                                  
        fi
    eval $rsync_cmd $rsync_options $rsync_src $rsync_dest
    
    done

My OS is Ubuntu 24.04 and the file system (on the USB HDD) is ExFAT

If I echo the rsync command (instead of using eval) it shows the following...

/usr/local/bin/rsync -a -l --dry-run /media/plex/TV Series/ /media/username/backup/TV Series

If I put a backslash in the path that has spaces (i.e. 'TV\ Series') then it fixes the rsync command but breaks the mkdir command, the result is:

mkdir: cannot create directory ‘/media/username/backup/TV\\ Series’: Invalid argument
5
  • 2
    that script looks fine to me, it runs the equivalent of mkdir -p './TV Series' (as e.g. set -x shows) which creates a directory called TV Series. The backslash you have in the error message looks odd. You'd get it like that with GNU coreutils mkdir if you had 'TV\ Series' instead. But that shouldn't be an invalid filename either on most Unixy filesystems. What OS and filesystem are you on? Commented Jan 15 at 13:40
  • Thanks ilkkachu, the OS is Ubuntu 24.04 an the file system is ext4 Commented Jan 15 at 14:05
  • Now that I look at it, the path is under /media which at least hints at a removable drive. Are you sure it's an ext4? Because as far as I remember, the backslash may be invalid on FAT variants, which are also what removable drives usually have... (I didn't check if that's the correct error for that case, though.) Anyway, the script as shown shouldn't create a backslash there. Commented Jan 15 at 15:44
  • Apologies I made some silly mistake, the error is actually with rsync and paths with spaces. I did have 'TV\ Series' which fixed the rsync error, but then caused the mkdir error. I have updated my original post with the actual issue. I also incorrectly stated the filesystem was ext4, buts its actually exFAT Commented Jan 15 at 15:59
  • See: How can we run a command stored in a variable? Commented Jan 16 at 6:14

2 Answers 2

5

It almost always better to avoid eval where you can. And since you're using arrays (and therefore a shell such as bash) you can double-quote your variables everywhere you use them and prevent the shell from trying to split words at whitespace.

Try this for size

#!/bin/bash
#
source=/media/plex
destination=/media/username/backup

sub_folders=(
    'Action'
    'Comedy'
    'Drama'
    'Horror'
    'SciFi'
    'TV Series'
)

rsync_cmd=/usr/local/bin/rsync
rsync_options=(-a -l --dry-run)

rsync_src=()
for sf in "${sub_folders[@]}"
do
    rsync_src+=("$source/${sf%/}")
done

"$rsync_cmd" "${rsync_options[@]}" "${rsync_src[@]}" "$destination"

The resulting command is

/usr/local/bin/rsync -a -l --dry-run /media/plex/Action /media/plex/Comedy /media/plex/Drama /media/plex/Horror /media/plex/SciFi '/media/plex/TV Series' /media/username/backup
2
  • Many thanks for your reply Chris, I shall give that a try. Can you explain why its best to avoid eval out of interest ? Commented Jan 18 at 19:01
  • @John the main reason is that it's way too easy to lose track of the nested quotation marks (or the escape characters) and end up with unquoted values that are then inadvertently evaluated/executed by the shell. See Why and when should eval use be avoided in shell scripts? and an answer to What is the "eval" command in bash? Commented Jan 19 at 17:45
-1

Fixed it after reading the rsync man page

It needs both single and double quotes like this...

eval $rsync_cmd $rsync_options '"$rsync_src"' '"$rsync_dest"'
1
  • 3
    If you remove the single quotes, you don't need the eval. Commented Jan 15 at 16:43

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.