LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-23-2006, 06:52 AM   #1
colabus
Member
 
Registered: Mar 2004
Distribution: Debian Sarge, FC4
Posts: 100

Rep: Reputation: 15
Bash script - escaping whitespaces


Hi all,

I wrote a little script I'm using to do checksums on my backups.

Code:
typhon:/var/www# cat /var/www/md5chk.sh
#!/bin/bash

checksumDir="/home/www-data/checksums/"

if [ $# -lt 3 ] ; then
        echo "* Error: $0 [directory] [type] [number]"

        exit 1
else
        if [ -d $1 ] ; then
                for i in $( find $1 -type f ); do
                        md5sum -b $i >> $checksumDir/$2.$3
                done
        else
                echo "* Error: $1 is not a directory"

                exit 1
        fi
fi

echo "Successfully completed."

exit 0
My problem is with filename with whitespace characters in them. I can't quite work out how to make $i escape it's whitespace chars.

I'd imagine it's gonna something along the lines of: sed 's/ /\\ /' cause I can get it working with `echo "hello world" | sed 's/ /\\ /'`, I'm not sure how to apply this with the $i variable.

Could someone help me out with this? I've been googling for a while with no luck lol.

Cheers.
 
Old 04-23-2006, 07:26 AM   #2
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 61
Quote:
md5sum -b $i ....
Put the $i in quotes "$i"
 
Old 04-23-2006, 08:41 AM   #3
colabus
Member
 
Registered: Mar 2004
Distribution: Debian Sarge, FC4
Posts: 100

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by homey
Put the $i in quotes "$i"
I have already tried that. Still get errors, I need the whitespaces escaped.
 
Old 04-23-2006, 09:02 AM   #4
colabus
Member
 
Registered: Mar 2004
Distribution: Debian Sarge, FC4
Posts: 100

Original Poster
Rep: Reputation: 15
OK kinda got a little further here.

Code:
for i in $( find $1 -type f | sed 's/ /\\ /g' ); do
This does want I want but the problem is the the whitespace char, so "Hello\ World" will be 1. "Hello\" and 2. "World" in the loop. Any way in bash to make the for loop make i read the entire line?

Yes, I've tried quotes here too. Same problem.

Cheers
 
Old 04-23-2006, 11:31 AM   #5
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 34
My usual recommendation is to use zsh, which doesn't do stupid things like automatic word splitting on scalar variables. Bash is a poor excuse for a shell, IMO.
 
Old 04-24-2006, 05:21 PM   #6
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
@colabus: the solution was handed to you by homey. The problem was obscured by the "for loop" expansion. Note that you best use "while loops" if you can't guesstimate what the expansion will amount to:
Code:
find $1 -type f|while read i; do md5sum -b "$i" >> $checksumDir/$2.$3; done

@ioerror:
Quote:
My usual recommendation is to use zsh
That's why all the OSes install Zsh as default shell and all the "important" apps are written as or ported to zsh shell scripts, right?.. Not.

Last edited by unSpawn; 04-24-2006 at 05:23 PM. Reason: //have keybd, can't type
 
Old 04-24-2006, 05:33 PM   #7
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 34
Quote:
That's why all the OSes install Zsh as default shell
Er, zsh is the default shell on MacOS X. NetBSD has it's own shell, other "OSes" use other shells, etc. Bash is the default shell on Linux because bash is the GNU shell, and Linux systems are GNU systems. So what? Any complete distribution will include zsh, tcsh, ksh etc. A distro that only installs bash is one I wouldn't touch with barge pole.

Quote:
the "important" apps are written as or ported to zsh shell scripts, right?
I thought that "important" apps were written in C.

There is nothing magical about bash, it is just the GNU shell. I don't think it's very good, it has lots of stupidities, like automatic word splitting. So I use zsh, and I merely suggested that the querent give it a try since it will automatically solve his problem. What's wrong with that?
 
Old 04-24-2006, 07:35 PM   #8
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
I thought that "important" apps were written in C.
Yeah, I should probably rephrase that as: "there are more popular and commonly used tools written in Bash compared to Zsh".


like automatic word splitting.
See IFS variable.


I merely suggested that the querent give it a try since it will automatically solve his problem. What's wrong with that?
I'm not questioning your competence but, considering the "fix" is that trivial, substituting Bash for zsh is utterly unnecessary.
 
Old 04-25-2006, 05:27 AM   #9
timmeke
Senior Member
 
Registered: Nov 2005
Location: Belgium
Distribution: Red Hat, Fedora
Posts: 1,515

Rep: Reputation: 61
@colabus:
to summarize the discussion between ioerror and unSpawn:
set $IFS prior to your for-loop.
Give it a value like "\n" (newline) only.
This should make the for-loop avoid splitting the words (shell splits up the words on spaces, tabs and newlines by default) that come out of the "find" command.

See:
Code:
man bash
and search for "IFS".
 
Old 04-25-2006, 06:06 AM   #10
T.Hsu
Member
 
Registered: Jan 2005
Posts: 178

Rep: Reputation: 31
Why not use find's `-exec' command?
 
Old 04-25-2006, 06:14 AM   #11
timmeke
Senior Member
 
Registered: Nov 2005
Location: Belgium
Distribution: Red Hat, Fedora
Posts: 1,515

Rep: Reputation: 61
Good point, H. Tsu.

An alternative would be to use the -print0 option of "find" and to pipe it into xargs -0.
I've seen solutions like that around on this forum too.
 
Old 04-25-2006, 06:18 AM   #12
T.Hsu
Member
 
Registered: Jan 2005
Posts: 178

Rep: Reputation: 31
Or

for i in "$(find . -maxdepth 1 -type f)"; do md5sum "$i"; done
 
Old 04-25-2006, 06:48 AM   #13
T.Hsu
Member
 
Registered: Jan 2005
Posts: 178

Rep: Reputation: 31
Also

find . -type f | while read line; do md5sum "$line"; done

Note newline char is "legal" in filename, so this one may not work properly.

The best solution I think is

find . -type f -print0 | xargs --null md5sum

Last edited by T.Hsu; 04-25-2006 at 06:53 AM.
 
Old 04-25-2006, 09:50 AM   #14
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 34
Quote:
there are more popular and commonly used tools written in Bash compared to Zsh
Well, bash is more prevalent (at least on Linux), so it's natural that more people would use it, but zsh could probably run most of those scripts without modification, although it does have a few subtle incompatibilities with POSIX syntax.

Quote:
I'm not questioning your competence but, considering the "fix" is that trivial, substituting Bash for zsh is utterly unnecessary.
OK, for a single case I would agree, but personally I haven't used bash for years, so no substitution occurs!

I don't want to start a pointless bash vs. zsh debate but zsh has lots of other features (e.g. nested parameter expansion (which bash still can't do), associative arrays, etc) which makes it an excellent choice both for scripting and interactive use. OK, I'm going to stop now. I only mentioned it in the first place because bash is so prevalent and the lesser known shells often get overlooked. After all, Linux is all about choice...
 
Old 04-25-2006, 10:03 AM   #15
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
I don't want to start a pointless bash vs. zsh debate
Me neither.


but zsh has lots of other features (e.g. nested parameter expansion (which bash still can't do), associative arrays, etc)
Yes, you're right there. Bash' array-fu certainly isn't that evolved.
 
  


Reply



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
Bash, LS, For loops, and whitespaces in directories jhrbek Programming 27 09-22-2010 05:17 AM
Automatic special character escaping in Bash scripts? wipe Linux - Software 1 06-05-2009 06:41 PM
NOT escaping bash history ivanatora Linux - General 3 06-07-2005 01:17 PM
send automatic input to a script called by another script in bash programming jorgecab Programming 2 04-01-2004 12:20 AM
handling whitespaces in bash guerilla fighta Linux - General 2 01-25-2003 04:12 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 08:11 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