1

プログラムで、シェルエイリアスがbashでどのコマンドに解決するかを決定する必要があります。つまり、エイリアスを参照する可能性のある名前を取り、最終的に参照する「実際の」コマンドを返すbash関数を作成する必要があります。該当する場合は、エイリアスのチェーンを繰り返します。

たとえば、次のエイリアスがあるとします。

alias dir='list -l'
alias list='ls'

私の関数はdereference_alias

dereference_alias list    # returns "ls"
dereference_alias dir     # also returns "ls"

私が知らないビルトインがこれをきちんと行うものはありますか、それとも私は自分自身を辞任して出力をスクレイピングしますaliasか?

4

2 に答える 2

3

これが私が書いたバージョンで、外部コマンドに依存せず、無限ループを作成せずに再帰エイリアスを処理します。

# Arguments:
#
#   $1  Command to compact using aliases
#
function command-to-alias()
{
    local alias_key
    local expansion
    local guess

    local command="$1"
    local search_again="x"
    local shortest_guess="$command"

    while [[ "${search_again:-}" ]]; do
        unset search_again
        for alias_key in "${!BASH_ALIASES[@]}"; do
            expansion="${BASH_ALIASES[$alias_key]}"
            guess="${command/#"$expansion"/$alias_key}"
            test "${#guess}" -lt "${#shortest_guess}" || continue
            shortest_guess="$guess"
            search_again="x"
        done
        command="$shortest_guess"
    done

    echo "$command"
}
于 2016-11-17T03:57:35.023 に答える
1

これが私がそれをしている方法ですが、それが最善の方法かどうかはわかりません:

dereference_alias () {
  # recursively expand alias, dropping arguments
  # output == input if no alias matches
  local p
  local a="$1"
  if [[ "alias" -eq $(type -t $a) ]] && p=$(alias "$a" 2>&-); then
    dereference_alias $(sed -re "s/alias "$a"='(\S+).*'$/\1/" <<< "$p")
  else
    echo $a
  fi
}

ここでの主な欠点は、私が依存していることですsed。エイリアスに引数をドロップする手段は最初のスペースで停止します。何らかの理由で名前にスペースが含まれているプログラムをエイリアスがポイントしないことを期待しています(つまりalias badprogram='A\ Very\ Bad\ Program --some-argument') 、これは十分に合理的な仮定ですが、それでもです。少なくとも全体をsedbash独自のコマンドラインの解析/分割/トークン化を利用したものに置き換えることができると思いますが、どこから始めればよいのかわかりません。

于 2013-01-06T09:40:03.790 に答える