2019-01-10 04:00:37 +0700, Robert Elz:
[...]
> Nor can we tell the shells not to expand words that would be
> keywords when used elsewhere as currently users have the
> ability to do that, and we cannot break existing conforming
> applications.
[...]

It seems there's been a misunderstanding. I'm not proposing to
break shell implementations. My proposed change would on the
contrary  give more freedom to implementations while giving
slightly less freedom to applications (in areas where nobody
cares anyway) and also align with existing implementations
(including zsh, bash when not in POSIX mode, and AT&T ksh).

I've just realised I had already made that point in 2016 at
http://austingroupbugs.net/view.php?id=953#c3195

To rephrase it:

Currently and with the currently proposed change, the spec more
or less tells us, the application writers:

> You can pick whatever name you want for your alias provided
> it's a [a-zA-Z0-9_!%@,]* name (and unspecified if not)
> 
> If you pick a name that happens to be the name of any of the
> shell reserved words (if, do, in, !, while...), that alias
> will be expanded except in the situations where that name is
> recognised as a reserved word.

What I'm saying is that it would be more useful to make it:

> You can pick whatever name you want for your alias provided
> it's a [a-zA-Z0-9_!%@,]+ name and is not the name of a shell
> reserved word (and unspecified if not)

(also note the change from * to + above)

And leave off the part about expansion or not of aliases for
reserved words since one can't use a reserved word as an alias.

That allows shells to do the more sensible thing of allowing
aliasing reserved words like bash or zsh do (when not in sh
mode) or ksh (for "select" only, not a concern here as portable
applications can't use "select", aliases or not, except quoted)

The only applications that that proposed change would break
would be the hypothetical ones that would do things like:

alias for=pour
alias do=faire
alias to_french='echo '

for word in for do; do
  eval "to_french $word"
done

(which already doesn't work in bash except in posix mode nor in
zsh in posix mode or not).

I'm not aware that anybody uses aliases that way. The trailing
blank thing is more about "alias env='env '" when you want your
aliases (but here aliases to commands not to random French
words) to be expanded after "env".

In any case, by no longer allowing pipelines, redirections,
multiple commands, keywords, comments in alias values, empty or
blank aliases, that proposed change breaks many applications,
especially scripts. The ones that are least likely to be broken
are the interactive usage ones like "alias ll='ls -l'" or "alias
sudo='sudo '", but no one cares about POSIX compliance
interactively.

For instance, among my posts on unix.stackexchange.com, at a
quick glance, these would have alias usages that would become
non-conformant:

https://unix.stackexchange.com/a/63868
https://unix.stackexchange.com/a/65113
https://unix.stackexchange.com/a/86785
https://unix.stackexchange.com/a/146147
https://unix.stackexchange.com/a/174681
https://unix.stackexchange.com/a/253505
https://unix.stackexchange.com/a/323132
https://unix.stackexchange.com/a/367112
https://unix.stackexchange.com/a/372484
https://unix.stackexchange.com/a/375157
https://unix.stackexchange.com/a/388257
https://unix.stackexchange.com/a/388697
https://unix.stackexchange.com/a/390285
https://unix.stackexchange.com/a/462760
https://unix.stackexchange.com/a/469773
https://unix.stackexchange.com/a/485501

And most usages of "alias" by modernish
(https://github.com/modernish/modernish):

~/git/modernish$ grep -Pr '^\s*alias\s' .
./bin/modernish:                alias readonly='typeset -rg' ;;
./bin/modernish:alias test=test 2>|/dev/null || _Msh_have FTL_NOALIAS 'No 
support for aliases at all.'
./bin/modernish:        alias _Msh_testFn=:
./bin/modernish:        alias local=typeset
./bin/modernish:alias not='! '          # note: final space = continue to 
expand aliases
./bin/modernish:alias so='{ let "$?==0"; }'     # we'll add 'let' to shells 
without it
./bin/modernish:alias forever='while :;'
./bin/modernish:                alias die='_Msh_doExit 128'
./bin/modernish:alias exit=_Msh_doExit
./bin/modernish:                alias export=_Msh_issetExHandleExport
./bin/modernish:alias shellquoteparams='{ '\
./bin/modernish:        alias source='_Msh_doSource "$#" "$@"'
./bin/modernish:                alias let='let --'
./bin/modernish:        alias readonly='typeset -r"$([[ -o posixbuiltins ]] && 
builtin echo g)"'
./libexec/modernish/var/local.mm:alias LOCAL="{ ${_Msh_sL_ksh93}unset -v 
_Msh_sL; { _Msh_sL_LOCAL ${_Msh_sL_LINENO}"
./libexec/modernish/var/local.mm:alias BEGIN="}; isset _Msh_sL && 
_Msh_sL_temp() { eval \"\${_Msh_PPs+unset -v _Msh_PPs; set -- \${_Msh_PPs}}\"; "
./libexec/modernish/var/local.mm:alias END="} || die 'LOCAL: init lost'; 
_Msh_sL_temp \"\$@\"; _Msh_sL_END \"\$?\" ${_Msh_sL_LINENO}; }"
./libexec/modernish/var/loop.mm:alias LOOP='{ { { _Msh_loop'
./libexec/modernish/var/loop.mm:alias DO='}; _Msh_loop_c && '\
./libexec/modernish/var/loop.mm:        alias DONE='} 8<&-; done; } 8</dev/null 
8<&-; _Msh_loop_setE; }'
./libexec/modernish/var/loop.mm:        alias DONE='} 8<&-; done; } 8<&-; 
_Msh_loop_setE; }'
./libexec/modernish/var/stack/trap.mm:alias trap='_Msh_POSIXtrap'
./libexec/modernish/var/stack/trap.mm:                  alias 
trap='_Msh_printSysTrap'
./libexec/modernish/var/stack/trap.mm:                  alias 
trap='_Msh_POSIXtrap'
./libexec/modernish/var/stack/trap.mm:                  alias 
trap='_Msh_printSysTrap'
./libexec/modernish/var/stack/trap.mm:                  alias 
trap='_Msh_POSIXtrap'
./libexec/modernish/cap/BUG_LNNOALIAS.t:alias 
_Msh_BUG_LNNOALIAS_testAlias='_Msh_test=$LINENO'
./libexec/modernish/tests/run.sh:alias TEST='{ testFn() {'
./libexec/modernish/tests/run.sh:alias ENDT='}; doTest; }'
./libexec/modernish/tests/util.t:       alias 
_util_test8="${CCn}x=\$LINENO${CCn}y=\$LINENO${CCn}z=\$LINENO${CCn}"

It even breaks ksh93's builtin alias for "times":

$ ksh -c 'alias times'
times='{ { time;} 2>&1;}'


In comparison, my proposed change is a lot less likely to break
an application.

Ironically, ksh93 has a builtin alias for "command" as well:

$ ksh -c 'alias command'
command='command '

When you do "command times" (which you may want to do as "times"
is meant to be a "special builtin" per POSIX):

$ ksh -c 'command times'
ksh: syntax error at line 1: `{' unexpected

-- 
Stephane

Reply via email to