brooks@ge-dab.ge.com (Stephen Brooks) (11/12/90)
In the C-shell, you can prevent alias substitution by preceding the aliased command with a backslash. For example, you might have: % alias rm rm -i % alias cd cd !* ; pwd However, why does "\rm" work, but "\cd" does not? Yes, I realize that "cd" is a C-shell builtin command, but I haven't been able to find any discussion on how the \ prevents alias substitution. For example (using the above aliases): ==================== this does what I expect ==================== % ls file1 file2 file3 % rm * rm: remove file1? n rm: remove file1? n rm: remove file1? n % ls file1 file2 file3 % \rm * % ls % ==================== this does not do what I expect ==================== % cd /usr/users/steve % \cd cd: Command not found. So, why does the \ prevent the C-shell from recognizing the builtin command as well as preventing alias substitution? Feature? Bug? -- %% Stephen (Steve) M. Brooks %% brooks@ge-dab.ge.com %% %% GE Simulation & Control Systems %% ...!uunet!ge-dab.ge.com!brooks %% %% P.O. Box 2825, Rm. 1370 %% ...!uunet!sunny.dab.ge.com!brooks %% %% Daytona Beach, FL 32115-2825 %% voice: (904) 239-4855 %%
maart@cs.vu.nl (Maarten Litmaath) (11/14/90)
In article <6663@ge-dab.ge.com>, brooks@ge-dab.ge.com (Stephen Brooks) writes: )... ) % alias rm ) rm -i ) % alias cd ) cd !* ; pwd ) )However, why does "\rm" work, but "\cd" does not? [...] Feature. An initial backslash prevents both alias substitution and builtin interpretation. If you want to skip aliases only, use this: % ''cd or % ""cd -- nreadwin@micrognosis.co.uk (Neil Readwin) on "snuff" films: "Seen one ? I was *in* one. They tortured me horribly and then killed me with a single shot in the back of the head ! Following total brain death I gave up acting and became a VMS hacker."
arthur@sgi.com (Arthur Evans) (11/14/90)
In article <6663@ge-dab.ge.com> brooks@ge-dab.ge.com (Stephen Brooks) writes: > > In the C-shell, you can prevent alias substitution by preceding the >aliased command with a backslash. For example, you might have: > > % alias rm > rm -i > % alias cd > cd !* ; pwd > >However, why does "\rm" work, but "\cd" does not? Yes, I realize that >"cd" is a C-shell builtin command, but I haven't been able to find any >discussion on how the \ prevents alias substitution. Well, here's my shot in the dark. The csh is setting the high bit on the first character of your command to "quote" it--prevent it from matching a metacharacter when the shell does filename substitution. So your command, with high bit set, is searched for in the list of builtin commands. When the shell doesn't find it there it does filename substitution--"globbing"--in the course of which it strips the high bit. Then it searches for your command, sans high bit, in the hash list and/or search path. In the case of "rm," the shell finds what it's looking for. In the case of "cd," it doesn't. OK -arthur -- "If I had all the money I'd spent on drink ... I'd spend it on drink." -- Sir Henry Rawlinson Arthur Evans arthur@rawlinson.wpd.sgi.com
chris@mimsy.umd.edu (Chris Torek) (11/14/90)
(this almost certainly belongs in comp.unix.shell, so I have redirected followups there, not that I actually expect any) In article <6663@ge-dab.ge.com> brooks@ge-dab.ge.com (Stephen Brooks) writes: > In the C-shell, you can prevent alias substitution by preceding the >aliased command with a backslash. ... why does "\rm" work, but "\cd" >does not? Yes, I realize that "cd" is a C-shell builtin command, but >I haven't been able to find any discussion on how the \ prevents alias >substitution. It is a side effect. The C shell first breaks each input line into a `word vector'. It then matches against aliases. Since `\rm' does not match `rm', any alias is ignored. Eventually the C shell fully applies any quoting (since an alias can include quotes, some of this work must be deferred; since an alias can include multiple words, more word vector work must be done as well; it all gets rather hairy). The C shell implements quoting by setting the 8th bit (bit 7) of each byte of a quoted character. Since '*'|0x80 is not the same character as '*', this prevents file name expansion, further word breaking, and so on. Eventually, the shell has a fully `parsed' line. It then compares word[0] against all the built-ins. If there is a match, it runs the corresponding built-in command (and it is up to that command to expand any remaining words; for instance, `ls *' in a directory containing only the file `-l' produces a long listing, but `jobs *' produces a usage message). If not, the shell performs globbing on the current word list, producing a new word list, and then: a) strips the 8th bit of each byte of each word b) exec()s the resulting command. This means that \cd not only bypasses any alias, but also reaches the built-in scanner as 'c'|0x80, 'd', '\0' which does not match the built-in command 'c', 'd', '\0' and so does not run the `cd' builtin. It is later stripped and the shell looks for an external program called `cd'. If you want to avoid alias substitution, but not built-in matching, you can replace \cd foo or \rm foo with ''cd foo or ""rm foo These do not match the aliases---during alias scanning they have quote pairs in front of them---but do match any builtin since the quotes have by then been stripped (setting bit 7 of all the characters contained between the two quotes, here none). Incidentally, since alias expansion occurs early, you can do some peculiar things with it: % [ Missing ]. % alias [ echo foo % [ foo (alias expansion occurs before globbing) % unalias [ unalias: Missing ]. (unalias globs its arguments!) % unalias \[ % alias unalias echo foo unalias: Too dangerous to alias that. (the C shell attempts caution...) % alias \unalias echo foo % alias unalias (echo foo) % unalias unalias foo unalias (but fails!) % ''unalias unalias % alias % (Fortunately, there is an exit.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris