[plug] rm of contents

Russell Steicke r.steicke at bom.gov.au
Tue Mar 18 06:57:57 WST 2003


There is a little too much misinformation in this thread.  Perhaps some
working examples are in order.  :)

  ~/tmp/s$ touch '$(rm -rf *)'
  ~/tmp/s$ touch anotherfile
  ~/tmp/s$ ls -al
  total 8
  drwxr-xr-x    2 russells russells     4096 Mar 18 05:58 ./
  drwxr-xr-x    3 russells russells     4096 Mar 18 05:50 ../
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 anotherfile
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 $(rm -rf *)
  ~/tmp/s$ for file in * ; do echo "$file" ; done
  anotherfile
  $(rm -rf *)
  ~/tmp/s$ ls -al
  total 8
  drwxr-xr-x    2 russells russells     4096 Mar 18 05:58 ./
  drwxr-xr-x    3 russells russells     4096 Mar 18 05:50 ../
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 anotherfile
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 $(rm -rf *)
  ~/tmp/s$ find . -type f -print0 | xargs -0 echo
  ./$(rm -rf *) ./anotherfile
  ~/tmp/s$ ls -al
  total 8
  drwxr-xr-x    2 russells russells     4096 Mar 18 05:58 ./
  drwxr-xr-x    3 russells russells     4096 Mar 18 05:50 ../
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 anotherfile
  -rw-r--r--    1 russells russells        0 Mar 18 05:58 $(rm -rf *)
  ~/tmp/s$

Notice that the * didn't get expanded in either case (for or
find/xargs), and the rm command inside $() didn't get run in either
case.

The point is that quoting in bash (and shells generally) actually does
work when done right.  If you don't want the shell to expand characters
in filenames, then you can prevent that from happening.  bash(1) can be
a bit hard to read, but it's complete.  An abbreviated rule: "Always
double-quote shell variables".

If you're worried about what xargs or the commands you tell it to run
will do to your filenames (you should be), use the -print0 flag to find,
matched to the -0 flag to xargs. [1]

The suggestion to write everything in "real" scripting languages (where
"real" == "not shell") is a bit harsh.  For instance, perl does
expansion inside strings just like the shells, only different, and you
have to understand how that works, just like the shells.  The advantage
of sh is that in this world (unix/linux) it's everywhere.

For a bigger example, apt-proxy is written in sh (#!/bin/ash), 1370
lines of it.  That's not a use-once throwaway script, it's a useful
background program that gets run by inetd, potentially many concurrent
instances of it.


[1] There are other uses for xargs -0.  If you use the example procmail
rule from procmailex(1) that deletes duplicate messages by caching their
Message-Id headers, you'll have a file called msgid.cache that contains
the Message-Ids null-separated.  This is how you can easily read it:

  $ xargs -0 -n 1 echo < msgid.cache
  <200302061032.57189.T.Phillips at murdoch.edu.au>
  <1044500756.1129.7.camel at desktop2.rmsurveys.com.au>
  <Pine.LNX.4.44.0302061030150.7052-100000 at ob.golden.wattle.id.au>
  <200302061132.18046.leon at brooks.fdns.net>



-- 
Russell Steicke

-- Fortune says:
Put cats in the coffee and mice in the tea!



More information about the plug mailing list