- 書式
- function NAME [OPTIONS]; BODY; end
概要
function
コマンドは関数名 NAME
で
本体 BODY
の関数を定義します。
関数とは
関数名がコマンドとして与えられたときに
実行されるコマンドのリストです。
オプション
以下のオプションが用意されています。
-a NAMES
/--argument-names NAMES
- コマンドライン引数を変数
NAMES
に割り当てる。 -d DESCRIPTION
/--description=DESCRIPTION
- 関数の動作についての説明文。
補完時の説明文に適している。 -w WRAPPED_COMMAND
/--wraps=WRAPPED_COMMAND
WRAPPED_COMMAND
から補完設定を継承する。
詳しくは complete コマンドを参照。-e EVENT_NAME
/--on-event EVENT_NAME
-
イベント
EVENT_NAME
が
発生したときに関数を実行する。
fishは内部的にイベントを発生させている、
たとえばプロンプト表示時などに。
-v VARIABLE_NAME
/--on-variable VARIABLE_NAME
- 変数
VARIABLE_NAME
の値が
変更されたときに関数を実行する。 -j PGID
/--on-job-exit PGID
-
グループID
PGID
のジョブが
終了したときに関数を実行する。
PGID
の代わりに
文字列caller
を設定できる。
caller
指定は コマンド置換 内のみで有効で、
そのコマンド置換を作成したジョブが
終了したときに発動するハンドラとなる。
-p PID
/--on-process-exit PID
- プロセスID
PID
のfishの子プロセスが
終了したときに関数を実行する。 -s SIGSPEC
/--on-signal SIGSPEC
-
シグナル
SIGSPEC
を受け取ったときに
関数を実行する。
SIGSPEC
はシグナル番号か
シグナル名(SIGHUP
とかHUP
)。
-S
/--no-scope-shadowing
-
呼び出し元の関数の変数に
アクセスできるようにする。
通常では、関数内においては
呼び出し元と同名の全変数は隠蔽される、
つまり、関数内の変数の値は
呼び出し元の関数とは無関係である。
関数における変数スコープ 参照。
-V NAME
/--inherit-variable NAME
- 関数実行時に、
変数NAME
の値を複写し、
同名同値のローカル変数を定義する。
関数に追加の引数を与えられたとき、
環境変数配列 $argv
に設定されます。
--argument-names
オプションが設定されたとき、
引数はオプションに指定された変数 にも 設定されます。
イベントハンドラ
イベントハンドラのオプションの
ひとつが関数に与えられたとき、
関数は特定のイベントが発生したときに
自動で実行されます。
-e
/--on-event
-v
/--on-variable
-j
/--on-job-exit
-p
/--on-process-exit
-s
/--on-signal
ユーザは新しいイベントを
emit コマンドをで生成できます。
fishは以下のイベントを生成します。
fish_prompt
- fishのプロンプトが表示される直前に発生する。
fish_command_not_found
- コマンド検索に失敗したときに発生する。
fish_preexec
-
コマンドラインから
コマンドを実行する直前に発生する。
呼び出された関数の最初の引数に
コマンドラインが渡される。
fish_postexec
-
コマンドラインから
コマンドを実行した直後に発生する。
呼び出された関数の最初の引数に
コマンドラインが渡される。
注意:
fish_preexec
と fish_postexec
は
コマンドラインが不正であっても発生します。
コマンドラインパラメータには
コマンドラインの内容そのまま渡されます。
改行文字が含まれている可能性もあります。
実行例
以下は ll
関数を定義します。
ls
コマンドを-l
オプションを付けて実行ls
に渡るファイルやスイッチも渡せる
function ll ls -l $argv end
以下は mkdir
関数を定義します。
- command コマンドにより、
外部コマンドのmkdir
を実行する - 成功すれば
作成したディレクトリ(訳注:最後の引数)に
カレントディレクトリを変更する - 訳注:最後の引数がオプションの場合は
他には何もしない。
function mkdir -d 'Create a directory and set CWD' command mkdir $argv if test $status = 0 switch $argv[(count $argv)] case '-*' case '*' cd $argv[(count $argv)] return end end end
以下は notify
関数を定義します。
- 最近のジョブが完了したときにビープ音を鳴らす。
- 以後訳注: jobs -l -g で最近のジョブのグループIDを取得
$job
はローカル変数- ジョブがないときは 終了ステータス 1(異常終了)
- 関数内関数
_notify_job_$job
を定義
$job
の値を関数名に埋め込んでいる--on-job-exit
でジョブが終了したときに
実行できるイベントハンドラ--inherit-variable job
で$job
を
関数内関数でも参照できるようにしている- functions -e で関数自身を削除(自殺)
function notify set -l job (jobs -l -g) or begin; echo 'There are no jobs' >&2; return 1; end function _notify_job_$job --on-job-exit $job --inherit-variable job echo -n \a # beep functions -e _notify_job_$job end end
変数のスコープを表した実例
まず基本的なこととして、
関数内においては、
外側の同名のローカル変数は隠蔽されます。
次に -S
と -V
の違いを示します。
前者がいわばダイナミックスコープで、
外側の変数が見えている状態です。
後者は関数定義時の値がコピーされるだけです。
あくまでローカル変数ですので、
外側の変数には影響しません。
function f1 echo "in f1:$a" # "" set -l a 1 function f2 -S # ダイナミックスコープになる echo "in f2:$a" set a 10 # 外側のaが変更される end function f3 --inherit-variable a # 定義時の値1がコピーされる echo "in f3:$a" set a 100 # 外側には影響しない end echo "before f2:$a" # 1 f2 # 1 echo "after f2:$a" # 10 f3 # 1 echo "after f3:$a" # 10 end set -l a 0 echo "outside: $a" # 0 # ローカル変数は関数内では隠蔽される f1 echo "outside: $a" # 0
実行結果はこうなります。
outside: 0 in f1: before f2:1 in f2:1 after f2:10 in f3:1 after f3:10 outside: 0
最後までお読みいただき、ありがとうございました。参考になれば嬉しいです。