LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 11-21-2014, 07:25 AM   #1
itayshom
LQ Newbie
 
Registered: Nov 2014
Distribution: OpenSUSE
Posts: 3

Rep: Reputation: Disabled
Bash script: confusing concatenation of explicit string and variable


Hello all,

I'm trying to use rsync to back up my data with the following script:

Code:
#!/bin/bash

TARGET="/var/run/media/itayshom/160 GB Volume"

rsync -a /home/itayshom "'${TARGET}'"
However, I get the following error:

Code:
rsync: mkdir "/home/itayshom/'/var/run/media/itayshom/160 GB Volume'" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(656) [Receiver=3.1.1]
For some reason, my home directory string gets concatenated to the next argument (even though there's a space).
If I just echo the command, I get the correct answer:

Code:
rsync -a /home/itayshom '/var/run/media/itayshom/160 GB Volume'
and it executes perfectly if entered by hand!

I know bash quotation can be tricky but I couldn't find an answer to this one.

Does anyone know what the problem is?

Thanks,
Itay.
 
Old 11-21-2014, 09:13 AM   #2
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,792

Rep: Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220
It is not concatenating the strings. It's just that your CWD happens to be the same as that source argument, and rsync is trying to create a directory "$CWD/'/var/run/media/itayshom/160 GB Volume'".

The real problem is that for a local destination you don't want that extra level of quoting to protect the spaces in that argument since there is no remote shell involved. Since the path is seen as beginning with a quote mark and not "/", it is taken as relative to the CWD rather than absolute. Any of these should work:
Code:
rsync -a /home/itayshom "${TARGET}"                           # Eliminate the extra quoting
rsync -a /home/itayshom localhost:"'${TARGET}'"               # Make it a "remote" destination
rsync -a --protect-args /home/itayshom localhost:"${TARGET}"  # Protect the arguments against word splitting
rsync -a --protect-args /home/itayshom "${TARGET}"            #    and the same syntax works for both local and remote
 
1 members found this post helpful.
Old 11-21-2014, 10:14 AM   #3
itayshom
LQ Newbie
 
Registered: Nov 2014
Distribution: OpenSUSE
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks rknichols! It works.

I used the first example, even though I don't completely understand why I can give up the quotes.

I have a follow-up question. Now I want to execute the command

Code:
rsync -a --exclude='.cache/' --exclude='.thumbnails/'  /home/itayshom '/var/run/media/itayshom/160 GB Volume'
So as to exclude some directories from backup. I want to keep the quotes because in the future I might have some directories with spaces in their names. For this I wrote the script:

Code:
#!/bin/bash

TARGET="/var/run/media/itayshom/160 GB Volume"

EXCLUSIONS=(
  ".cache"
  ".thumbnails"
)

for i in "${EXCLUSIONS[@]}"; do EXCLUDE+="--exclude='$i/' "; done   # note the quotes around $i/

rsync -a "${EXCLUDE}" /home/itayshom "${TARGET}"
Again, when echoing the last line it shows up exactly as I want it (this is very annoying). However running the script, rsync misinterprets the --exclude arguments and copies the contents of .cache etc.
This happens even if I remove the single quotes, e.g. --exclude=.cache/ so I hope this question is not just repeating my previous one.

How can I make bash to tell rsync the right directories to exclude?

Any help would be much appreciated
Itay.
 
Old 11-21-2014, 10:58 AM   #4
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,792

Rep: Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220Reputation: 2220
Quote:
Originally Posted by itayshom View Post
Code:
rsync -a "${EXCLUDE}" /home/itayshom "${TARGET}"
You can't have those quotes around ${EXCLUDE}. That causes the whole string to be passed as one argument, so rsync would try to exclude a file whose name was the entire string following that first "=" character, as though you had entered:
Code:
--exclude=".cache --exclude=.thumbnails"
And, you indeed don't want those single quotes around the individual file names. They will be taken literally, as part of the name.

It gets messy trying to build up argument strings that way. Using an array is much more straightforward:
Code:
EXCLUSIONS=(
  ".cache"
  ".thumbnails"
)
N=0
for i in "${EXCLUSIONS[@]}"; do EXCLUDE[N++]="--exclude=$i/"; done

rsync -a "${EXCLUDE[@]}" /home/itayshom "${TARGET}"
I believe this all works even when some of the EXCLUSIONS names contain embedded spaces.

Last edited by rknichols; 11-21-2014 at 11:02 AM. Reason: Switch from associative to indexed array type
 
1 members found this post helpful.
Old 11-21-2014, 04:28 PM   #5
itayshom
LQ Newbie
 
Registered: Nov 2014
Distribution: OpenSUSE
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thanks! That solved it.

Itay.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Bash Shell Script - Store a variable as a string not an integer RML1992 Linux - General 8 09-12-2012 09:19 AM
Variable concatenation in bash. stf92 Linux - Newbie 3 11-11-2010 12:22 AM
csh Shell Script: String Concatenation, how do i add a new line character? vxc69 Programming 1 05-04-2009 07:51 PM
bash script path issue - how to pass a path as a string to a variable PiNPOiNT Programming 5 04-17-2009 05:48 PM
Help: removing a variable substring from a string variable in sh script gnparsons Programming 2 06-04-2008 05:21 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 12:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration