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