3

A stock-standard zsh behaves as follows with an alias with a - in it, eg: a-a:

% zsh -f
svelte% alias a-a=date
svelte% a-a
Sun 19 Jul 2020 17:20:05 +07

My configuration has it behave as follows:

% alias a-a=date       
% alias | grep a-a
a-a=date
% a-a
zsh: command not found: a-a

Non-hyphen aliases work fine.

What option would be causing zsh to not find the alias named with a hyphen?

7
  • Perhaps you could narrow the field a bit by mentioning the things you've done to your stock configuration?
    – Jeff Schaller
    Jul 19 '20 at 11:56
  • @JeffSchaller Hundreds of lines of config and many years have passed since stock config.
    – Tom Hale
    Jul 19 '20 at 14:43
  • 1
    Does type a-a give you anything interesting? Jul 19 '20 at 16:12
  • 1
    Sounds unlikely options could be responsible for that (except for the noaliases option obviously). To verify it, you could always do set +o > myoptions and source that file from zsh -f to see if you can reproduce it. Jul 19 '20 at 18:35
  • 3
    Have you tried unsetopt POSIX_ALIASES ?
    – ImHere
    Jul 20 '20 at 1:18
4

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.

1

The trivial answer would be setopt aliases (as you didn't mention if no-hyphen aliases keep working).

The less trivial one - don't you have any math/calc 3rd party plugins loaded, that might treat such interactive line as "a minus a"?

Since you apparently got big and hairy configuration (who doesn't...), disable all the external code (like zsh-lovers tricks) first, as it's the most probable source of interference, not the zsh options itself.

1
  • Good idea... but in this case non-hyphen aliases work fine. I just updated the question.
    – Tom Hale
    Jul 19 '20 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.