web-dev-qa-db-ja.com

エイリアスと関数

Bashマニュアルから

エイリアスの定義と使用に関するルールはやや混乱します。 bashは常に、その行でコマンドを実行する前に、少なくとも1行の完全な入力を読み取ります。エイリアスは、コマンドが実行されるときではなく、読み取られるときに展開されます。したがって、別のコマンドと同じ行にあるエイリアス定義は、次の入力行が読み込まれるまで有効になりません。その行のエイリアス定義に続くコマンドは、新しいエイリアスの影響を受けません。この動作は、関数が実行されるときの問題でもあります。 関数の実行時ではなく、関数の定義が読み込まれるときにエイリアスが展開されます関数定義自体が複合コマンドであるため。結果として、関数で定義されたエイリアスは、その関数が実行されるまで使用できませんです。安全のために、エイリアスの定義は常に別の行に記述し、複合コマンドではエイリアスを使用しないでください。

「関数が実行されるときではなく、関数定義が読み込まれるとき、エイリアスは拡張されます」と「関数で定義されたエイリアスは、その関数が実行されるまで使用できません」という2つの文は互いに矛盾しているようです。

それぞれの意味を説明できますか?

17
Tim
  1. エイリアスは、関数が実行されるときではなく、関数定義が読み込まれるときに展開されます…

    $ echo「素早く茶色のキツネが怠惰な犬を飛び越えます。」 > myfile 
     
     $ alias myalias = cat 
     
     $ myfunc(){
    > myalias myfile 
    >} 
     
     $ myfunc 
    素早い茶色の狐が怠惰な犬を飛び越えます。
     
     $ alias myalias = "ls -l" 
     
     $ myalias myfile 
    -rw-r--r-- 1 myusername mygroup 45 Dec 13 07:07 myfile 
     
     $ myfunc 
    クイックブラウンキツネは怠惰な犬を飛び越えます。

    myfuncmyaliasを呼び出すように定義されていて、myaliasを再定義しましたが、myfuncmyaliasの元の定義を実行します。関数が定義されたとき、エイリアスはexpandedだったからです。実際、シェルはmyfuncmyaliasを呼び出すことを覚えていません。 myfunccatを呼び出すことだけを知っています:

    $ type myfunc 
     myfunc is a function 
     myfunc()
     {
     cat myfile 
    }
  2. …関数で定義されたエイリアスは、その関数が実行されるまで使用できません。

    $ echo「素早く茶色のキツネが怠惰な犬を飛び越えます。」 > myfile 
     
     $ myfunc(){
    > alias myalias = cat 
    >} 
     
     $ myalias myfile [.____ 。

    myaliasエイリアスは、myfunc関数が実行されるまで使用できません。 (エイリアスを定義する関数を定義するだけでエイリアスを定義できるとしたら、それはかなり奇妙だと思います。)

以下のスニペットを.bashrcで試してみると、最初の文で示されている答えが必要です

alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
    local CMD=${1:-ls} DIR=${2:-.};
    $CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; }     # list all file, no directories

unalias -a; source ~/.bashrcの後、lflsfを実行しようとしますが、

$ lf
-bash: ll: command not found

$ lsf
./file1 ./file2 ./script.sh ...     # no color, no control-chars

$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...

エイリアスは関数の実行時にではなく、関数の定義時に展開されるようです

  • lfを実行すると、エラー-bash: ll: command not found
  • lsfを実行すると、/usr/bin/lsが使用されます。エイリアスフォームは使用されず、色が強調表示されず、実行可能ファイルの後に制御文字がありません。
1
qeatzy