[comp.unix.wizards] an rm question

moran-william@CS.Yale.EDU (William L. Moran Jr.) (04/14/88)

I managed to create a file whose name contained bizarre characters; in
fact, they were so bizarre that rm * wouldn't remove them (oh well,
porting arc is a nasty business), I got a nonexistent file message.
Anyway, since the directory they were in was junk I went up one dir
and did an 'rm -r' on the directory, and that worked. So, being the
curious sort, I went to the BSD sources and took a look; however, I
can't figure out why the rm -r worked when the other didn't. I would
appreciate any explanation. BTW the original problem was on a Xenix
system, so I would probably accept a "Xenix is f***ed" explanation. :)


			  
			  William L. Moran Jr.
moran@{yale.arpa, cs.yale.edu, yalecs.bitnet}  ...{ihnp4!hsi,decvax}!yale!moran

A man who could reason like that could not reason at all.
				Lord Peter Wimsey

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (04/15/88)

One of the nice things about Korn shell is the 8 bit capability. I can
get evil names out by using something like this:
	fname=`echo "*\\0200*"`
			 ^^^ any octal code for a magic character
	rm $fname

I don't have Xenix source so I can't prove it's not brain damaged.  I
suspect that high bit files are like files starting with '.', and they
have to be explicitly named or they are ignored.  Try:

	mkdir expendable
	cd expendable
	date > .x
	date > y
	ls -la		# show .x and y
	rm *		# delete everything
	ls -la		# .x still there
	cd ..
	rm -r expendable # now the file goes away

  I don't have a virgin copy of BSD, but it works that way on Ultrix.
Now on Ultrix you can't create a file with the high bit set, at least
not easily. If you did I would bet it works the same way as '.' files,
so I think Xenix may be okay on this one.

  For international UNIX we need more than seven bits in a filename, so
if you disagree please use a new header, it's a separate topic.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

nevin1@ihlpf.ATT.COM (00704a-Liber) (04/16/88)

In article <27133@yale-celray.yale.UUCP> moran-william@CS.Yale.EDU (William L. Moran Jr.) writes:
>I managed to create a file whose name contained bizarre characters; in
>fact, they were so bizarre that rm * wouldn't remove them (oh well,
>porting arc is a nasty business), I got a nonexistent file message.
>Anyway, since the directory they were in was junk I went up one dir
>and did an 'rm -r' on the directory, and that worked. So, being the
>curious sort, I went to the BSD sources and took a look; however, I
>can't figure out why the rm -r worked when the other didn't.

Here is the SVR3 explanation (although it should be the same):

When you use '*', the shell expands it into filenames and then splits them
up via delimiters (such as space) to send to an exec() system call.  On
filenames with bizarre chars in them the split is done incorrectly.

When you use 'rm -r', I think (I haven't looked at the sources lately) that
the file names are taken directly out of the directory file so the shell
expansion problems do not occur.

Hope this helps,
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah

shankar@hpclscu.HP.COM (Shankar Unni) (04/16/88)

> I managed to create a file whose name contained bizarre characters; in
> fact, they were so bizarre that rm * wouldn't remove them (oh well,
> porting arc is a nasty business), I got a nonexistent file message.

This isn't "rm"'s fault: Let's say that you managed to create a file called
"a.*\03\07^q". If you just typed in rm a.*\03\07^q, the *shell* steps in
and does nasty stuff. Even quoting doesn't often help (what if the last
character of the file name is '\' ?).

On the other hand, "rm -ir" on the directory containing it helps, because
the shell is no longer involved: "rm" reads the names directly from the
directory.

We had the same problem frequently when people would create files called,
for instance "-b", and rm would choke (-b: illegal option!). The solution
was (a) rm -- -b (the -- terminates the option list, IN MANY IMPLEMENTATIONS),
or (b) rm nonexistentfile -b or (c) /etc/unlink -b (for superusers only).

--scu

guy@gorodish.Sun.COM (Guy Harris) (04/16/88)

> >I managed to create a file whose name contained bizarre characters; in
> >fact, they were so bizarre that rm * wouldn't remove them (oh well,
> >porting arc is a nasty business), I got a nonexistent file message.
> >Anyway, since the directory they were in was junk I went up one dir
> >and did an 'rm -r' on the directory, and that worked. So, being the
> >curious sort, I went to the BSD sources and took a look; however, I
> >can't figure out why the rm -r worked when the other didn't.
> 
> Here is the SVR3 explanation (although it should be the same):
> 
> When you use '*', the shell expands it into filenames and then splits them
> up via delimiters (such as space) to send to an exec() system call.  On
> filenames with bizarre chars in them the split is done incorrectly.
> 
> When you use 'rm -r', I think (I haven't looked at the sources lately) that
> the file names are taken directly out of the directory file so the shell
> expansion problems do not occur.

Half right.

The fact that it does work with "rm -r" is as stated above.

The fact that it *doesn't* work with "rm *" has nothing to do with the reason
stated above.  The problem is that, in most versions of various UNIX shells,
the 8th bit is used internally to indicate quoted characters.  This bit is then
stripped off of all arguments before they are passed to programs.  This means
that if you have a file named "\305ngstrom" (that's (A-with-a-ring)ngstrom, in
ISO Latin #1) in the current directory, it will be read as "\305ngstrom" but
converted to "Engstrom" by the shell.  "rm" won't find "Engstrom" (unless
you're *really* unlucky) and will complain.

When you use "*", the shell does expand it into filenames.  However, since it
does this expansion by reading the directory in which the files occur and
matching each filename it finds against the pattern, there's no need for it to
split the filenames up; they're already split up in the directory!  As such,
the shell does not split the filenames up; try, for instance:

	gorodish$ >"foo bar"
	gorodish$ >"bletch mumble"
	gorodish$ rm -i *b*
	rm: remove bletch mumble? y
	rm: remove foo bar? y

It has no problems with file names including spaces.

The "SVR3 explanation" is "this doesn't happen under SVR3".  The S5R3 Bourne
shell doesn't use the 8th bit for quoting, and doesn't strip them off.  This
comes in handy for removing various test files named "Citro\:en" that I
occasionally create (where '\:e' is the ISO Latin #1 "e with a diaresis"
character, octal 353) or creating the symlink "/UNIX(R)" I have to "/vmunix
(where '(R)' is the ISO Latin #1 "registered trademark" character, octal 256).
(Unfortunately, we don't have the latest internationalized Korn shell in-house
yet, so I can't use my *normal* shell for doing this.  Grumble, grumble....)

wjc@ho5cad.ATT.COM (04/18/88)

In article <27133@yale-celray.yale.UUCP> moran-william@CS.Yale.EDU (William L. Moran Jr.) writes:

> I managed to create a file whose name contained bizarre characters; in
> fact, they were so bizarre that rm * wouldn't remove them (oh well,
> porting arc is a nasty business), I got a nonexistent file message.
> Anyway, since the directory they were in was junk I went up one dir
> and did an 'rm -r' on the directory, and that worked. So, being the
> 

The bizarre chars you mentioned probably had  some with the high-order
bit set.  Many versions of shells use that high bit for their own evil
purposes and strip it off for you (thanks a bunch).  So, the "*" being
expanded by the  shell  didn't exactly match  the  actual names of the
files  in the directory.  The  "rm -r"  doesn't use   expansion by the
shell to get it done, so you get all 8 bits intact.

I found this out by the same sort of experience you had.

	Bill Carpenter
	(AT&T gateways)!ho5cad!wjc

goudreau@xyzzy.UUCP (Bob Goudreau) (04/18/88)

In article <670012@hpclscu.HP.COM> shankar@hpclscu.HP.COM (Shankar Unni) writes:
>We had the same problem frequently when people would create files called,
>for instance "-b", and rm would choke (-b: illegal option!). The solution
>was (a) rm -- -b (the -- terminates the option list, IN MANY IMPLEMENTATIONS),
>or (b) rm nonexistentfile -b or (c) /etc/unlink -b (for superusers only).

The problems with these solutions are:  (a) is non-portable; (b) is a kludge;
and (c) is just unnecessarily harsh on your file system.

A cleaner and more general solution to this problem can be had by simply
thinking about the names by which a given file can be referenced.  That's
right, "names" not "name".  In particular, "./-b" will always do the trick.
There are an infinitude of other ways to refer to the offending file
that don't begin with "-", such as "/usr/foo/-b" (or whatever one of its full
pathnames may be), or "../foo/-b", or "././-b" or ....

-- 
	Bob Goudreau
	Data General Corp.,  62 Alexander Drive,
	Research Triangle Park, NC  27709
	(919) 248-6231
	{ihnp4, seismo, etc.}!mcnc!rti!xyzzy!goudreau
	goudreau@dg-rtp.dg.com

chris@trantor.umd.edu (Chris Torek) (04/18/88)

In article <793@xyzzy.UUCP> goudreau@rtp48.UUCP (Bob Goudreau) writes:
>A cleaner and more general solution to this problem can be had by simply
>thinking about the names by which a given file can be referenced.  That's
>right, "names" not "name".  In particular, "./-b" will always do the trick.

Indeed, as long-time readers of this group know, that is the answer
I always give.  While `rm' has an option to say `no more options',
there exist programs that do not; for these `./name' still works.
Of course, my answer is phrased as a question, usually `name two
names for your file.'  It seems to help retention.  If not, well,
at least it helps reduce the rate of questioning :-) .
-- 
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
Domain: chris@mimsy.umd.edu		Path: ...!uunet!mimsy!chris

rjd@occrsh.ATT.COM (04/19/88)

Does anyone have a program similar to "rm" that will remove a file
based on filessystem and inode number?  I am aware that it would have
to be runnable only by root or setuid root.  (AT&T System 5 release 2
or above...)

Randy

limes@sun.uucp (Greg Limes) (04/19/88)

In article <670012@hpclscu.HP.COM>, shankar@hpclscu.HP.COM (Shankar Unni) writes:
>                          Let's say that you managed to create a file called
> "a.*\03\07^q". If you just typed in rm a.*\03\07^q, the *shell* steps in
> and does nasty stuff.

If you put single quotes around it, this name should get through either
/bin/sh or /bin/csh; you will probably need to use your LNEXT character
(as reported by "stty"; usually Ctrl-V) to get the Ctrl-C and Ctrl-G
characters through the line editor.

>                       Even quoting doesn't often help (what if the last
> character of the file name is '\' ?).

Single quotes around the filename take care of this.

> We had the same problem frequently when people would create files called,
> for instance "-b", and rm would choke (-b: illegal option!).

Try using "./" before the filename. For instance, if you have a file
called "-rf *" in your current directory, the command "rm './-rf *'"
would get rid of it. Note the single quotes here, too.

> --scu

-- Greg Limes [limes@sun.com]			frames to /dev/fb

rroot@edm.UUCP (uucp) (04/19/88)

From article <10431@steinmetz.ge.com>, by davidsen@steinmetz.ge.com (William E. Davidsen Jr):
> One of the nice things about Korn shell is the 8 bit capability. I can
....
] 	mkdir expendable
] 	cd expendable
] 	date > .x
] 	ls -la		# show .x 
] 	rm *		# delete 'everything'
] 	ls -la		# .x still there
] 	cd ..
] 	rm -r expendable # now the file goes away

The easy way to get rid of .x is to name it explicitly..
rm .x
rm .? will also work, but it will complain about .. being
a directory, but if the file were .xx , then rm .??* would
get it (or anything longer, for that matter)
 for getting rid of REALLY random names (like with the 8th bit
set) try:'
  rm -ir .
It will at least ask you if you really want to eat the file.
  (don't use "rm -[i]r .. or .?, since it may try to eat stuff
out of your parent directory...)
-- 
-------------
 Stephen Samuel 
  {ihnp4,ubc-vision,vax135}!alberta!edm!steve
  or userzxcv@uqv-mts.bitnet

mouse@mcgill-vision.UUCP (der Mouse) (04/26/88)

In article <142700029@occrsh.ATT.COM>, rjd@occrsh.ATT.COM writes:
> Does anyone have a program similar to "rm" that will remove a file
> based on filessystem and inode number?  (AT&T System 5 release 2 or
> above...)

I'd suggest clri to zap the inode and fsck to fix make the resulting
filesystem self-consistent; does clri still exist in SVR2 or was AT&T
silly enough to drop it?  (I feel safe assuming fsck still exists :-)

					der Mouse

			uucp: mouse@mcgill-vision.uucp
			arpa: mouse@larry.mcrcim.mcgill.edu

news@edm.UUCP (news software) (04/30/88)

From article <1080@mcgill-vision.UUCP>, by mouse@mcgill-vision.UUCP (der Mouse):
> In article <142700029@occrsh.ATT.COM>, rjd@occrsh.ATT.COM writes:
>> Does anyone have a program similar to "rm" that will remove a file
>> based on filessystem and inode number?  (AT&T System 5 release 2 or
>> above...)
> 
If you are the super-user (or at least have read access to the filesystem,
then use ncheck(1 or 8). 

if /dev/rdsk0 were mounted as /usr2 then something along the lines of:
  for i over `ncheck -i 4432 /dev/rdsk0 ` 
  do
    rm -f /usr2/$i
  done

would remove all copies of inode 4432 from /usr2 .
(I assume that there is a way to map file numbers to /dev names, but
I'm too tired to figure that out right now).

  This is much cleaner than killing the inode and doing an fsck..
among other things:
1) you don't need to unmount the drive and
2) you don't need su privledges (OTHER THAN READ ACCESS TO THE SLICE). 
 
  I consider having public read access to a disk slice a security hole,
since it implies that anybody who really wants to can read any file
on the slice. (just decode the file system)

-- 
-------------
 Stephen Samuel 
  {ihnp4,ubc-vision,vax135}!alberta!edm!steve
  or userzxcv@uqv-mts.bitnet