これはfish(Friendly Interactive SHell)のドキュメントです。
fishはユーザフレンドリーなコマンドラインシェルで、主に対話的な用途を意図しています。
シェルとは、他のプログラムを実行するために使われるプログラムです。
最新情報は fishホームページ を参照してください。

訳注:fishは以下の機能を提供しています。

  1. 他言語のように''の中に\'を含められる。
  2. エイリアスと統合された関数
  3. オートロード関数
  4. 制御構造も含めてすべてがコマンド
  5. すべてのビルトインにmanページが用意されている
  6. Webブラウザでヘルプが見られる
  7. 強力なオートサジェスチョン
  8. 多機能なタブ補完
  9. 補完設定が簡単に記述できる
  10. 設定ファイルは分割統治されて整っている
  11. シンプルで強力なコマンド置換
  12. 柔軟な配列変数
  13. 永続的な変数「ユニバーサル変数」
  14. 強力でカスタマイズ可能なハイライト機能
  15. リアルタイムシンタックスハイライト
  16. 必要最低限のビルトインコマンド
  17. コマンドラインはEmacs/Viモードが使える
  18. Emacs式のキルリング
  19. 強力な履歴検索
  20. 複数行に対応したコマンドラインエディタ
  21. GUIの仮想端末ウィンドウにタイトルを設定できる
  22. プロンプトを自在に設定できる
  23. 起動時にあいさつを表示できる
  24. 多くのイベントハンドラー
  25. 内蔵されたスクリプトデバッガ

文法の概略

fishのようなコマンドラインシェルを使うためには、まずコマンドを与えます。
すべてのfishのコマンドは、統一されたシンプルな文法に沿っています。

コマンドはコマンド名の後に引数を書いて実行されます。

例:

echo hello world

上記の例はecho コマンドを実行します。
echoは引数を画面に書き出すコマンドです。
上記の例では、 'hello world' と出力されます。
fishにおいては、すべてのことがコマンドで成されます。

以下のようなコマンドもあります。

  • 一連のコマンドを繰返し実行するコマンド
  • 変数を設定するコマンド
  • 一連のコマンドをひとつのコマンドとみなすコマンド

そして、すべてのコマンドは統一されたシンプルな文法に沿っています。

上記の例で使ったechoコマンドについての詳細を知るには、 man echo を実行してechoコマンドのmanページを読んでください。

manは与えられたトピックのmanページを表示するコマンドです。
manコマンドは表示するmanページの名前を引数に取ります。
ほとんどのコンピュータ上のほぼすべてのコマンドにmanページがあります。
他のこと…たとえばシステムライブラリや重要なファイルなど…についてのmanページもあります。

コンピュータ上のすべてのプログラムはfishでコマンドとして使えます。
プログラムファイルが環境変数PATHのどこかに置かれていれば、プログラム名を打ち込むだけで使えます。
そうでなければ、ディレクトリも含めたパス( /home/me/code/checkers/checkers や ../checkers のように) を使わなければなりません。

いくつかの便利なコマンドのリストを挙げます。

cd
カレントディレクトリを変更する
ls
ファイルやディレクトリをリストする
man
画面上にmanページを表示する
mv
ファイルを移動(リネーム)する
cp
ファイルをコピーする
open
ファイルタイプごとに関連付けられたデフォルトのアプリケーションで開く
less
ファイルの内容を表示する

コマンドとパラメータはスペース文字で区切られます。
すべてのコマンドは改行(つまりEnterキーを押すこと)またはセミコロンで終了します。
1つ以上のコマンドをセミコロンで区切って同じ行に書くこともできます。

スイッチは特殊な引数の形式として、とても一般的です。
スイッチは、ほぼ必ず1つ以上のハイフンで始まり、コマンドの挙動を変更します。(訳注:DOS/Windowsでは古くから / がスイッチとして使われていたため「ほぼ必ず」と表現されていると思われる)
たとえば、lsコマンドはスイッチ無しではカレントディレクトリ内すべてのファイルとディレクトリを表示しますが、
-l スイッチをつけると、lsはファイル名だけでなくサイズ、パーミッション、所有者、最終更新時刻をも表示するようになります。

スイッチはコマンドごとに異なり、各コマンドのmanページで説明されています。
ですが、いくつかのスイッチはほとんどのコマンドで共通しています。
たとえば --help はたいていヘルプテキストを表示します。
-iは実行前に対話的プロンプトを表示することが多く、-fはプロンプトを表示しません。

クオート

時々、パラメータ展開や文字エスケープなどの機能が働くことがあります。
これらが発生するとき、ユーザはクオート(シングルクォートかダブルクォート)でパラメータを囲むことができます。

シングルクォートとダブルクォートには1つの重要な違いがあります。
ダブルクォートが使われたときには、変数展開が行われます。
シングルクォートが使われたときには、({}展開パラメータ展開も含めて)展開は行われません。

クオートすればパラメータにスペースを含められます。

シングルクォート内では

  • エスケープシーケンスが無視される
  • 受け付けるバックスラッシュエスケープは2つだけ
    • シングルクォートをエスケープする \'
    • バックスラッシュをエスケープする \\

ダブルクォート内で受け付けるバックスラッシュエスケープは4つです。

  • ダブルクォートをエスケープする \"
  • $をエスケープする \$
  • 継続行を表す行末の \
  • バックスラッシュをエスケープする \\

ダブルクォート内のシングルクォートに特殊な意味はありません。
シングルクォート内のダブルクォートも同様です。

例:

rm "cumbersome filename.txt"

は 'cumbersome filename.txt' を削除しますが、

rm cumbersome filename.txt

は 'cumbersome' と 'filename.txt' の2つのファイルを削除します。

エスケープシーケンス

いくつかの文字はコマンドラインに直接書くことはできません。
これらのキャラクターにはエスケープシーケンスが用意されています。

特殊文字はこのように表記します。

  • \a → アラート
  • \b → バックスペース
  • \e → エスケープ文字
  • \f → フォームフィード
  • \n → 改行(LF)
  • \r → キャリッジリターン(CR)
  • \t → タブ
  • \v → 垂直タブ

以下はエスケープが必要なキャラクターです。

  • スペース → \ の後にスペース
  • $\$
  • \\\
  • *\*
  • ?\?
  • ~\~
  • %\%
  • #\#
  • (\(
  • )\)
  • {\{
  • }\}
  • [\[
  • ]\]
  • <\<
  • >\>
  • ^\^
  • &\&
  • ;\;
  • " → \"
  • ' → \'

他にも以下の記法が用意されています。

  • \xxx はASCII文字の16進数表記。たとえば \x9 はタブ文字となる。
  • \Xxx はデータのバイトの16進数表記。マルチバイトエンコーディングを使うとき、不正な文字列になることがあるので、しっかり理解した上で使うこと。
  • \ooo は8進数表記。たとえば \011 はタブ文字となる。
  • \uxxxx は16ビットUnicode文字の16進数表記。 たとえば \u9 はタブ文字となる。
  • \Uxxxxxxxx は32ビットUnicode文字の16進数表記。たとえば、 \U9 はタブ文字となる。
  • \cx はコントロール文字でxはアルファベット。たとえば \ci はCtrl+Iでタブ文字となる。

入出力リダイレクト

ほとんどのプログラムが3つの入出力ストリームを使います。
それぞれファイルディスクリプタ(FD)と呼ばれる番号で表現されます。

  • FD 0は標準入力。デフォルトではキーボードから入力を読み込む。
  • FD 1は標準出力。デフォルトでは画面に出力する。
  • FD 2は標準エラー出力。エラーや警告のために使われる。デフォルトでは画面に出力する。

2つの出力FDをもつ理由は、エラー・警告と通常のプログラムの出力を分けられるようにするためです。

どのFDも「リダイレクト」と呼ばれる単純な仕組みによって、デフォルトとは異なるように出力できます。

たとえば、ファイルへのリダイレクト echo hello > output.txt は、echoコマンドの出力を output.txt へ書き込みます。

  • 標準入力をファイルから読み込むには <SOURCE_FILE と書く。
  • 標準出力をファイルへ書き込むには >DESTINATION と書く。
  • 標準エラー出力をファイルへ書き込むには ^DESTINATION と書く。
  • 標準出力をファイルへ追記するには >>DESTINATION_FILE と書く。
  • 標準エラー出力をファイルへ追記するには ^^DESTINATION_FILE と書く。
  • 存在するファイルを上書きしないようにするには >?DESTINATION^?DESTINATION と書く。

DESTINATIONは以下のうちのどれかを指定できます。

  • ファイル名を指定したときは、出力はそのファイルに書き込まれます。
  • & の後に別のFDを指定したときは、出力はそのFDに向かいます
  • &- を指定したときは、FDは閉じられます。

例:
標準出力と標準エラー出力の両方を all_output.txt にリダイレクトするには、

echo Hello > all_output.txt ^&1

と書きます。

リダイレクトの先頭にFDを付けることで、任意のFDにリダイレクトできます。

  • FD Nの入力をリダイレクトするには N<DESTINATION と書きます。
  • FD Nの出力をリダイレクトするには N>DESTINATION と書きます。
  • FD Nの出力をファイルに追記するには N>>DESTINATION_FILE と書きます。

例:

echo Hello 2>output.stderr
echo Hello ^output.stderr

は等価です。

どちらも、標準エラー出力(FD 2)は output.stderr に書き込まれます。

パイプライン

ユーザは複数のコマンドをひとまとめにする、いわゆるパイプラインが可能です。
これは、1つのコマンドの標準出力を次のコマンドの標準入力に渡すことです。
パイプラインはコマンドを | で区切ります。

たとえば、

cat foo.txt | head

は、まずfoo.txtの内容を出力するcatプログラムを呼び出します。
foo.txtの内容はheadプログラムへフィルタされます。
headプログラムはfoo.txtの最初の10行を画面に出力します。
パイプラインによってどのようにコマンドを組み合わせるかについての詳細を知るにはmanコマンドを使ってコマンドのmanページを読んでください。
catプログラムについての詳細を知るには man cat を実行します。

パイプラインはよく最初のプロセスのFD1(標準出力)を次のプロセスのFD0(標準入力)に接続します。
出力FDと出力リダイレクトシンボルと | を記述することで別なFDをパイプラインできます。

たとえば、

make fish 2>| less
make fish ^| less

はfishプログラムをビルドし、エラーをlessページャで表示します。
(訳注:等価な例を追加。)

バックグラウンドジョブ

fishでジョブ(訳注:プログラム)を起動させると、fishそのものは停止し、端末の制御を起動したプログラムへと渡します。
たまにコマンドラインを使い続けたくて、ジョブをバックグラウンドで動作させたくなるときがあります。
バックグラウンドジョブを作成するには & をコマンドの後に付けます。
これはfishにジョブをバックグラウンドで動作させることを伝えます。
バックグラウンドジョブはGUIプログラムを動作させるときにとても便利です。

例えば

emacs &

は、バックグラウンドでEmacsテキストエディタ を起動します。

ジョブコントロール

ほとんどのプログラムはCtrl+Zで実行を一時停止してfishに制御を戻すことを許可しています。
一度fishのコマンドラインに戻れば、他のプログラムを実行させたり、やりたいことをなんでもできるようになります。
一時停止したコマンドに戻りたければ fg (フォアグラウンド) コマンドを実行します。

バックグラウンドで実行したければ bg コマンドを実行します。

現在動作中のジョブをリストするには jobs コマンドを実行します。

関数

関数とはfishの文法で記述されたプログラムです。
関数は1つ以上のコマンドと引数を1つの関数名を使って統合します。
関数名はまた、特定のプログラムに追加の引数をつけて実行する場合にも使われます。

たとえば、lsコマンドに -l 引数をつけて呼び出す関数定義llがあります。
lsの -l オプションはカレントディレクトリのファイルの詳細なリストを表示します。

function ll
    ls -l $argv
end

最初の行はllという名前の関数を定義することをfishに伝えます。
使うには、コマンドラインで単にllと打ち込むだけです。
2行目はllが実行されたときにコマンド ls -l $argv が呼ばれることをfishに伝えます。
$argv は関数に渡された全引数が含まれる配列変数で、関数内ではいつでもアクセスできます。
ll関数においては、シンプルにlsコマンドに渡されます。
関数についての詳細はfunctionビルトインの説明 を参照してください。

別名定義

関数の最も一般的な用途のひとつは、既存のコマンドのふるまいを少しだけ変更することです。
たとえば、lsコマンドを色付き表示するように再定義したい場合があります。
GNU lsで色付き表示させるスイッチは --color=auto です。
lsの別名またはラッパーは次のようになります。

function ls
    command ls --color=auto $argv
end

別名について、いくつか重要なことを述べる必要があります。

  • いつも $argv 変数を元のコマンドのパラメータリストに加えるよう注意してください。
    ユーザが追加の引数を関数に指定してきたときに、元のコマンドに渡るようになります。
  • 別名が元のコマンドと同じ名前であるならば、 command を前置して下さい。
    commandを前置することで、fishが関数そのものを呼び出さずに同名のコマンドを実行するようになります。
    これを怠ると、無限再帰のバグを引き起こしかねません。

この種の関数を簡単に定義できるようにするために aliasコマンド が用意されています。

オートロード関数

関数はコマンドラインか設定ファイル(訳注: ~/.config/fish/config.fish )で定義できます。
別な方法として関数をオートロードさせることもできます。
オートロード関数には、いくつかのメリットがあります。

  • 動作中のfishシェルすべてで自動的に有効になる
  • 関数定義が変更されたとき、動作しているすべてのシェルで変更されたバージョンで再読み込みされる
  • 起動時間やメモリ消費量を減らせる
  • などなど…

fishは配列変数 $fish_function_path で指定されたすべてのディレクトリを自動的に探索し、そこで定義された関数を必要に応じて読み込みます。
関数定義のファイル名は、「関数名+拡張子.fish」にしなければなりません。

デフォルトでは、fishは以下の順序で関数を探索し、最初に見付けたファイルを使います。

自作関数を置いているディレクトリ
たいてい ~/.config/fish/functions/ (環境変数 XDG_CONFIG_HOME で変更可能)
システム管理者がすべての人に使える関数を用意しているディレクトリ
たいてい /etc/fish/functions/
サードパーティーのソフトウェアベンダーが独自の関数を用意しているディレクトリ
たいてい /usr/share/fish/vendor_functions.d/
fishに最初からついてくる関数
たいてい /usr/share/fish/functions/

$fish_function_path はビルド、インストール、実行時、上記のディレクトリで設定されたパラメータによって制御できます。

これだけ広範囲を探索するのは、もしかしたら混乱するかもしれません。
とりあえず、標準関数以外はおそらく ~/.config/fish/functions/ にあるでしょう。

とても重要なことなのですが、関数定義のファイルは特定の関数定義のみ含まれていて、他は何も記述されないということです。
そうでなければ、関数ファイルをオートロードするときには、関数がすでにロード済みであることが必要となり、循環参照を引き起こしてしまいます。

オートロードはイベントハンドラー には使えません。
なぜなら関数がロードされていないときは、イベントが起きたときに、その関数が実行されるべきであるとfishは知ることができないからです。
詳細はイベントハンドラーの節を参照してください。

あなたがプログラムを開発中であるならば、システム上のすべてのfishユーザのために関数群を用意したくなるかもしれません。
関数群はvendor関数ディレクトリにインストールできます。
配置場所はシステムごとに異なることがあるのでpkgconfigフレームワークを使って発見すべきです。
pkg-config --variable functionsdir fish の出力でわかります。(訳注:こちらでは /usr/share/fish/vendor_functions.d)

条件分岐と制御フロー

fishには、特定の条件を満たしたときのみコマンド群を実行させるようにする4つのビルトインがあります。

switchコマンドは文字列値によって多くのブロックのうち1つを実行するために使われます。
詳細はswitchのドキュメントを参照してください。

その他の条件分岐はコマンドかブロックコマンドの終了ステータス によって実行するかどうかを決定します。
詳細はif、and、orのドキュメントを参照してください。

用語説明

fishで使われる用語について短い説明をします。

引数
コマンドに与えられるパラメータ。
ビルトイン
fish内で実装されているコマンド。ビルトインはシェルと密接にくっついているため、外部コマンドとして実装できない。
コマンド
シェルが実行可能なプログラム。
関数
あたかもひとつのコマンドであるかのように呼び出せるコマンド群。関数を使うことで複数の小さなコマンドを1つの強力なコマンドとして束ねることができる。
ジョブ
実行中のパイプライン・コマンド。
パイプライン
1つのコマンドの出力を次のコマンドの入力になるように接続された状態で同時に実行しているコマンド群。
リダイレクト
ジョブに関連づけられた入出力ストリームを変更する操作。
スイッチ
コマンドの挙動を変更するために引数として渡される特別なフラグ。スイッチはほぼすべて1つか2つのハイフンから始まる。

ヘルプ

fishは多くのヘルプシステムがあります。
help コマンドは特定の項目やコマンドに関するヘルプを表示します。
たとえば、 help syntax を実行するとこのドキュメントの文法の概略 が表示されます。

fishは内部コマンドのmanページもあります。
たとえば、 man set はsetコマンドをmanページとしてドキュメントを表示します。

特定のビルトインに対するヘルプは -h スイッチをつけても得ることができます。
たとえば、fgコマンドのヘルプを得るには fg -h または help hg を実行します。

オートサジェスチョン

fishはあなたがコマンドラインを入力するにつれて、コマンド履歴、補完、正しいファイル名からコマンドを提案(サジェスチョン)します。
コマンドを打ち込むと、カーソルの後にグレー色でサジェスチョンを表示します。
(fish_color_autosuggestion変数によって変更可)

オートサジェスチョンを受け入れる(コマンドラインの内容を置き換える)には、→またはCtrl+F(訳注:EmacsモードではCtrl+Eも可)を押します。
サジェスチョンの最初の単語を受け入れるには、Alt+→またはAlt+Fを押します。
オートサジェスチョンが望みのものでなければ、そのまま無視してください。
あなたが受け入れない限り実行されることはありません。

オートサジェスチョンは最初の数文字を入力するだけでよく入力するコマンドを素早く呼び出せますので強力な方法です。
ディレクトリ階層を渡るテクニックとしても効率的です。

タブ補完

タブ補完は現在のあらゆるシェルにおいて最も時間を節約できる機能のひとつです。
TABキーを押すことで、ユーザはfishに現在入力中のコマンドやパラメータの残りを推測させることができます。
もしfishが1つの候補しか見付けられなかった場合は、それをそのまま書き出します。
1つ以上の補完候補がある場合は、fishは共通する最長のプレフィクスを補完します。(訳注:fillとfilterならばfil)
最初の文字から補完候補が異なる場合は、全補完候補の一覧を表示します(訳注:補完ページャ)。
一覧表示は補完候補の説明が書かれてあり、一覧が長くて画面におさまらない場合は矢印キー・PageUp・PageDown・TAB・スペース(訳注:Emacs風のC-f/C-b/C-n/C-pでも可)で選択可能になります。
一度一覧選択に入ればその他のキーを押すと検索を始めます。
一覧選択に入らなければ、他のキーを押せば一覧表示をやめ、押されたキーがコマンドラインに入力されます。

以下はfishが提供しているタブ補完の一般的な用途です。

  • コマンド補完(ビルトイン、関数、一般的なプログラム)
  • シェル変数名
  • チルダ( ~ )からはユーザ名
  • ファイル名補完(ワイルドカード( ***? )文字列上にも対応)
  • プロセス展開 (ジョブID、ジョブ名、プロセス名)

fishはプログラム固有の補完をたくさん提供しています。
ほとんどの補完はlsに対する -l のようにシンプルなオプションですが、いくつかは高度です。
高度な補完候補たとえば、

  • man、whatis → インストールされた全manページ
  • make → カレントディレクトリのMakefileの全ターゲット
  • mount → /etc/fstabに指定された全マウントポイント
  • ssh → known_hostsに書かれている全ホスト(詳細はsshのドキュメント参照)
  • su → 全ユーザ
  • apt-get、rpm、yum → インストールされた全パッケージ

自分独自の補完を記述する

自分独自の補完を記述するのは難しくありません。
completeコマンドを使います。
completeは補完対象のコマンド名をパラメータにします。
たとえば、myprogプログラムの補完を加えるには、 complete -c myprog から始めます。

myprogに対する補完候補一覧を指定するには -a スイッチを使います。
myprogがstartとstopという引数を受け付けるならば、

complete -c myprog -a 'start stop'

と指定します。
-a スイッチに対する引数は1つの引数です。
補完時において、それはスペースとタブにより区切られ、変数展開、コマンド置換、その他パラメータ展開が行われます。

fishはコマンドによって受け付けられるスイッチを指定することをサポートする特殊な構文を用意しています。
-s-l-o スイッチはそれぞれ以下のスタイルのスイッチを指定します。

  • -s: 1文字スイッチ(short switch: -l など)
  • -l: GNUスタイルの長いスイッチ(long switch: --color など)
  • -o: 古い長いスイッチ(old-style long switch: -shuffle など)

myprogコマンドが -o (長くは --output )オプションを持ち、オプション引数にyesかnoを取るならば、以下のように記述します。

complete -c myprog -s o -l output -a "yes no"

completeコマンドのスイッチには、他にも引数を取るものがあります。

  • ファイル名補完を無効化する
  • 特定の組み合わせでのみ有効な補完を作成する
  • などなど

completeコマンドが受け付けるたくさんのスイッチについての完全な説明は以下の情報を参照してください。

独自の複雑な補完設定の記述例を知りたければ /usr/share/fish/completions 内の補完を研究してください。
(正確なパスはインストール時のプレフィクスなどで異なります。)

補完設定を記述する便利な関数

fishは特定のコマンド専用の補完設定を記述するのにとても便利な関数群を用意しています。
それらの関数名の多くは __fish_ から始まり、fish内部で使われます。
将来のバージョンのfishでは名前やインターフェースが変更されるかもしれません。
ここではそのうちいくつかの関数について述べます。
将来のバージョンでは削除されるか変更されるかもしれないことに注意してください。

__fish_print_ から始まる関数は、改行で区切られた文字列リストを出力します。
たとえば、 __fish_print_filesystems は認識されているすべてのファイルシステムを出力します。
__fish_complete_ から始まる関数は、説明文付きで補完候補を改行で区切られたリストとして出力します。
補完候補と説明文はタブ文字で区切られます。

__fish_complete_directories STRING DESCRIPTION
STRINGでパス補完。ディレクトリのみを受け付ける。説明文DESCRIPTIONを付けることもできる。
__fish_complete_path
STRINGでパス補完。説明文DESCRIPTIONを付けることもできる。
__fish_complete_groups
グループとグループの説明文を出力する。
__fish_complete_pids
PIDとコマンド名を出力する。
__fish_complete_suffix SUFFIX
SUFFIXで終わるファイル名を補完する。説明文も付けられる。
__fish_complete_users
ユーザ名とフルネームを出力する。
__fish_print_filesystems
全ファイルシステムを出力する。現時点では固定化されたリストになっている。使っているOSが実際にどのファイルシステムを受け付けるかには依存しない。
__fish_print_hostnames
全ホスト名を出力する。NFSサーバはfstabから、sshはknown_hostsから、そして/etc/hostsから探索される。
__fish_print_interfaces
全ネットワークインターフェースを出力する。
__fish_print_packages
インストールされたパッケージを出力する。現時点ではDebian、rpm、Gentooのパッケージのみ対応。

補完設定はどこに置くか

補完設定はコマンドライン上で定義することや設定ファイルに記述することもできます。
しかし、補完設定はオートロードすることもできます。
fishは $fish_complete_path 配列変数に含まれているディレクトリからも補完設定を走査し、補完設定は必要なときに自動でロードされます。
補完設定のファイル名は「補完するコマンド名.fish」で構成されている必要があります。

デフォルトでは、fishは以下を探索し、最初に見付けたファイルを採用します。

  • ユーザ用ディレクトリ ~/.config/fish/completions ( XDG_CONFIG_HOME 環境変数で可変)
  • システム管理者が全ユーザのために用意したディレクトリ /etc/fish/completions
  • サードパーティーソフトウェアベンダーがソフトウェアのために用意した補完設定ディレクトリ /usr/share/fish/vendor_completions.d
  • fishに標準でついてきている補完設定ディレクトリ /usr/share/fish/completions
  • OSのマニュアルにより自動生成された補完設定ディレクトリ ~/.local/share/fish/generated_completions

これらのパスはビルド・インストール・動作時のパラメータや上記のデフォルトにより異なります。

広範囲の探索は混乱を招くかもしれません。
どこに補完設定があるのかよくわからないならば、とりあえず ~/.config/fish/completions を見てみましょう。

一般的なUnixコマンドの新しい補完設定を書いたのならば、さらなる助けと開発 にある説明に従って登録することでシェアすることを考えてください。

あなたがプログラムを開発し、そのプログラムとともに補完設定を配布するつもりならば、ベンダー用の補完設定ディレクトリにインストールしてください。
このパスはシステムごとに異なるため、そのパスを発見するためにpkgconfigフレームワークを使うべきです。
pkg-config --variable completions fish を実行すれば得られます。(訳注:あれれ、こっちでは出力されないけど…)

パラメータ展開(グロブ)

コマンドにプログラムの引数が与えられたとき、コマンドに送信される前にパラメータ展開が行われます。
パラメータ展開は以下に示すように強力なメカニズムです。

ワイルドカード

*? がパラメータに存在する場合、fishは以下のようにパラメータを解釈し、ファイルにマッチさせるよう試みます。

  • ?/ 以外のどれか1文字にマッチする
  • */ を含まない0文字以上の文字列にマッチする
  • ** は0文字以上の文字列にマッチする。
    • / を含む文字列にもマッチする。すなわち、サブディレクトリ以下のファイルにもマッチする。
    • 文字列を / で区切った場合、他の文字列とこのワイルドカードを使うと、カレントディレクトリ( $PWD )のファイルにはマッチしない。
      • これはzshのような他のシェルとは異なる。
      • たとえば、 **\/*.fish (訳注: **/*.fish でもいい)は
        • zshにおいてはカレントディレクトリの拡張子.fishファイルにもマッチする
        • fishではサブディレクトリの拡張子.fishファイルにしかマッチしない。
        • fishでは ***.fish と記述すればカレントディレクトリとサブディレクトリ双方の拡張子.fishファイルにマッチする。

(訳注:例で示す)

# /tmp/xx以下に xx.fish と yy/yy.fish を作成する
$ cd /tmp
$ mkdir xx
$ cd xx
$ mkdir yy
$ touch xx.fish yy/yy.fish

# fishの場合
 echo **/*.fish
yy/yy.fish
fish $ echo **\/*.fish
yy/yy.fish
fish $ echo ***.fish
xx.fish yy/yy.fish

# zshの場合
zsh $ echo **\/*.fish
xx.fish yy/yy.fish
zsh $ echo **/*.fish
xx.fish yy/yy.fish

zshのような他のシェルではグロブでマッチするファイルを制限するために複雑なグロブ構文を用意しています。
たとえば **(.) では通常のファイルのみにマッチします。
fishでは車輪の再発明をするよりも、findなどのプログラムに任せることにしました。
つまり、ワイルドカードを通常のファイルのみにマッチしたい場合、fishでは関数を定義して使うアプローチをとります。

たとえば、

function ff --description 'Like ** but only returns plain files.'
    # This also ignores .git directories.
    find . \( -name .git -type d -prune \) -o -type f | \ 
        sed -n -e '/^\.\/\.git$/n' -e 's/^\.\///p'
end

定義したff関数を ** の代わりに使います。
my_prog (ff) はカレントディレクトリにある全通常ファイルをmy_progの引数にします。

ワイルドカードのマッチは大文字小文字の区別をせずにソートされます。
数字が含まれるファイルにおいては、連続した数字を1つの数値とみなします。
そのため、1、5、12はその順番に並びます。(訳注:わー、これは嬉しい!)

(訳注:例で示す)

$ touch 1 5 12
$ echo *
1 5 12
$ zsh -c 'echo *'
1 12 5
$ bash -c 'echo *'
1 12 5

. がファイル名の最初として与えられていない場合、 . から始まるファイル名はワイルドカードの対象外になります。(訳注: . から始まるファイル名は隠しファイルだから)
たとえば、

  • a* はカレントディレクトリのaから始まるすべてのファイルにマッチする
  • ??? はカレントディレクトリでちょうど3文字のファイル名のファイルにマッチする
  • ** はカレントディレクトリとそのサブディレクトリのすべてのファイルとディレクトリにマッチする。

ワイルドカード展開に失敗したとき、ほとんどのコマンドは実行されず、$status に0以外の数字がセットされ、警告が表示されます。
この振る舞いは、bashで shopt -s failglob と設定した場合と合致します。
ちょうど以下の3つの例外があります…

3つのコマンドはワイルドカード展開結果が0個になることを許します。
すなわちbashの shopt -s nullglob に相当します。

たとえば、 ls *.foo は拡張子.fooファイルが存在しない場合は警告が出ますが、set/count/lsを組み合わせると警告が出ません。

# *.fooが存在しない場合
$ ls *.foo
No matches for wildcard '*.foo'.
fish: ls *.foo
         ^
$ set foos *.foo
$ if count $foos >/dev/null
      ls $foos
  end

# *.fooが存在する場合
$ touch a.foo b.foo
$ ls *.foo
a.foo  b.foo
$ set foos *.foo
$ if count $foos >/dev/null
      ls $foos
  end
a.foo  b.foo

コマンド置換

一連のコマンドの出力は他のコマンドのパラメータとして使えます。
パラメータに1組の () があるとき、 () の中はコマンドのリスト(訳注:コマンドは多くの場合は1つだが、セミコロンで複数のコマンドが書けるのでリストと表現している)として解釈されます。
展開時にコマンドのリストは実行され、出力によって置き換えられます。
出力が1行以上のときは、各行が新しいパラメータに展開されます。
IFS変数を空文字列に設定すると、行を分割しなくなります。

最後に実行したコマンド置換の終了ステータスが $status で取得できます。

出力の一部のみを使うこともできます。
詳細は範囲演算子 を参照してください。

例:

$ echo (basename image.jpg .jpg).png
image.png

$ for i in *.jpg; convert $i (basename $i .jpg).png; end
# convertプログラムでカレントディレクトリの
# 全JPEGファイルをPNGフォーマットに変換。

$ begin; set -l IFS; set data (cat data.txt); end
# data.txtの内容を配列へ分割せずに変数dataに代入。
# (訳注:「set -l」によってIFSを
# begin〜end間のみに有効なローカル変数にしている)

{}展開

{} で囲まれ , で区切られたリストは、各要素が新しいパラメータになるように展開されます。

例:

$ echo input.{c,h,txt}
input.c input.h input.txt

$ mv *.{c,h} src/
# mv *.c *.h src/ と同じ

変数展開

$VARIABLE_NAME 変数VARIABLE_NAMEの値に展開されます。
シェル変数の概念を理解するには、シェル変数 を参照してください。

未定義、または空の変数は空文字列に展開されます。

変数名とテキストを分離するには、 "" か {} で変数を囲んでください。

例:

$ echo $HOME
/home/rubikitch
$ echo $nonexistent_variable
# 空行
$ set WORD cat
$ echo The plural of $WORD is "$WORD"s
The plural of cat is cats
$ echo The plural of $WORD is {$WORD}s
The plural of cat is cats

"" か {} がなければ、fishは $WORDs という存在しない変数を展開しようとします。

後者の構文 {$WORD}{}展開 により行われています。
0要素の配列変数や未定義の変数には気を付けてください。
なぜなら、これらはデカルト積として展開されるため、その結果、空文字列になってしまうからです。

変数展開は "" で囲まれた文字列で行われる唯一の展開です。
しかしながら、クオートされるときとされないときでは変数展開がどのように行われるかについて重要な違いがあります。
クオートされない変数展開は可変数の引数になります。
たとえば、 $foo という変数が0要素か未定義のときは、引数 $foo は0要素として展開されます。
$foo が5要素の配列であるとき、引数 $foo は5要素に展開されます。
"$foo" のようにクオートされると、常に1引数として変数展開されます。
未定義の変数は空文字列に展開され、配列変数はスペースで連結された文字列に展開されます。

fishの変数展開でもうひとつ注目すべき特徴があります。
以下のコード片を考えてください。

$ set foo a b c
$ set a 10; set b 20; set c 30
$ for i in (seq (count $$foo))
      echo $$foo[$i]
  end
10
20
30

上記のコードは変数値を変数名として展開するための複数の $ の使い方を示しています。
$ を変数参照演算子と考えることができます。
この機能を配列の [] とともに使うとき、 [] は最も内側の $ と結び付きます。
すなわち $$foo[5] は変数fooの5番目の要素が参照されます。
変数fooを2回参照した5番目の要素にはなりません。
代わりに $$foo[1][5] と記述します。

デカルト積

リストが他のリストや文字列と連結すると、デカルト積(直積集合)@Wikipedia として展開されます。

例:

$ echo {good,bad}" apples"
good apples bad apples
$ set -l a x y z
$ set -l b 1 2 3
$ echo $a$b
x1 y1 z1 x2 y2 z2 x3 y3 z3
$ echo $a"-"$b
x-1 y-1 z-1 x-2 y-2 z-2 x-3 y-3 z-3
$ echo {x,y,z}$b
x1 y1 z1 x2 y2 z2 x3 y3 z3
$ echo {$b}word
1word 2word 3word

変数名とテキストを分離するときに {} を使う場合は注意してください。
上記の最後の例で示した危険は {} の代わりに "" で囲むことで回避できます。

(訳注:例をさらに補充)

$ echo "$b"word
1 2 3word

範囲演算子

コマンド置換とシェル変数展開はどちらも特定の要素のみをアクセスする機能があります。
そのためには [] にインデックスのセットを記述します。
配列の一連の要素にアクセスすることはしばしばあります。
そのためには範囲演算子 .. を使います。
範囲 a..b ( ab は整数)はインデックスを a a+1 a+2 ... b (a < b) または a a-1 a-2 ... b (b < a) のように展開します。
負のインデックスは配列・コマンド置換の後から数えます。

いくつかの例:

$ seq 10
1
2
3
4
5
6
7
8
9
10
$ echo (seq 10)
1 2 3 4 5 6 7 8 9 10

# コマンド置換による出力を限定する
# 2〜5の要素を使用する
$ echo (seq 10)[2..5]
2 3 4 5

# 範囲が重なっている場合
# 2〜5、そして1〜3の要素を使用する
$ echo (seq 10)[2..5 1..3]
2 3 4 5 1 2 3

# 逆順に表示する
# 出力の最終行を先頭にし、逆順にする
$ echo (seq 10)[-1..1]
10 9 8 7 6 5 4 3 2 1

変数の設定、展開についても同じように働きます。

# PATHを逆順にする
$ set PATH $PATH[-1..1]
# この方法もある
$ set PATH[-1..1] $PATH

# PATHの後からn要素のみを取り出す
$ set n -3
$ echo $PATH[$n..-1]

変数は変数展開のインデックスとして使えますが、コマンド置換では使えません。

(訳注:例で示す。 コマンド置換で変数のインデックスを使いたければ、一度変数に設定する必要がある。)

$ set n -3
$ echo (seq 10)[$n]
Invalid index value
fish: echo (seq 10)[$n]
                    ^
$ set a (seq 10)
$ echo $a[$n]
8

ホームディレクトリ置換

~USERNAME がパラメータの先頭にある場合、ユーザ USERNAME のホームディレクトリに展開されます。
~ または ~/ はプロセスのオーナー(自分自身)のホームディレクトリに展開されます。

プロセス展開

パラメータの先頭に %STRING がある場合はプロセスID(PID)に展開されます。
以下の展開が行われます。

  • %self は動作中のfishのPID
  • %last は最後のジョブのPID
  • STRING がジョブIDである場合は、ジョブのグループID(PID)
  • STRING が子プロセスにマッチする場合、マッチしたすべての子プロセスのPID
  • STRING がユーザが所有するプロセスにマッチする場合、マッチしたすべてのプロセスのPID
  • どれにもマッチしない場合はエラー

この種の展開はkillやfgのようにPIDを引数とするコマンドに便利です。

例:

fg %ema はコマンドラインがemaから始まるプロセス(たとえばemacs)を検索します。
見付かればそのプロセスをフォアグラウンドにします。

kill -s SIGINT %3 はジョブID 3のジョブに対してSIGINTシグナルを送信します。

(訳注:例をさらに補充。sleepコマンドは引数の秒数だけ何もしない)

$ echo %self
12835
$ sleep 100&
$ sleep 200&
$ jobs
Job     Group   CPU     State   Command
2       12952   0%      running sleep 200&
Job     Group   CPU     State   Command
1       12923   0%      running sleep 100&
$ pgrep -af sleep
12923 sleep 100
12952 sleep 200
$ echo %last
12952
$ echo %sleep
12952 12923
$ echo %slee
12952 12923
$ echo %notfound
Unable to find a process 'notfound'
fish: echo %notfound
            ^
$ echo %1
12923
$ kill %1
fish: Job 1, 'sleep 100&' terminated by signal SIGTERM (Polite quit request)
$ jobs
Job     Group   CPU     State   Command
2       12952   0%      running sleep 200&
$ echo %slee
12952

異なる展開を組み合わせる

上記の展開すべてを組み合わせることができます。
1つ以上のパラメータに展開される場合、すべての組み合わせが生成されます。

複数のパラメータ展開を組み合わせた場合、以下の順番で展開されます。

  1. コマンド置換
  2. 変数展開
  3. {}展開
  4. プロセス展開
  5. ワイルドカード展開

展開は右から左へと行われ、 {} が入れ子になっている場合は内側から外側に展開されます。

例:(訳注:実際のコマンドラインに書き換えた。コマンド置換{}展開によるデカルト積)

$ mkdir /tmp/xx
$ cd /tmp/xx
$ ls
$ touch foo bar
$ echo a(ls){1,2,3}
abar1 abar2 abar3 afoo1 afoo2 afoo3

シェル変数

シェル変数は名前が付けられたデータの塊で、作成され、削除され、値を変更されるものです。
変数はexportすることもできます。
exportすることで変数のコピーが子プロセスにも伝播します。
exportされる変数は「環境変数」と呼ばれます。

変数に値を設定するには、setコマンド を使います。

例:

smurf_color変数にblueという値を設定するには、 set smurf_color blue を実行します。

変数が設定された後は、変数値を変数展開で使うことができます。

例:(訳注:実際のコマンドラインに書き換えた)

変数値を使うには $VARIABLE_NAME と書きます。

$ set smurf_color blue
$ echo Smurfs are usually $smurf_color
Smurfs are usually blue

変数のスコープ

fishには3種類の変数があります。
ユニバーサル変数グローバル変数ローカル変数 です。
ユニバーサル変数は1つのコンピュータ間で動作しているすべてのfishセッションで共有されます。

グローバル変数は

  • 現在のfishセッション固有
  • 特別なブロックスコープとは結び付かない
  • set -e コマンドを使うまで決して削除されない

ローカル変数は

  • 現在のfishセッション固有
  • 特別なブロックスコープとは結び付く
  • 特別なブロックスコープの外に出ると自動的に削除される

コマンドのブロックは以下の一連のコマンドから開始し、end コマンドで終了します。

ユーザはset コマンドのスイッチでスコープを決定できます。(訳注:原文ではだぶってるようだ)

  • -U または --universal でユニバーサル変数
  • -g または --global でグローバル変数
  • -l または --local でローカル変数

変数を作成・変更するときのスコープのルールは以下の通りです。

  1. 変数を明示的にユニバーサル変数、グローバル変数、ローカル変数に設定したときは、その設定が優先される。別なスコープに同名の変数が存在するとき、その変数は変更されない。
  2. 変数のスコープが明示されないが、すでに定義されているときは、変数のスコープは変わらない。
  3. 変数のスコープが明示されず、未定義である場合は、現在実行中の関数にローカルになる。これは -l / --local スイッチとは異なることに注意!これらのスイッチを使った場合、その変数は実行中の最も内側のブロックにローカルになる。使わない場合は、関数にローカルになる。関数実行中でない場合はグローバルになる。

同名で異なるスコープのたくさんの変数が存在する場合もあります。
変数を参照する場合、スコープの内側から外側にかけて検索されます。
すなわち、ローカル変数→グローバル変数→ユニバーサル変数の順番で使われます。

例:

以下のコードは何も出力しません。

begin
    # すべての変数が無効になるステキなローカルスコープ
    set -l pirate 'There be treasure in them thar hills'
end

echo $pirate
# pirateはローカル変数であるため、このコマンドは何も表示しない

ユニバーサル変数

ユニバーサル変数はコンピュータ内で動作している自分のfishセッション間で共有される変数です。
fishは多くの設定オプションをユニバーサル変数として記憶しています。
つまり、fishの設定を変更するためには、変数値を一度変更するだけでいいのです。
変更はすべてのfishセッションで自動的に反映され、リブート・ログイン・ログアウトしても保持されます。

以下の操作を通じてユニバーサル変数を実際に体験してください。

  1. 2つのfishセッションを並べて起動させる
  2. 1つめのfishで set fish_color_cwd blue を実行する
  3. 両方の端末でカレントディレクトリの色が一瞬で変更されるのを確認する

それは fish_color_cwd がユニバーサル変数だからです。

ユニバーサル変数は ~/.config/fish/fishd.MACHINE_ID というファイルに保存されます。
MACHINE_ID はたいていの場合MACアドレスです。
このファイルを直接変更しないでください!
変更が上書きされてしまうことがあるからです。
その代わり、fishをスクリプト経由か対話的に使用することでユニバーサル変数を変更してください。

ユニバーサル変数を ~/.config/fish/config.fish で加えないでください。
なぜなら、ユニバーサル変数は新しいfishセッションごとに長くなっていくからです。(訳注:ちょっとよくわからない…)
その代わり、コマンドラインで一度だけ設定してください。(訳注: set -U)

関数における変数スコープ

関数を呼ぶとき、現在のローカル変数は一時的にすべて消えます。
名前空間が衝突して間違って他(訳注:呼び出し元等)の関数からの変数が簡単に変更できてしまうため、ローカルスコープを隠すことが必要になってきます。

例:

function shiver
    set phrase 'Shiver me timbers'
end

function avast
    set phrase 'Avast, mateys'
    # Calling the shiver function here can not
    # change any variables in the local scope
    shiver
    echo $phrase
end
avast
# "Avast, mateys"を出力する

export変数

fishの変数はexportできます。
exportとは、fishから起動されるすべてのコマンドが変数を継承することです。
export変数は大文字、それ以外の変数は小文字にするのが慣例になっています。

変数はset コマンドで -x または --export スイッチをつけることでexportできます
-u または --unexport スイッチでexportしないこともできます。
作成時・変更時のexportのルールはスコープのルールと同一です。

  1. 変数がexportされるかどうかを明示的に設定したときは、その設定が優先される。
  2. 変数がexportされるかどうかを明示的に設定していないが、すでに定義されているときは、定義時のルールに従う。
  3. 変数がexportされるかどうかを明示的に設定していなくて、かつ未定義であるときは、exportされない。

配列

fishは複数の文字列を1つの変数に格納できます。
配列の要素にアクセスするには、インデックスを [] で指定します。
たとえば、このように。

echo $PATH[3]

fishにおいては配列のインデックスは1から始まります(訳注:1始点)。
多くのプログラミング言語では0から始まりますが、fishでは異なります。
seqのような多くの一般的なUnixツールが1始点だからです。

[] を使わない場合、配列の全要素が個別に出力されます。
このことは、for コマンドを使って簡単に繰返し処理できることを意味します。

$ for i in $PATH; echo $i is in the path; end
/r/.config/fish/bin is in the path
/m/home/rubikitch/bin is in the path
/r/gocode/bin is in the path
/m/home/rubikitch/ruby is in the path
/usr/local/sbin is in the path
/usr/local/bin is in the path
/usr/sbin is in the path
/usr/bin is in the path
/sbin is in the path
/bin is in the path
/usr/bin/mh is in the path
/usr/games is in the path
/usr/X11R6/bin is in the path

blueとsmallの2要素で構成されたsmurfという変数を作成するには、シンプルにこのように記述します。

set smurf blue small

配列の要素を個別に設定・削除することもできます。

# 変数smurfを'blue'と'small'の2要素に設定する
$ set smurf blue small

# 2番目の要素を'evil'に変更する
$ set smurf[2] evil

# 最初の要素を削除する
$ set -e smurf[1]

$ echo $smurf
evil

配列変数を拡大・設定するときに負のインデックスを指定すると、配列は後ろから数えられます。
たとえば、インデックス -1 は配列の最後尾です。

インデックスで範囲演算子も使えます。
詳細は 範囲演算子 を参照してください。

すべての配列は1次元で、他の配列を含めることはできません。
ですが、 変数展開 の参照演算子を使うことで疑似的な多次元配列は実現できます。

fishは起動時に PATHCDPATHMANPATH 環境変数から自動的に配列を作成します。
(以前のバージョンではコロン区切りの全ての環境変数から配列を作成していました。)

特殊変数

ユーザは特定の変数を変更することでfishの設定を変えられます。

  • fish_colorfish_pager_color から始まる膨大な数の変数がある。
  • fish_greeting 変数は起動時に表示されるあいさつメッセージ。
  • fish_escape_delay_ms はfishがESC文字を受信してからキーバインド検索をやめるまでのデフォルトのタイムアウトを変更する。
    • Emacs(デフォルト)キーバインドで300ms。
    • viキーバインドで10ms。
    • bind ビルトインの説明を参照。
    • この遅延処理があるからこそ、ESCをメタキーとして使える。
  • BROWSER はユーザお気に入りのWebブラウザ。
    • この変数を設定すると、fishはドキュメントを表示するためにシステムのデフォルトブラウザではなくてこの変数で設定されたブラウザを使用する。
  • CDPATH はcdビルトインがディレクトリを検索するために使う配列変数
    • 訳注:たとえば set -x CDPATH $HOME と設定していれば、どのディレクトリにいてても cd .emacs.d~/.emacs.d に移動できて便利。
    • よく使うディレクトリを追加すると快適になる。
  • LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME は、fishと子プロセスの言語オプションを設定する。
  • fish_user_paths は環境変数 PATH に優先的に加えられるディレクトリの配列変数。
    • ユニバーサル変数にできる。
  • PATH はコマンドを検索するディレクトリの配列変数。
  • umask はファイル作成時のumaskを設定する変数。
    • umask 変数を変更するには、umask関数 を介すること。
    • umask 変数に不当な値を設定すると常に失敗する。

fishはいくつかの環境変数を通してユーザに新たな情報を送信します。
ユーザは以下の変数値のほとんどを変更できません。

  • _ は現在動作中のコマンド名。
  • argv はシェル(訳注:fishスクリプト)や関数に渡された引数の配列変数。
    • 以下の状況のときのみ定義される。
      • 関数呼び出し中。
      • fish myscript.fish foo bar のようにスクリプトの引数として指定されたとき。
    • ユーザ側で変更可能。
  • history は過去に実行したコマンド履歴の配列変数。
  • HOME はユーザのホームディレクトリ
    • ユーザ側で変更可能。
  • IFS (internal field separator)は read builtin が単語に分割する際に使う変数。
    • 空文字列に設定すると、コマンド置換 で行ごとに分割しない。
    • ユーザ側で変更可能。
  • PWD はカレントディレクトリ。
  • status は最後にフォアグラウンドで実行したジョブの 終了ステータス
    • シグナルで停止させられた場合は、「128+シグナル番号」になる。
  • USER はユーザ名。
    • ユーザ側で変更可能。
  • CMD_DURATION には最後のコマンドの実行時間(ミリ秒)。
  • FISH_VERSION は動作中のfishのバージョン。
  • COLUMNS は端末の幅。
  • LINES は端末の高さ。
  • SHLVL はシェルのネスティングレベル。

これらの変数名の多くはcsh系からとったもので、bashなどのBourne系とは異なります。
大文字の変数名はfishから起動されるプログラムにexportされ、小文字の変数はexportされません。
このルールはfishが強要するものではありませんが、exportされる変数とされない変数を区別するための良い心掛けです。
fishはまた、いくつかの変数を内部的に使っています。
このような変数名は __FISH__fish から始まります。
内部的な変数は決して使わないようにしてください。
内部的な変数を変更するとfishが動かなくなるかもしれません。

$status 変数

終了ステータスとは、

  • プロセスが終了すればいつでも起動したプログラムから(多くの場合はシェル)返ってくる。
  • 終了ステータスは整数。
  • コマンドの実行結果を呼び出し元に伝える。一般に
    • 終了ステータス0で正常終了。
    • 0以外で異常終了。

fishは最後のジョブの最後のプロセスの終了ステータスを $status 変数に格納します。

コマンド実行中に問題が発生したときは、fishは $status に特定の値を設定することがあります。

  • 1は一般に不当な引数をビルトインコマンドに与えた場合。
  • 124はワイルドカードにマッチするファイルがなくてコマンドが実行されなかった場合。
  • 125は指定された名前の実行ファイルはあるものの、OSがコマンドを実行できなかった場合。
  • 126は指定された名前のファイルはあるものの、実行不可能だった場合。
  • 127はその名前の関数、ビルトイン、コマンドがなかった場合。

プロセスがシグナルで終了した場合は、「128+シグナル番号」が終了ステータスとなります。

ハイライトの色を変更する変数

fishがシンタックスハイライトで使う色は様々な変数値を変更することで設定できます。
これらの変数値は set_color コマンドにより受け付けられた色のひとつのこともあります。
set_color が受け付ける --bold または -b スイッチも受け付けます。

以下の変数はfishのハイライトの色を変更します。

  • fish_color_normal はデフォルトの色。
  • fish_color_command はコマンドの色。
  • fish_color_quote はクオートされたテキストの色。
  • fish_color_redirection はIOリダイレクトの色。
  • fish_color_end;& のようなプロセスを分けるための色。
  • fish_color_error は起こり得るエラーをハイライトするための色。
  • fish_color_param は通常のコマンドのパラメータの色。
  • fish_color_comment はコードのコメントの色。
  • fish_color_match はマッチした括弧の色。
  • fish_color_search_match は履歴検索をハイライトするための色。
  • fish_color_operator*~ といったパラメータ展開演算子の色。
  • fish_color_escape\n\x70 といった文字エスケープをハイライトするための色。
  • fish_color_cwd はデフォルトプロンプトのカレントディレクトリの色。
  • fish_color_autosuggestion はオートサジェスチョンで使われる色。
  • fish_color_user はいくつかのデフォルトプロンプトで使われている現在のユーザ名の色。
  • fish_color_host はいくつかのデフォルトプロンプトで使われている現在のホスト名の色。

また、次の変数値を変更することで補完ページャのハイライトを変更できます。

  • fish_pager_color_prefix はプレフィクス文字列の色。補完済み。
  • fish_pager_color_completion は補完候補の色。
  • fish_pager_color_description は説明文の色。
  • fish_pager_color_progress は左下隅のプログレスバーの色。
  • fish_pager_color_secondary は第二の候補のバックグラウンドの色。

例:

エラーを赤くハイライトするには

set fish_color_error red --bold

を実行します。

ロケール変数

ロケールを設定する最も一般的な方法は set -x LANG en_GB.utf8 のようなコマンドを使うことです。
これは現在のロケールをイギリス英語にし、UTF-8の文字セットを使う設定です。
全ロケールを得るには locale -a を実行します。

以下はシェルと子プロセスに対する言語設定を行う変数です。

  • LANG
  • LC_ALL
  • LC_COLLATE
  • LC_CTYPE
  • LC_MESSAGES
  • LC_MONETARY
  • LC_NUMERIC
  • LC_TIME

これらの変数は次のように働きます。

  • LC_ALL はロケールのすべての情報を強制的にその値に設定する。
  • LC_ALL が設定されていれば、他の変数は無視される。
  • 他の LC_ 変数は特定のロケール情報を設定する。
  • LANG は他の LC_ 変数が未定義のときに使われる予備の変数。

ビルトインコマンド

他のシェルの多くは膨大なビルトインコマンドを持っています。
ビルトインコマンドの多くはスタンドアロンなコマンドとしても存在しますが、シェル側で実装されています。
しかしコードが重複する上、ビルトインコマンドとスタンドアロンのコマンドの微差がもたらす混乱招きます。
混乱を避けるため、fishでは原則的に、通常のコマンドでは実現できない挙動のみをビルトインとして実装しています。

fishが用意しているすべてのビルトイン、関数、コマンドを一覧したければ、サイトの左カラムを参照してください。
ドキュメントはコマンドに --help スイッチを付けても閲覧できます。

コマンドラインエディタ

fishのコマンドラインエディタはこんな機能があります。

bashと同じように、fishにもEmacsモードViモードの編集モードがあります。
デフォルトの編集モードはEmacsモードです。
Viモードに切り替えるには、 fish_vi_key_bindings を実行し、Emacsモードに戻すには fish_default_key_bindings を実行します。
関数を作成して $fish_vi_key_bindings にその名前を設定することで、あなた独自のキーバインドが実現します。

たとえば、

function hybrid_bindings --description "Vi-style bindings that inherit emacs-style bindings in all modes"
    for mode in default insert visual
        fish_default_key_bindings -M $mode
    end
    fish_vi_key_bindings --no-erase
end
set -g fish_key_bindings hybrid_bindings

^

モード共通のコマンド

いくつかのキーバインドはEmacsモードViモードで共通しています。
なぜなら、それらはテキストを変更するものではなく、Vi/Vimの特定のキーはシェルにおいては意味を成さないからです。

  • TABは現在のトークンを補完 する。
  • Shift+TABは現在のトークンを補完し、ページャサーチモードに移行する。
  • Alt+←とAlt+→は
    • カーソルを単語単位で移動する。
    • コマンドラインが空のときはディレクトリ履歴をたどり、カレントディレクトリを変更する。
    • カーソルが行末にあり、オートサジェスチョンが有効なときは、Alt+→またはAlt+Fはサジェスチョンの最初の単語を受け入れる。


  • ↑と↓はコマンドラインで指定された文字列からコマンド履歴を検索する。
    • コマンドラインが空の状態で検索を始めると、すべてのコマンドにマッチする。
    • 履歴検索の詳細は履歴を参照。
  • Alt+↑とAlt+↓はコマンドラインで指定されたトークンを含むコマンド履歴を検索する。
    • コマンドラインが空の状態で検索を始めると、すべてのトークンにマッチする。
    • 履歴検索の詳細は履歴を参照。
  • Ctrl+Cはコマンドライン全体を削除する。
  • Ctrl+Dは
    • カーソル位置の文字を削除する。
    • コマンドラインが空ならば、fishを終了する。
  • Ctrl+Uはコマンドライン全体を削除するが、キルリング に格納する。
  • Ctrl+Wは直前のパス要素(直前の / まで)を削除し、キルリング に格納する。
  • Alt+Dは次の単語を削除し キルリング に格納する。
  • Alt+H または F1 は現在のコマンドのmanページを開く。
  • Alt+Lはファイルリストを表示する。
    • カーソルがディレクトリ引数にあるならばそのディレクトリを表示する。
    • ないならばカレントディレクトリを表示する。
  • Alt+Pは文字列 '| less;' をカーソル位置のジョブの最後に追加する。
    • それにより、出力結果がページャで表示される。
    • (訳注:出力が長いときにおすすめ。環境変数 PAGER で他のページャを指定可能。)
  • Alt+Wはカーソル位置のコマンドの短い説明を表示する。

Emacsモードのコマンド

  • HomeまたはCtrl+Aはカーソルを行頭に移動する。
  • EndまたはCtrl+Eは
    • カーソルを行末に移動する。
    • カーソルがすでに行末にあり、オートサジェスチョンが有効であるならば、オートサジェスチョンを受け入れる。
  • ←(またはCtrl+B) と →(またはCtrl+F)は
    • カーソルを1文字単位で左右に移動する。
    • カーソルがすでに行末にあり、オートサジェスチョンが有効であるならば、オートサジェスチョンを受け入れる。
  • Deleteはカーソル位置、BackSpaceはカーソル直前の1文字を削除する。
  • Ctrl+Kはカーソル位置から行末までを削除し キルリング に格納する。
  • Alt+Cは現在の単語をキャピタライズにする。
  • Alt+Uは現在の単語を大文字にする。
    • (訳注:Emacsにおいて単語を小文字にするAlt+Lはfishではページャのコマンドを挿入するコマンドになっている)
  • Ctrl+Tは直前の2文字を入れ替える。
  • Alt+Tは直前の2単語を入れ替える。

キーバインドを変更するには、bind ビルトインを使います。

Viモードのコマンド

Viモードはコマンドラインにおいて、Viライクなコマンドが使えます。
最初は 挿入モード が有効になっています。
ESCでViモードのコマンドが使えるようになります。
以下の3つのモードで使えるコマンドを以下で述べます。

Viモードはモード共通のコマンドEmacsモードのコマンド を共有します。

以下のような設定で、ViモードにすべてのEmacsモードのキーバインドを加えることができます。

function fish_user_key_bindings
    # Emacsキーバインドが使われるように、モードごとにこれを一度実行する。
    fish_default_key_bindings -M insert
    # fish_vi_key_bindings は引数なしではすべてのキーバインドをデフォルトに戻す
    # fish_vi_key_bindingsの引数には最初のモードを指定する(insert, default, visual)
    fish_vi_key_bindings insert
end

Viモードでは fish_mode_prompt 関数がプロンプトの左にどのモードであるかを表示します。
fish_vi_cursor 関数を使えばサポートされている端末においては、モードごとにカーソルの形を変更できます。
この機能を無効にしたければ、 fish_vi_cursor を空の関数として再定義してください。

(訳注:例で示す)

function fish_vi_cursor
end

コマンドモード

コマンドモードとはノーマルモードとも呼ばれています。

  • hはカーソルを左へ移動する。
  • lはカーソルを右へ移動する。
  • i はカーソル位置において 挿入モード へと移行する。
  • v はカーソル位置において ビジュアルモード へと移行する。
  • a はカーソル位置の直後で 挿入モード へと移行する。
  • Shift+A 行末において 挿入モード へと移行する。
  • 0 (ゼロ) はカーソルを行頭へ移動する。
    • 実行後もコマンドモードのまま
  • dd は現在行を削除して キルリング へ格納する。
  • Shift+D はカーソル位置から行末までを削除し キルリング に格納する。
  • p は キルリング からテキストを貼り付ける。
  • u は最後の編集をアンドゥする。
  • [ と ] はコマンドラインで指定されたトークンを含むコマンド履歴を検索する。
  • Ctrl+X はカレントバッファをシステムのクリップボードへコピーする。
  • Ctrl+V はクリップボードの内容を貼り付ける。
  • Ctrl+C はコマンドライン全体を削除する。
  • BackSpace はカーソルを左へ移動する。

挿入モード

  • ESC か Ctrl+C は コマンドモード へ移行する。
  • Ctrl+X は
    • 行末へカーソルを移動する。
    • オートサジェスチョンが有効であるならば、オートサジェスチョンを受け入れる。
  • BackSpace はカーソル直前の文字を削除する。

ビジュアルモード

  • ← と → は1文字ずつ選択範囲を広げ(狭め)る。
  • b と w は1単語ずつ選択範囲を広げ(狭め)る。
  • d と x は選択範囲を削除して キルリング に格納し、 コマンドモード へ移行する。
  • ESC と Ctrl+C は コマンドモード へ移行する。

コピー&ペースト(キルリング)

fishは以下に示すようにEmacsのようなキルリングを持ちます。

  • コピー・貼り付けができる。
  • Ctrl+K はカーソル位置から行末までをカットする。
  • カット(Emacs用語でいうkill)された文字列は、キルリングと呼ばれるリンクリストに挿入される。
  • Ctrl+Yはキルリングの先頭を貼り付ける。
  • 貼り付け後、Alt+Yでキルリングを過去のものに置き換える。

検索可能な履歴

コマンドは入力された後に履歴リストの最後尾に挿入されます。
過去の履歴と一致するものは自動的に削除されます。
ユーザは↑と↓キーで履歴を検索できます。
履歴検索をしたときにコマンドラインが空でなければ、コマンドラインに入力された文字列を含むコマンドのみが示されます。

Alt+↑とAlt+↓でも履歴検索が行われますが、コマンドライン全体を検索するのではなくて、各コマンドラインは実行前のように要素(訳注:単語)ごとに分割され、カーソル位置にマッチした要素を履歴から検索します。

ESCで履歴検索を中止します。

コマンドラインの先頭をスペースで始めれば、行全体を履歴に登録しなくなります。

履歴は ~/.local/share/fish/fish_history または $XDG_DATA_HOME/fish/fish_history ( $XDG_CONFIG_HOME が設定されているなら) に保存されます。

例:

単語makeを含む過去のコマンドラインを検索するには、makeと打ち込んで↑を押してください。

コマンドラインに cd m とまで打ち込んでAlt+↑を押すと、過去のコマンドラインからmを含む単語を検索します。

複数行の編集

fishのコマンドラインエディタは複数行にわたるコマンドでも動作するようになっています。
コマンドを複数行に分割するには3つの方法があります。

  • ブロック系のコマンド(1つ以上の for / begin / if など)が対応する end コマンドで閉じられていないときにEnterを押す。
  • Enterの代わりにAlt+Enterを押す
  • Enterを押す前に \ を挿入して改行文字をエスケープする

fishのコマンドラインエディタは1行でも複数行でもまったく同じように動作します。
行間を移動するには←・→キーやその他キーボードショートカットを使ってください。

複数のプログラムを動作させる

fishが起動したプログラムは通常、フォアグラウンドで動作します。
つまり、プログラムは端末を制御し、fishは起動したプログラムが終了するまで動作を停止します。
ときに、フォアグラウンド動作は望まないこともあります。
たとえば、端末からGUIアプリケーションを起動し、fishを使い続けたいときです。
そのような場合、ユーザがfishの挙動を変更するいくつかの方法があります。

  1. コマンドを & を終了させて、fishにそのコマンドをバックグラウンドで動作させるように指示する。
    • バックグラウンドプロセスはfishと同時に動作する。
    • fishは端末の制御権を保持しているので、プログラムはキーボード入力を受け付けない。
  2. Ctrl+Zを押して、現在動作中のフォアグラウンドプログラムを一時停止させ、fishに制御を戻す。
    • この方法が効かないプログラムはCtrl+Zを別なキーに割り当てる。
    • GNU EmacsはCtrl+X Ctrl+Zで動作を一時停止する。
      • (訳注:Ctrl+X zはrepeatなので原文が間違っている。またCtrl+Zも普通に効く)
  3. fgbg ビルトインコマンドを使って任意の動作中のジョブをフォアグラウンド/バックグラウンドにさせる。

ただし、関数はバックグラウンドで動作させることはできません。
一時停止され、bgコマンドでバックグラウンドに動作させられた関数は正しく動作しないでしょう。

(訳注:これは痛いfishの弱点(涙)
将来は克服されることを願う。
それまでは fish -c COMMAND & で代用しよう。)

初期化ファイル

fishは起動時に、いくつかの設定ファイルを評価します。
設定ファイルはfishの挙動をコントロールするために使われます。
設定変数(?)の場所はいくつかの環境変数により決定します。
デフォルトまたは典型的な場所は以下になります。

設定ファイルは以下の順番で評価されます。

  1. fishに付属している設定(編集されるべきではない) :: $__fish_datadir/config.fish (たいてい /usr/share/fish/config.fish )
  2. システム全体の設定ファイル(システム管理者がすべてのユーザが使えるようにするために用意した(POSIXなシェルの/etc/profile相当)) :: $__fish_sysconfdir (たいてい /etc/fish/config.fish )
  3. 拡張子.fishの設定ファイルたち

    1. $XDG_CONFIG_HOME/fish/conf.d (デフォルト ~/.config/fish/conf.d/ )
    2. $__fish_sysconfdir/conf.d (デフォルト /etc/fish/conf.d )
    3. /usr/share/fish/vendor_conf.d (コンパイル時に設定; デフォルト $__fish_datadir/conf.d )

    同名のファイルが以上のディレクトリに存在した場合、最初のみが実行される。

  4. ユーザによる初期化。 たいてい ~/.config/fish/config.fish
    (環境変数 XDG_CONFIG_HOME で設定可能)

これらのパスはビルド・インストール・動作時のパラメータや上記のデフォルトにより異なります。

広範囲の探索は混乱を招くかもしれません。
どこに自分の設定ファイルがあるのかよくわからないならば、とりあえず ~/.config/fish/config.fish を使ってください。

以上のファイルはfishの起動時に毎回実行されます。
対話的シェルとしてfishを起動させるときのみ実行させたいコマンドがあるならば、 status --is-interactive の終了ステータスを使い、fishが対話的なのかを判別してください。
ログインシェルとして使うときのみコマンドを実行させるには status --is-login を代わりに使ってください。
こうすることで非対話的、非ログインシェルの起動が速くなります。

あなたがプログラムを開発するならば、もしかしたらシステム内の全fishユーザに動作させる設定をインストールしたくなるかもしれません。
これはおすすめできません。
もし設定が慎重に記述されていない場合、副作用を引き起こすかfishの起動が遅くなるかもしれません。
しかも、fish固有の設定は他のシェルのユーザに益をもたらしません。
しかしながら、全ユーザに動作させる設定が絶対的に必要であれば vendor 設定ディレクトリにインストールしてもよいです。
この場所はシステムごとに異なるので、pkgconfigフレームワークを使って発見すべきです。
pkg-config --variable confdir fish の出力で得られます。

例:

ログインシェルで ~/linux/bin を PATH に加えたいならば、 ~/.config/fish/config.fish に以下の設定を加えてください。

if status --is-login
    set -x PATH $PATH ~/linux/bin
end

fishを終了するときにコマンド群を実行させたいときは、終了時に実行される イベントハンドラー を使ってください。
(訳注: %self はfishのPID)

function on_exit --on-process %self
    echo fish is now exiting
end

その他の機能

シンタックスハイライト

fishはコマンドラインに文字を打ち込むたびに解釈し、シンタックスハイライトでユーザにフィードバックします。
最も重要なフィードバックは起こり得るエラーを発見することです。
デフォルトではエラーは赤く表示されます。

以上のエラーを検出します。

  • 存在しないコマンド。
  • 存在しないファイルに対する読み込みや追記。
  • 出力リダイレクトの誤用。
  • 釣合わない括弧。

カーソルが括弧やクオートの内側にあるとき、fishはマッチする括弧やクオートをもハイライトします。

シンタックスハイライトをカスタマイズするには、ハイライトの色を変更する変数でリストされた環境変数を設定してください。

タイトルの設定

GUI上の仮想端末を使っているならば、ほとんどの場合、端末ウィンドウのタイトルバーに表示させるメッセージを設定できます。
この設定は fish_title 関数を定義することでfishが自動的にやってくれます。
新しいコマンドを実行する前後、またはフォアグラウンド実行させたときに fish_title 関数は実行され、出力がタイトルバーメッセージとして使われます。
fish_prompt 関数が呼ばれるとき、 $_ 環境変数はいつもフォアグラウンドで実行しているジョブ名(fishに制御があるときは'fish')を保持しています。
fish_title の最初の引数は直前にフォアグラウンド実行されたコマンド文字列です(fish 2.2以降)。

例:デフォルトのfishのタイトル

function fish_title
    echo $_ ' '
    pwd
end

例:直前のコマンドをタイトルに設定する

function fish_title
    echo $argv[1]
end

プロンプトの設定

fishがユーザ入力を待っているとき、 fish_promptfish_right_prompt 関数を呼び出すことでプロンプトを表示します。
fish_prompt 関数の出力は左側、 fish_right_prompt 関数の出力は右側に表示されます。
fish_mode_prompt の出力は左側の先頭に追加されます。
デフォルトの関数はこれをViモード でしかやりませんが。

起動時あいさつの設定

fish_greeting 関数が定義されているならば、対話モードに入るときに実行されます。
fish_greeting 関数が未定義で、 fish_greeting 環境変数が定義されているならば、それを表示します。
(訳注:対話モードに入るときのみ実行・出力してほしいコマンドを書く場合にいい場所だと思う)

イベントハンドラー

fishで新しい関数を定義するとき、イベントハンドラーにすることもできます。
つまり、特定のイベントが発生したときに自動的に実行される関数です。
現在対応しているイベントハンドラーは、以下です。

  • シグナルを受け取った。
  • プロセス・ジョブが終了した。
  • 変数が変更された。
  • プロンプトを表示する直前。
  • コマンドが見付からなかった。

例:WINCHシグナルに対するシグナルハンドラを記述する。

function --on-signal WINCH my_signal_handler
    echo Got WINCH signal!
end

注意!イベントハンドラーは関数がロードされたときのみ有効になります。
オートロード するのではなくて source コマンドを使うか関数を実行する必要があります。
~/.config/fish/config.fish に記述するのがひとつの方法です。

新しいイベントハンドラーを定義する方法についての詳細は、 function コマンドの説明を参照してください。

fishスクリプトのデバッグ

fishはデバッガを備えています。
デバッガを使えば任意の地点でスクリプトの実行を一時停止し、プロンプトを出すことができるようにします。
このプロンプトを使えば、任意の変数値をチェック・変更したり、どんなシェルスクリプトコマンドを実行したりできます。
元のスクリプトの実行に戻るには、単にプロンプトを終了すればいいだけです。

デバッガを起動させるには、breakpoint(和訳・実例追記!) ビルトインを呼び出すだけです。
TRAP シグナルのデフォルトの挙動は breakpoint を呼び出すことです。
そのため、実行中のスクリプトにTRAPシグナルを送信することでデバッグできます。
一度デバッガに入れば、新しいブレークポイントを設定することは簡単です。
funced 関数を使って元の関数定義を変更することでできます。

fishにおける主な問題点

ホームディレクトリにfishをインストールした場合、fishは自分以外のユーザでは正しく動作しないでしょう。
なぜなら、fishは正しく動作させるための初期化ファイル群が必要だからです。
この問題を解決するには、各fishユーザのホームディレクトリに初期化ファイル群をコピーするか、初期化ファイル群を /etc/ にインストールしてください。

さらなる助けと開発

このドキュメントで触れられていない質問があるならば、助けを求められる手段がいくつかあります。

  1. 公式メーリングリスト fish-users@lists.sourceforge.net
  2. IRCチャネル irc.oftc.net の #fish
  3. GitHubのプロジェクトページ

fishの発展に貢献したければ、メーリングリストかGitHubページに投げてください。

最後までお読みいただき、ありがとうございました。参考になれば嬉しいです。