出于学习目的,我想在每次运行它们时自动打印出我使用的别名。我希望它能帮助我了解命令中涉及的一些有用标志的作用,并让我对涉及管道的别名中的部分保持新鲜。
我知道每次我想记住时我都可以运行
type alias-name
,但我希望这会自动发生。
到目前为止,我有这个脚本,来自 ~/.bashrc
declare -a ALIASES
while read -r; do
ALIASES+=("$REPLY")
done < <(alias)
for i in "${ALIASES[@]}"
do
ALIAS_AND_NAME=$(awk -F '=' '{print $1}' <<< "$i") # puts the keyword alias and the alias itself into the variable
NAME_ONLY=$(awk '{print $2}' <<< "$ALIAS_AND_NAME") # removes the keyword alias
COMMAND_AFTER_EQUALS=$(sed -e 's/^[^=]*=//g' <<< "$i")
# regex: matches up until the '=', then also matches '=', and replaces the match with nothing (removes the alias piece)
ALIAS_COMMAND=$(sed -e "s/^'//" -e "s/'$//" <<< "$COMMAND_AFTER_EQUALS")
# remove single quotes
# now remake the alias, first echoing what the alias is, then running the command
alias $NAME_ONLY="echo ~~~alias $NAME_ONLY=\'$ALIAS_COMMAND\'~~~ 1>&2; $ALIAS_COMMAND"
done
据我所知,每当单独使用别名时,这就像我想要的那样。我现在遇到的问题是当别名命令像
alias grep='grep --color=auto'
用于管道。我相信现在输入将从之前的管道命令进入新别名中的 echo 语句。有没有办法避免这种情况?
你不能单独使用别名来完成你想要做的事情——但是如果你将该别名与一个函数配对,它就可以实现:
write_alias_warning_and_execute() {
local orig_alias_name orig_alias_str orig_alias_q args_q
orig_alias_name=$1; shift
orig_alias_str=$1; shift
printf -v args_q '%q ' "$@"
printf -v orig_alias_q '%q' "$orig_alias_str"
echo "alias $orig_alias_name=$orig_alias_q" >&2
eval "command $orig_alias_str $args_q"
}
for alias_name in "${!BASH_ALIASES[@]}"; do
alias_content=${BASH_ALIASES[$alias_name]}
if [[ $alias_content = *write_alias_warning_and_execute* ]]; then
echo "alias $alias_name is already wrapped; skipping" >&2
fi
printf -v new_alias 'write_alias_warning_and_execute %q %q' "$alias_name" "$alias_content"
BASH_ALIASES[$alias_name]=$new_alias
done