How to handle spaces in script

  • Follow


I have the unmount() function below in my ~/.bashrc.  It allows me
to unmount most file systems just by typing unmount.  I now have a 
USB drive mounted with a space in the file name like

/dev/sdf1             233G  152G   82G  66% /media/Passport WD-1

I've tried numerous ways to handle the space in the path name 
"/media/Passport WD-1".  How can this space or spaces be handled?



function unmount()
{

  # Get sdXX or srXX drives, or CIFS mounted file systems.  The -f3,4 will
  # handle a path name with ONE space in it.
  mntpoints="$(mount | egrep '192.168|\/dev\/sd|\/dev\/sr|cifs|loop' | cut -d ' ' -f3,4 | grep -v type)"

  if [ "$mntpoints" ]; then
    for i in $(echo "$mntpoints"); do

      if [ "$i" != '/' ]; then
#      if [ "$i" ]; then
        echo Unmounting "$i"
        sudo /bin/umount "$i"
      fi

    done
  else
    echo "No mounted file systems found."
  fi

}
0
Reply James 10/17/2010 4:21:06 PM

On comp.unix.shell, James Egan <jegan473@comcast.net> wrote:
> I have the unmount() function below in my ~/.bashrc.  It allows me
> to unmount most file systems just by typing unmount.  I now have a 
> USB drive mounted with a space in the file name like
>
> /dev/sdf1             233G  152G   82G  66% /media/Passport WD-1
>
> I've tried numerous ways to handle the space in the path name 
> "/media/Passport WD-1".  How can this space or spaces be handled?
>
> function unmount()
> {
>
>   # Get sdXX or srXX drives, or CIFS mounted file systems.  The -f3,4 will
>   # handle a path name with ONE space in it.
>   mntpoints="$(mount | egrep '192.168|\/dev\/sd|\/dev\/sr|cifs|loop' | cut -d ' ' -f3,4 | grep -v type)"
>
>   if [ "$mntpoints" ]; then
>     for i in $(echo "$mntpoints"); do
>
>       if [ "$i" != '/' ]; then
> #      if [ "$i" ]; then
>         echo Unmounting "$i"
>         sudo /bin/umount "$i"
>       fi
>
>     done
>   else
>     echo "No mounted file systems found."
>   fi
>
> }

Probably the way Ed Morton just taught me to handle
file names with spaces: by setting the IFS (internal field seperator)
to a newline.

IFS='
'

Sid

0
Reply Sidney 10/17/2010 4:41:34 PM


On Sun, 17 Oct 2010 16:21:06 +0000, James Egan wrote:

> I have the unmount() function below in my ~/.bashrc.  It allows me to
> unmount most file systems just by typing unmount.  I now have a USB
> drive mounted with a space in the file name like
> 
> /dev/sdf1             233G  152G   82G  66% /media/Passport WD-1


It would help if you showed the output of "mount" rather than the output 
of "df" if you are going to use "mount" in your script!
 
> I've tried numerous ways to handle the space in the path name
> "/media/Passport WD-1".  How can this space or spaces be handled?

Of course the best way to deal with a problem is to avoid it in the first 
place.
 
 
> function unmount()
Curious syntax, you need either the 'function' or the '()', not both.
> {
> 
>   # Get sdXX or srXX drives, or CIFS mounted file systems.  The -f3,4
>   will # handle a path name with ONE space in it.
>   mntpoints="$(mount |
>   egrep '192.168|\/dev\/sd|\/dev\/sr|cifs|loop' | cut -d ' ' -f3,4 |
>   grep -v type)"

The "grep -v type" will mean that you will not unmont anything that has
field 4 set to "type", which means anything without a space in the name.

>   if [ "$mntpoints" ]; then
>     for i in $(echo "$mntpoints"); do
> 
>       if [ "$i" != '/' ]; then
>         echo Unmounting "$i"
>         sudo /bin/umount "$i"
>       fi
>     done
>   else
>     echo "No mounted file systems found."
>   fi
> }

So probably the first thing you should be informed of is that umount will
take either the directory name (which as you observe can contain spaces)
or the device name. For local devices you can choose the names not to have
spaces, and you can use '-f1' as your cut specification.

It might be that all you want is
	sudo sh -c 'for i in /media/* ; do /bin/umount "$i" ; done'


0
Reply Icarus 10/17/2010 4:57:29 PM

James Egan wrote:

> I have the unmount() function below in my ~/.bashrc.  It allows me
> to unmount most file systems just by typing unmount.  I now have a
> USB drive mounted with a space in the file name like
> 
> /dev/sdf1             233G  152G   82G  66% /media/Passport WD-1
> 
> I've tried numerous ways to handle the space in the path name
> "/media/Passport WD-1".  How can this space or spaces be handled?

Given your original code:

>  mntpoints="$(mount | egrep '192.168|\/dev\/sd|\/dev\/sr|cifs|loop' | cut

You don't need to escape slashes with egrep(1).

>  -d ' ' -f3,4 | grep -v type)"

  mntpoints="$(mount | egrep '192\.168|/dev/sd|/dev/sr|cifs|loop' |
               cut -d ' ' -f3- | grep -v type)"

  …
    echo "$mntpoints" | while read i
    do
      … "$i" …
    done

(RTFM.)  You might want to replace `egrep | cut | grep -v' with `tail | awk' 
(provided that your mount(1) would print headings in the first line).

  mntpoints="$(mount | tail -n +2 | awk '
    $3 ~ /192\.168|\/dev\/sd|\/dev\/sr|cifs|loop/ {
      print $3;
    }')"

Still, it is unclear to me why you would not simply umount(1) on the device 
path (-f 1, or $1), and only grep for the mountpoint.  Also note that the 
output of `mount' and the content of /etc/mtab may differ.  Especially, it 
may be a good idea to `sudo mount' if you `sudo umount' later.

-- 
PointedEars
0
Reply Thomas 10/17/2010 8:19:36 PM

James Egan <jegan473@comcast.net> writes:

> I have the unmount() function below in my ~/.bashrc.  It allows me
> to unmount most file systems just by typing unmount.  I now have a 
> USB drive mounted with a space in the file name like
>
> /dev/sdf1             233G  152G   82G  66% /media/Passport WD-1
>
> I've tried numerous ways to handle the space in the path name 
> "/media/Passport WD-1".  How can this space or spaces be handled?

I usually use the `read' builtin for this kind of work.  In particular,
it preserves spaces in the final field.

Something approximately like this ought to work (completely untested;
will probably need some work refining the patterns).

unmount () {
  declare win=nil
  ## Get sdXX or srX drives, or CIFS mounted file systems.
  while read dev sz used avail pc mntpt; do
    case "$dev,$mntpt" in 
      *,/ | *,*type*) continue ;;
      192.168.* | /dev/sd* | /dev/sr* | cifs,* | loop*) ;;
      *) continue ;;
    esac
    echo "Unmounting $mntpt"
    sudo /bin/umount "$mntpt"
    win=t
  done < <(mount)
  case "$win" in
    nil) echo "No mounted file systems found." ;;
  esac
}

Note the (Bash-specific) use of process substitution so as to keep the
`while' loop from being run in a subshell.  A portable version would
look like

  mount | {
    while read ...; do
      ...
    done
    case "$win" in
      ...
    esac
  }

-- [mdw]
0
Reply Mark 10/28/2010 12:07:29 AM

4 Replies
588 Views

(page loaded in 0.07 seconds)

Similiar Articles:













7/22/2012 1:23:49 PM


Reply: