Not correct processing of “\ “ in names of dirs inside shell script (tar command - system backup scr

Hello,

Recently, I've started with shell scripting, and decided to write a script for my system backup using tar. When I was dealing with tar execution inside shell script I found this, inside shell we have the following code:

tar $TAR_PARAMS $ARCHIVE_FILE $EXCLUDE $BACKUP_START

with reflection

tar -cvpzf /home/ilnar/Doenloads/laptop_backup_2011_06_04_125909.tar.gz  --exclude=/home/ilnar/Downloads/laptop_backup_2011_06_04_125909.tar.gz 
--exclude=/proc 
--exclude=/dev
(etc... further home dirs)
--exclude=/home/ilnar/Desktop
--exclude=/home/ilnar/Pictures
(etc..AND MAIN QUESTION)
--exclude=/home/ilnar/Documents
--exclude=/home/dasha/my\ songs
(start from...)
/

So, command should exclude �my songs� from gzip archive, bit it doesn't. If I execute this command directly in shell, everything is ok, but when the same is in shell script it doesn't work! I've tested with:

echo tar $TAR_PARAMS $ARCHIVE_FILE $EXCLUDE $BACKUP_START

I'm using ubuntu 11.04

(Please note: with my backup and restore scripts I want to exclude all users folders with files like heavy video and audio etc., but not users settings (like .hidden_files))

I'm writing about �spaces� because�, my wife Dasha may create such directories. If you want to look on my scripts, see the attachments.

Will be appreciate for any answers and comments, why this happens.

P.S I live in Russia, so sorry if I have language mistakes, I'm studding English with passion in deed...

sorry, forgot attachments

Try with

--exclude=/home/dasha/my\\ songs

Thanks for reply
I,ve tried this, but unfortunately, it was included in tar archive anyway, the code, that does changes from " " => "\\ " inside dir names is:

OLD_IFS="$IFS"
IFS=""
USER_EXCLUDE=`ls -d ${HOME_DIR}/*/*/`
USER_EXCLUDE=`echo $USER_EXCLUDE | sed s/" "/"\\\\\\\\\\\\\ "/g`
USER_EXCLUDE=`echo $USER_EXCLUDE | sed s/"\(.*\)\/"/"--exclude=\1"/g`
IFS=$OLD_IFS

It's required so many \\\\\\\\\\\..., to reflect "\\"

If the value stored in the variable $EXCLUDE contains any IFS characters (by default, space, newline, and tab), after the shell expands $EXCLUDE into its value, it will split the resulting string into fields on those IFS characters. All the backslashes and quotes in the world within the value of $EXCLUDE won't stop that, since those backslashes and quotes are not in any way special to the shell (by the time field splitting begins, the parsing step that looks for quotes has completed).

Regards,
Alister

1 Like

Thanks Alister,

I suppose there is no way to expand $EXCLUDE with correct meaning of "\ " :wall: I think this is kind of disadvantage of shell programming to traditional. There should be clear text manipulation(processing) mechanism...

That's because you're using double-quotes, where the shell handles escaping itself and needs two to tell it to ignore it. Try single single-quotes, where escaping doesn't happen in the shell:

's/ /\\ /g' is equivalent to  "s/ /\\\ /g"

And you can single-quote just part of an expression too, the way you've been doing with double quotes.

I just remembered another trick: IFS=$'\n' This will cause the shell to split only on newlines when expanding variables -- spaces in directory names won't bother it at all. IFS is a special variable telling it how to expand variables and how to split when using read. This is the 'clear text processing mechanism' you wanted :slight_smile: