TransWikia.com

Execute zsh alias when name contains a hyphen

Unix & Linux Asked on December 22, 2021

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?

2 Answers

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.

Answered by ImHere on December 22, 2021

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.

Answered by Tomasz Pala on December 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP