Вопрос или проблема
Я хочу получить раскрытие псевдонима.
Например, если у меня есть:
alias g=hub
alias cdh="cd $HOME"
Я хочу, чтобы было:
expand_alias g
== hub
expand_alias cdh
== cd $HOME
Интересно, что в двух оболочках вывод различается:
bash:
$ alias g cdh
alias g='git'
alias cdh="cd $HOME"
zsh:
% alias g cdh
g=hub
cdh="cd $HOME"
Обратите внимание, что нет префикса alias
и нет кавычек вокруг hub
.
В zsh
вы можете просто использовать
get_alias() {
printf '%s\n' $aliases[$1]
}
С bash
(при условии, что он не находится в режиме POSIX, в этом случае его alias
даст вывод, аналогичный zsh
), вы можете сделать:
get_alias() (
eval '
alias() { printf "%s\n" "${1#*=}"; }'"
$(alias -- "$1")"
)
В основном, мы оцениваем вывод alias
после того, как переопределяем alias
как функцию, которая выводит то, что находится справа от первого =
в ее первом аргументе.
Вы можете использовать схожий подход для чего-то, совместимого с большинством оболочек POSIX, zsh
и bash
:
get_alias() {
eval "set -- $(alias -- "$1")"
[ "$#" -gt 0 ] || return
eval 'printf "%s\n" "${'"$#"'#*=}"'
}
Исходя из ответа Стефана Шазеля, я придумал:
function alias_expand {
if [[ $ZSH_VERSION ]]; then
# shellcheck disable=2154 # псевдонимы ССылки, но не присвоены
[ ${aliases[$1]+x} ] && printf '%s\n' "${aliases[$1]}" && return
else # bash
[ "${BASH_ALIASES[$1]+x}" ] && printf '%s\n' "${BASH_ALIASES[$1]}" && return
fi
false # Ошибка: псевдоним не определен
}
(с bash 4.0 или новее).
А как насчет определения функции оболочки:
EXA() { alias $@ | sed 's/^/expand_/; s/=/ == /; s/\o047//g; '; }
В моей zsh это было связано с комбинацией клавиш:
_expand_alias () {
local word expl tmp pre sel what
local -a tmpa suf
eval "$_comp_setup"
if [[ -n $funcstack[2] ]]
then
if [[ "$funcstack[2]" = _prefix ]]
then
word="$IPREFIX$PREFIX$SUFFIX"
else
word="$IPREFIX$PREFIX$SUFFIX$ISUFFIX"
fi
pre=()
else
local curcontext="$curcontext"
if [[ -z "$curcontext" ]]
then
curcontext="expand-alias-word:::"
else
curcontext="expand-alias-word:${curcontext#*:}"
fi
word="$IPREFIX$PREFIX$SUFFIX$ISUFFIX"
pre=(_main_complete - aliases)
fi
zstyle -s ":completion:${curcontext}:" regular tmp || tmp=yes
case $tmp in
(always) sel=r ;;
(yes | 1 | true | on) [[ CURRENT -eq 1 ]] && sel=r ;;
esac
zstyle -T ":completion:${curcontext}:" global && sel="g$sel"
zstyle -t ":completion:${curcontext}:" disabled && sel="${sel}${(U)sel}"
tmp=
[[ $sel = *r* ]] && tmp=$aliases[$word]
[[ -z $tmp && $sel = *g* ]] && tmp=$galiases[$word]
[[ -z $tmp && $sel = *R* ]] && tmp=$dis_aliases[$word]
[[ -z $tmp && $sel = *G* ]] && tmp=$dis_galiases[$word]
if [[ -n $tmp ]]
then
tmp=${tmp%%[[:blank:]]##}
if [[ $tmp[1] = [[:alnum:]_] ]]
then
tmpa=(${(z)tmp})
if [[ $tmpa[1] = $word && $tmp = $aliases[$word] ]]
then
tmp="\\$tmp"
fi
fi
zstyle -T ":completion:${curcontext}:" add-space || suf=(-S '')
$pre _wanted aliases expl alias compadd -UQ "$suf[@]" -- ${tmp%%[[:blank:]]##}
elif (( $#pre )) && zstyle -t ":completion:${curcontext}:" complete
then
$pre _aliases -s "$sel" -S ''
else
return 1
fi
}
В моей среде zsh, когда я печатаю alias
без команды, я получаю на stdout
список всех псевдонимов. То же самое происходит в bash (на MacOS оба). Они представлены в форме alias=expansion
Итак, вы можете отфильтровать ещё больше с помощью sed: alias | sed -ne 's/cdh=\(.*\)$/\1/p'
, если “cdh” это псевдоним, который вы хотите узнать. Вы можете создать функцию оболочки в вашем профиле для этого, если это обычная задача для вас: например,
expand_alias() { alias $@ | sed -ne 's/^'$@'=\(.*\)$/\1/p' }
Если псевдоним заканчивается пробелом, следующий псевдоним также будет раскрыт, таким образом очень простая альтернатива:
$ alias expand_alias="echo "
$ expand_alias expand_alias
echo
Тестировано на GNU bash 5.1.16 и zsh 5.5.1.
Из справочного руководства по Bash:
Если последний символ значения псевдонима является
пробелом
, следующая команда, следующая за псевдонимом, также проверяется на раскрытие псевдонима.
Ответ или решение
Чтобы получить расширение псевдонима (алиаса) в оболочках Bash и Zsh, можно воспользоваться различными подходами, так как оба интерпретатора имеют свои особенности.
В Bash:
Вы можете определить функцию, которая будет извлекать значение алиаса, используя массивы встроенных переменных BASH_ALIASES
. Например:
function get_alias() {
# Проверяем, есть ли алиас
if [ "${BASH_ALIASES[$1]+x}" ]; then
printf '%s\n' "${BASH_ALIASES[$1]}"
return
fi
false # Алиас не определен
}
Использование этой функции будет следующим:
$ alias g=hub
$ get_alias g
hub
Этот способ работает для версий Bash 4.0 и новее. Если вы находитесь в строгом режиме POSIX, попробуйте переопределить команду alias
:
get_alias() (
eval '
alias() { printf "%s\n" "${1#*=}"; }'
$(alias -- "$1")
)
В Zsh:
В Zsh это делается проще благодаря тому, что исследовать алиасы можно через ассоциативные массивы:
function get_alias() {
# Проверяем, есть ли алиас
if [ ${aliases[$1]+x} ]; then
printf '%s\n' "${aliases[$1]}"
return
fi
false # Алиас не определен
}
Применение этой функции:
% alias g=hub
% get_alias g
hub
Общий подход для обеих оболочек:
Если вы хотите создать функцию, которая будет работать как для Bash, так и для Zsh, можно объединить оба подхода. Вот пример такой функции:
function expand_alias() {
if [[ $ZSH_VERSION ]]; then
# Обрабатываем Zsh
[ ${aliases[$1]+x} ] && printf '%s\n' "${aliases[$1]}" && return
else
# Обрабатываем Bash
[ "${BASH_ALIASES[$1]+x}" ] && printf '%s\n' "${BASH_ALIASES[$1]}" && return
fi
false # Алиас не определен
}
Теперь вы можете вызывать expand_alias
с именем псевдонима для получения его значения.
Заключение
Эти методы позволяют получить расширение алиасов как в Bash, так и в Zsh. Выбор способа зависит от ваших предпочтений и среды, в которой вы работаете. Оба подхода достаточно просты в реализации и использовании, что делает их полезным дополнением к любой оболочке для работы с командной строкой.