Определение псевдонима и немедленное его использование

11

В zshэтом все отлично работает:

alias foo=ls
foo

Но это не так:

alias foo=ls; foo

Нажатие ввода дополнительное время не является проблемой при работе в интерактивном режиме. Но когда пробег через sshэто внезапно становится проблемой:

% ssh zsh@server 'alias foo=ls; foo'
zsh:1: command not found: foo

Даже с новой строкой это не работает:

% ssh zsh@server 'alias foo=ls;
foo'
zsh:2: command not found: foo

Странная вещь в том, что zshзнает, что это псевдоним:

% ssh zsh@server 'alias foo=ls; alias'
foo=ls
run-help=man
which-command=whence

Как сказать, zshчто псевдонимы должны быть активными?

Оле Танге
источник
Это общая проблема с алиасами. Я попробовал, используя, bashи cshони вели себя так же. Я надеюсь, что кто-то может объяснить это.
Сликс
Bash не проблема: сервер ssh 'shopt -s expand_aliases; псевдоним jj = ls \ njj'
Ole Tange

Ответы:

9

Ты не можешь сделать это.

Поскольку псевдонимы были развернуты только после раскрытия истории, и вся строка была прочитана за один раз, поэтому, когда он fooбыл выполнен, процесс раскрытия псевдонимов завершился, оболочке уже слишком поздно распознавать новый псевдоним.

Лучший способ сделать это - определить псевдоним .zshrcили использовать функцию, например , ответ jimmij или использовать eval:

alias foo=ls; eval foo

Есть особый случай с zsh -c . В этом случае те псевдонимы, которые были определены в, .zshenvбудут расширены.

cuonglm
источник
Это не объясняет, почему ssh host 'alias foo=bar<newline>foo'не работает. Есть специальный случай дляzsh -c
Стефан Шазелас
Или используйтеalias foo=ls; eval foo
Стефан Шазелас
@ StéphaneChazelas: Спасибо за информацию, обновленную вместе с ними. О sshслучае, не могли бы вы сделать это более ясным. Я думаю, что команда все еще была прочитана за один раз.
Cuonglm
10

Это очень известная проблема, которая даже описана в zshруководстве под заголовком ALIASING (см. man zshmisc). Рекомендуемый способ борьбы с ним - использовать функцию вместо псевдонима:

foo() { ls; } ; foo

или даже лучше в случае ls:

foo() { ls -- "${@:-.}"; } ; foo

пс. точка с запятой в конце определения функции (список) и пробелы в zsh не нужны, но по привычке из других оболочек я их все равно ставлю.

jimmij
источник
1

Используя c-shell (точнее tcsh) из командной строки:

mymachine % alias showme "echo here it is"
mymachine % showme
here it is

или поместите его в файл .cshrc, затем отправьте файл:

mymachine % source ~/.cshrc

mymachine % showme
here it is

mymachine % ssh garnet showme
here it is
user3227618
источник