[PATCH 0 of 1] Shell alias arguments (again)

Martin Geisler mg at lazybytes.net
Wed Aug 18 02:13:34 CDT 2010


Steve Losh <steve at stevelosh.com> writes:

> This patch is my latest stab at adding more flexible support for arguments in
> shell aliases.
>
> First: an HG_ARGS environment variable will be set in the environment
> that the aliases run in. This variable contains the name of the alias
> plus the arguments, all separated by spaces. This matches the behavior
> of hooks.
>
> I'm not so sure about the next changes. The goal is to provide an easy
> way to use the arguments given to a shell alias in a flexible way.
>
> This patch replaces occurrences of "$@" (without quotes) in an alias
> with a space-separated string of the arguments given. It also replaces
> $1, $2, etc with the appropriate argument, "$0" with the name of the
> alias, and any extra $\d+ occurrences with an empty string.
>
> These replacements happen at the *Python* level, *before* the shell
> sees anything. This leads to some unexpected behavior:
>
>     [alias]
>     echo = !echo '$@'
>
>     $ echo '$@'
>     $@
>     $ hg echo foo
>     foo
>
> Unfortunately I don't see an easy way around this.
>
> We can't set an environment variable of "$@" (or $1, etc) directly. Bash (and
> Zsh, and probably other shells) ignores the environment variable because it's
> reserved.

I don't think anybody replied to my mail where I suggested that we feed
the arguments to the shell and let that do the interpolation:

Could we instead let the shell do the substitution using its normal
rules for handling quotes?

I mean, regardless of how the users quoted our command line arguments,
we know how many arguments we got and we can quote them again. So if we
execute

  ['sh', '-c', ALIAS, 'ignored'] + cmdargs

then I think it could work. That is, this little test works:

  sh -c 'ls "$@"' ignored 'a " b' 'c d'

where "works" means that I get

  ls: cannot access a " b: No such file or directory
  ls: cannot access c d: No such file or directory

as output, indicating that the $@ has been expanded correctly into two
arguments for ls. Without the double quotes around $@, ls sees five
arguments:

  % sh -c 'ls $@' ignored 'a " b' 'c d'
  ls: cannot access a: No such file or directory
  ls: cannot access ": No such file or directory
  ls: cannot access b: No such file or directory
  ls: cannot access c: No such file or directory
  ls: cannot access d: No such file or directory

-- 
Martin Geisler

Mercurial links: http://mercurial.ch/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20100818/a0dcd12a/attachment.pgp>


More information about the Mercurial-devel mailing list