In addition to the basic 10 chars that a working alias can not accept in zsh: "&');<>`|
, setting the option posixaliases
adds 12 more
#$(*-?[\]^{~
That includes the dash -
, which is valid without posixaliases
.
Alias options
There are few options in zsh that affect aliases:
ALIASES ALIAS_FUNC_DEF POSIX_ALIASES
The aliases
option enables all or none, not the option to control only a-b
.
The aliasfuncdef
is more related to how function definitions are parsed.
posixaliases
So, the only one left to try is posixaliases
. The man description is:
When this option is set, reserved words are not candidates for alias expansion:
Doesn't seem to apply to this question.
POSIX defined aliases
However, knowing that the POSIX description of alias
is:
3.10 Alias Name
In the shell command language, a word consisting solely of underscores, digits, and alphabetics from the portable character set and any of the following characters: '!', '%', ',', '@'.
Implementations may allow other characters within alias names as an extension.
That is: for POSIX, the list of available characters is _0-9a-zA-Z!%,@
.
That description doesn't include the dash -
, even if it is allowed as an extension.
So, it may be possible that a posix_alias
is limiting alias
in some way.
In fact, it is.
alias allowed chars
In general, the list of valid characters for alias
is somewhat obscure and difficult to find. In practice, it seems to allow all Unicode chars:
% for c in ä å é ë þ ü ú í ó ö á ß ð f g h ï œ ø ¶ æ œ © ® b ñ µ ç;
> do d=a${c}b;
> alias $d="echo alias $d";
> done
% alias
a©b='echo alias a©b'
a®b='echo alias a®b'
aµb='echo alias aµb'
a¶b='echo alias a¶b'
aáb='echo alias aáb'
aßb='echo alias aßb'
aäb='echo alias aäb'
aåb='echo alias aåb'
aæb='echo alias aæb'
açb='echo alias açb'
aéb='echo alias aéb'
aëb='echo alias aëb'
aíb='echo alias aíb'
aïb='echo alias aïb'
aðb='echo alias aðb'
añb='echo alias añb'
aób='echo alias aób'
aöb='echo alias aöb'
aøb='echo alias aøb'
But zsh is more restrictive when using ASCII characters:
% for c in ! @ % +; do d=a${c}b; alias $d="echo alias $d"; done
But a!b
only works if quoted as a\!b
and some characters like # $ ^ *
can not be used easily (not used above).
In fact, the whole list of ASCII, {\ ..~}
could be tested to define an alias:
for c in {\ ..~}; do d="a${c}b"; alias $d="echo alias ${(q)d}";done
But only some aliases actually work:
for c in {\ ..~}; do d="a${c}b"; if e=$(eval $d) 2>/dev/null; then print $d $e; else print "failed char: $c"; fi; done
we get 10 failed chars: "&');<>`|
, some syntax chars can be defined as aliases but will not work (unquoted): <=>&;
, some chars are pattern chars [?
that get searched in the file system, and some aliases get incorrectly defined with this unquoted chars: \`$#
.
In POSIX aliases only "plain unquoted chars" may be valid and in zsh, setting the posixaliases
enforces that definition making 12 additional chars become directly failed chars
in the test above:
#$(*-?[\]^{~
Those characters could not be used in a working alias. That includes the -
, the source of your question.
Note from man zsh
:
When POSIX_ALIASES is set, only plain unquoted strings are eligible for aliasing. The alias builtin does not reject ineligible aliases, but they are not expanded.
type a-a
give you anything interesting?noaliases
option obviously). To verify it, you could always doset +o > myoptions
and source that file fromzsh -f
to see if you can reproduce it.unsetopt POSIX_ALIASES
?