Documentation

チュートリアル

なぜfishなのか?

fishはbashやzshのように完備で, 気の利いたユーザーフレンドリーなコマンドラインシェルです. fishはシンタックスハイライト, オートサジェスト, タブ補完といった強力な機能を学習したり 設定をいじったりすることなく利用することができます.

コマンドラインを難しい構文を覚えたり設定ファイルを書いたりすることなくもっと生産的に, 便利に, 楽しくしたいならfishこそが探し求めていたものになるでしょう!

はじめかた

一度インストールしてしまえば今使っているシェルでfishとタイプするだけで試してみることができます!

起動するとfishのプロンプトが表示されます. これはもう準備ができていてfishを始めることができることを意味しています.

> fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
you@hostname ~>____

このプロンプトはfishのデフォルトのプロンプトで, あなたのユーザーネーム, ホストネーム, それからワーキングディレクトリを表示しています.

  • プロンプトを変えるためには[プロンプトの変えかた]
  • fishをログインシェルにするには[デフォルトシェルをfishに変える]

を読んでください.

以降, プロンプトは簡単のため'>_'で表します.

fishを学ぶ

このチュートリアルではコマンドラインシェルとUnixコマンドの基本的な理解と, fishが動く環境を前提としています.

もし他のシェルのことをよく知っていて, fishがそれとどう異なるのかを知りたい場合は他のシェルと違ってというフレーズを検索してください. これは重要な違いを示す時に使われています.

コマンドの実行

fishは他のシェルと同じように, コマンドに続けて引数を与えることで実行します. スペースはセパレータとなっています.

>_ echo hello world
hello world

空白文字として引数を与えたい場合, バックスラッシュを前置するか或いはシングルクオート, ダブルクオートで囲むことによって実現します.

>_ mkdir My\ Files
>_ cp ~/Some\ File 'My Files'
>_ ls "My Files"
Some File

コマンドはセミコロンを用いることによって繋げることができます.

ヘルプを読む

fishには素晴らしいhelpとmanページが備わっています. helpコマンドを実行するとウェブブラウザでヘルプを開き, manコマンドはターミナル上でmanページを開きます. 特定のコマンドについてのヘルプを読むこともでき, 例えばhelp setとすればウェブブラウザで, mans setとすればターミナルで読むことができます.

>_ man set
set - handle shell variables
  Synopsis...

シンタックスハイライト

fishを使っているとタイプするに従ってシンタックスハイライトが効いていることに すぐに気がつくでしょう. 無効なコマンドはデフォルトでは赤く表示されます.

>_ <eror>/bin/mkd</eror>

コマンドが存在しない或いは実行可能でない場合に無効となり, 有効になると色が変化します.

>_ /bin/mkdir

fishはファイルパスが有効なとき下線を示すでしょう.

>_ cat <u>~/somefi</u>___

これは'somefi'から始まるファイルが存在していることを示していて, タイピングの補助となります.

これらのシンタックスハイライトは他にもたくさんありますが, fish_configを変更したり 変数を直接編集することによって色を変えることができます.

ワイルドカード

fishはワイルドカードの*をサポートしています. 全てのJPEGファイルをリストアップするには次のようにします.

>_ ls *.jpg
lena.jpg
meena.jpg
santa maria.jpg

複数のワイルドカードを用いることもできます.

>_ ls l*.p*
lena.png
lesson.pdf

特に強力なのはディレクトリを再帰的に探索する**です.

>_ ls /var/**.log
/var/log/system.log
/var/run/sntp.log

ディレクトリの探査に時間がかかるときはCtrl-cで中止することができます.

パイプとリダイレクト

|を用いることでコマンドをパイプすることができます.

>_ echo hello world | wc
       1       2      12

stdinとstdoutは馴染み深い<>によってリダイレクトすることができます. stderrは2>によってリダイレクトされます.

>_ grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt

オートサジェスト

fishはタイプに従ってコマンドをサジェストします. サジェストされた結果はカーソルの右側に灰色で示されます.

>_ <eror>/bin/h</eror><s>___ostname</s>

パスやオプションをサジェストすることもできます.

>_ grep --i<s>___gnore-case</s>

もちろん履歴にもはたらきます. 一度コマンドを実行したことがあれば, 数文字タイプしただけで再度 実行することができます.

>_ <eror>r<</eror><s>___sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</s>

サジェストの結果を利用するにはまたはCtrl-fを押してください. 最初の1語だけを利用したい場合はAlt-→を押してください. また, サジェストが求めているものと異なればそのまま無視して構いません.

タブ補完

fishはすぐに使えるリッチなタブ補完を備えています. tabを押してみると, fishはコマンドや引数, パスを補完しようとするでしょう.

>_ <eror>/pri</eror> :kbd:`Tab` => /private

複数の候補が見つかれば, それらをリストとして表示します.

>_ <eror>~/stuff/s</eror> :kbd:`Tab`
<mtch>~/stuff/script.sh  <i>(Executable, 4.8kB)</i>  \mtch{~/stuff/s</mtch>ources/  <i>(Directory)</i>}

tabを押すたびにその候補を順にフォーカスします.

fishはgitのブランチのようなものまでも補完することができます.

>_ git merge pr :kbd:`Tab` => git merge prompt_designer
>_ git checkout b :kbd:`Tab`
<mtch>builtin_list_io_merge <i>(Branch)</i> \mtch{b</mtch>uiltin_set_color <i>(Branch)</i> <mtch>b</mtch>usted_events <i>(Tag)</i>}

実際にtabを押して確認してみましょう!

変数

他のシェルと同じように, $によって変数を扱います.

>_ echo My home directory is $HOME
My home directory is /home/tutorial

変数はダブルクオートのなかでは置換されますが, シングルクオートの中では置換されません.

>_ echo "My current directory is $PWD"
My current directory is /home/tutorial
>_ echo 'My current directory is $PWD'
My current directory is $PWD

他のシェルと違って, fishは変数を代入する構文を持ちません. 代わりに変数名とその値を引数にとる, setコマンドを持ちます.

>_ set name 'Mister Noodle'
>_ echo $name
Mister Noodle

(クオートに注意してください. もしこれがなければMisterNoodleは別々の引数として認識され, $nameは2つの要素を持つリストになります.)

他のシェルと違って, 変数は置換後に分割されることはありません.

>_ mkdir $name
>_ ls
Mister Noodle

bashでは上記コマンドで"Mister"と"Noodle"という2つのディレクトリが作られます. fishでは"Mister Noodle"という値を持った変数によって1つのディレクトリが作られます. つまりmkdirにはスペースを含んだ文字列の引数として渡されます. 他のシェルではリストという表現ではなく"配列"という用語が用いられます.

終了ステータス

他のシェルと違って, fishは直前に実行したコマンドの終了ステータスを$?ではなく$statusという変数に格納します.

>_ false
>_ echo $status
1

0は成功, それ以外はエラーを表します. $pipestatusというパイプの過程の終了ステータスを格納する配列の変数もあります.

エクスポート(シェル変数)

他のシェルと違って, fishexportコマンドをサポートしていません. 代わりにsetコマンドの--export或いは-xオプションによって変数をエクスポートします.

>_ set -x MyVariable SomeValue
>_ env | grep MyVariable
MyVariable=SomeValue

変数は-e若しくは--eraseオプションによって削除することができます.

>_ set -e MyVariable
>_ env | grep MyVariable
(no output)

リスト

先に見たsetコマンドはクオートで囲むことによってMister Noodleを1つの引数として扱いました. もし2つの引数だったなら, 変数nameは長さ2のリストになります. 実際, fishの全ての変数はリストであり, いくつでも値を保持できるし全く持たないことも可能です.

$PWDのようないくつかの変数は1つしか値を持ちません. 慣習に従って変数の値というとき, 最初(かつただ1つ)の値を指すことにします.

$PATHのようなその他の変数は複数の値を保持しています. これらの変数は複数の引数として展開されます.

>_ echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin

"PATH"で終わる変数は自動的にコロンで分割されてリストになります. これらはサブコマンドに渡されるときにコロンによって結合されます. この仕様は$PATHはコロンで区切られていると想定している他のツールとの互換性のためにあります. 明示的にパスを変数に加えるにはset --path, 削除するにはset --unpathを用いることができます.

リストは要素として他のリストを保持することはできず, 再帰的ではありません. 変数は文字列のリストであり, 他にはありえません

リストの要素数を得るにはcountコマンドを使います.

>_ count $PATH
5

リスト自身に追加の引数をセットすることで, 要素を追加することができます. $PATH/usr/local/binを追加する例を示します.

>_ set PATH $PATH /usr/local/bin

[]を用いることで個別の要素にアクセスすることができます. インデックスは1から始まり, 最後は-1です.

>_ echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
>_ echo $PATH[1]
/usr/bin
>_ echo $PATH[-1]
/usr/local/bin

"スライス"を用いてある範囲の要素にアクセスすることもできます.

>_ echo $PATH[1..2]
/usr/bin /bin
>_ echo $PATH[-1..2]
/usr/local/bin /sbin /usr/sbin /bin

forループを用いてリスト全体(或いはスライス)に繰り返しアクセスすることもできます.

>_ for val in $PATH
     echo "entry: $val"
   end
entry: /usr/bin/
entry: /bin
entry: /usr/sbin
entry: /sbin
entry: /usr/local/bin

他のリストや文字列と隣り合ったリストは, クオートで囲まなければ直積となります. ([直積], [変数展開] 参照)

>_ set a 1 2 3
>_ set 1 a b c
>_ echo $a$1
1a 2a 3a 1b 2b 3b 1c 2c 3c
>_ echo $a" banana"
1 banana 2 banana 3 banana
>_ echo "$a banana"
1 2 3 banana

これは[ブレース展開]と似た作用です.

コマンド置換

コマンド置換は1つのコマンドの実行結果を他のコマンドの引数として渡す際に使われます. 他のシェルと違って, fish``ではなく()を用います.

>_ echo In (pwd), running (uname)
In /home/tutorial, running FreeBSD

コマンドの結果を変数に代入するときによく使われます.

>_ set os (uname)
>_ echo $os
Linux

コマンド置換はクオートによって展開されません. その代わり一度クオートを閉じ, コマンド置換を行いそれから再びクオートを開くことによって実現できます.

>_ touch "testing_"(date +%s)".txt"
>_ ls *.txt
testing_1360099791.txt

他のシェルと違って, fishは(スペースやタブのような)いかなる空白文字であっても 分割されることはなく, 改行によってのみ分割されます. これはpkg-configのような複数の引数を1行に出力するコマンドを使う際に問題となります. スペースでも分割できるようにするためにはstring splitを用いてください.

>_ printf '%s\n' (pkg-config --libs gio-2.0)
-lgio-2.0 -lgobject-2.0 -lglib-2.0
>_ printf '%s\n' (pkg-config --libs gio-2.0 | string split " ")
-lgio-2.0
-lgobject-2.0
-lglib-2.0

セパレートコマンド(;)

他のシェルと違って, fishは複数のコマンドを独立した行に書くことも同一の行に書くことも許容されます.

ワンライナーで書く場合, ;を用います. 以下の2つの例が等価であることを確認してください.

echo fish; echo chips

# or
echo fish
echo chips

コンバイナ(and, or, not)

fishは馴染みのある&&||, それから否定の!をサポートしています.

>_ ./configure && make && sudo make install

さらにfishand, ornotも同様にサポートしています. 最初の2つはコマンドの修飾子で, 優先順位は低くなっています. 以下に例を挙げます.

>_ cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt ; and echo "Backup successful"; or echo "Backup failed"
Backup failed

セパレートコマンド(;)の項で触れたように複数行にわたって 書くこともできます.

cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt
and echo "Backup successful"
or echo "Backup failed"

条件式(if, else, switch)

if, else ifそれからelseを使うことでコマンドの終了ステータスによって 実行するコードを条件分岐することができます.

if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
else
    echo Got nothing
end

文字列や数字の比較, ファイルのプロパティ(ファイルが存在するか, 書き込み可能かなど)を確認する場合には次のように[testコマンド]を利用してください.

if test "$fish" = "flounder"
    echo FLOUNDER
end

# or

if test "$number" -gt 5
    echo $number is greater than five
else
    echo $number is five or less
end

コンバイナを使うことでさらに複雑な条件式がかけるようになります.

if grep fish /etc/shells; and command -sq fish
    echo fish is installed and configured
end

もっと複雑になったときにはbeginendを使ってグループ化してください.

また, switchコマンドもあります.

switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!
end

caseはフォールスルーせず, さらに複数の引数やクオートで囲まれたワイルドカードを受け付けることに注意してください.

関数

fishの関数はコマンドのリストであり, オプションとして引数をとることができます. 他のシェルと違って, 引数は$1のような"数字変数"ではなく,$argvという一つのリストとして渡されます. 関数を作るためにビルトインのfunctionコマンドを用います.

>_ function say_hello
     echo Hello $argv
   end
>_ say_hello
Hello
>_ say_hello everybody!
Hello everybody!

他のシェルと違って, fishはエイリアスや特殊なプロンプト構文を持ちません. これらも関数で表現します.

functionsキーワードによって全ての関数名を列挙することができます. (複数形であることに注意!) fishにははじめから数多くの関数が定義されています.

>_ functions
alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, trap, type, umask, up-or-search, vared

functionsに関数名を渡すことでその関数の中身をみることもできます.

>_ functions ls
function ls --description 'List contents of directory'
    command ls -G $argv
end

ループ

Whileループは次のように使えます.

>_ while true
     echo "Loop forever"
end
Loop forever
Loop forever
Loop forever
...

Forループはリスト全体を処理することができます.

>_ for file in *.txt
     cp $file $file.bak
   end

seqコマンドを用いることで数列でループすることができます.

>_ for x in (seq 5)
     touch file_$x.txt
   end

プロンプト

他のシェルと違って, PS1のようなプロンプト変数はありません. プロンプトを表示するために, fishfish_promptという名前の関数を実行し, その出力がプロンプトとして用いられます.

次のように独自のプロンプトを定義することができます.

>_ function fish_prompt
     echo "New Prompt % "
   end
New Prompt %

複数行のプロンプトも可能です. 色はset_colorコマンドにANSI colorsか16進数のRGB値を渡すことによって設定できます.

>_ function fish_prompt
     set_color purple
     date "+%m/%d/%y"
     set_color FF0
     echo (pwd) '>'
     set_color normal
   end
<span style="color: purple">02/06/13</span>
<span style="color: #FF0">/home/tutorial ></span>___

fish_config_prompt関数を実行することでサンプルの中からプロンプトを選ぶことができます. また, fishfish_right_prompt関数によって右プロンプトもサポートしています.

PATH変数

$PATHは環境変数で, fishがコマンドを探索するディレクトリを保持しています. 他のシェルと違って, $PATHリストであり, コロンで区切られた文字列ではありません.

/usr/local/bin/usr/sbin$PATHに追加するためには次のように書きます.

>_ set PATH /usr/local/bin /usr/sbin $PATH

$PATHから/usr/local/binを削除するには次のようにします.

>_ set PATH (string match -v /usr/local/bin $PATH)

また, 他のシェルの.profileのようにconfig.fishを直接編集しても構いません.

より早い方法として$fish_user_pathsという[ユニバーサル変数]を設定すると良いでしょう. これは自動的に$PATHに追加されます. 例えば, $PATHに永続的に/usr/local/binを追加したい場合, 次のようにしてください.

>_ set -U fish_user_paths /usr/local/bin $fish_user_paths

この方法の利点は設定ファイルを汚さなくてよいところです. 一度コマンドラインで実行さえすれば現在のセッションから永久的にパスが有効になります. (注意: これをconfig.fishに書き加えないでください. もしそうした場合, fishを起動するたびに変数に追加されて長くなっていってしまいます!)

起動に際して(.bashrc)

fish~/.config/fish/config.fishに書かれたコマンドを起動時に実行します. もしこのファイルがなかったら新たに作ることができます.

次のようなコマンドを用いる事でconfig.fishに直接関数や変数を定義することができます.

>_ cat ~/.config/fish/config.fish

set -x PATH $PATH /sbin/

function ll
    ls -lh $argv
end

しかし, オートロード関数やユニバーサル変数を使うのが一般的で効果的です.

オートロード関数

fishがコマンドを認識したとき, ~/.config/fish/functions/からそのコマンドを探し, オートロード関数として呼び出そうとします.

例えばllという関数が欲しければ, ll.fishというテキストファイルを~/.config/fish/functions/に追加します.

>_ cat ~/.config/fish/functions/ll.fish
function ll
    ls -lh $argv
end

同様に独自プロンプトを次のように定義するのがより良い方法です.

>_ cat ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
    echo (pwd) "> "
end

こうしたファイルを自動的に作る方法として[funced], [funcsave]を参考にしてください.

ユニバーサル変数

ユニバーサル変数はfishの全てのインスタンスで値が共有される変数で, 現在立ち上げているインスタンスだけでなくリブートした後でさえ継続します. set -Uのオプションを用いることでユニバーサル変数を設定することができます.

>_ set -U EDITOR vim

上記コマンドを実行した後, 他のインスタンスにも引き継がれます.

>_ echo $EDITOR
vim

fishをデフォルトシェルにする

fish(或いはその他のシェル)をデフォルトシェルとして使いたい場合, fishの実行ファイル/usr/local/bin/fish/etc/shellsにも置く必要があります. それからchsh -s /usr/local/bin/fishでデフォルトシェルに変更することができます.

具体的には次のコマンドに従ってください.

fishを/etc/shellsに追加する.

> echo /usr/local/bin/fish | sudo tee -a /etc/shells

デフォルトシェルをfishに変える.

> chsh -s /usr/local/bin/fish

(他のシェルに戻すには上記コマンドの引数/usr/local/bin/fish/bin/bash, /bin/tcsh/bin/zshに置き換えてください.)

より多くを知るには

もっとfishについて知りたければより詳しい[ドキュメント]や 公式メーリングリスト, irc.oftc.netのIRCチャンネル#fish, github pageを参照してください.

なぜfishなのか?

fishはbashやzshのように完備で, 気の利いたユーザーフレンドリーなコマンドラインシェルです. fishはシンタックスハイライト, オートサジェスト, タブ補完といった強力な機能を学習したり 設定をいじったりすることなく利用することができます.

コマンドラインを難しい構文を覚えたり設定ファイルを書いたりすることなくもっと生産的に, 便利に, 楽しくしたいならfishこそが探し求めていたものになるでしょう!

はじめかた

一度インストールしてしまえば今使っているシェルでfishとタイプするだけで試してみることができます!

起動するとfishのプロンプトが表示されます. これはもう準備ができていてfishを始めることができることを意味しています.

> fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
you@hostname ~>____

このプロンプトはfishのデフォルトのプロンプトで, あなたのユーザーネーム, ホストネーム, それからワーキングディレクトリを表示しています.

  • プロンプトを変えるためには[プロンプトの変えかた]
  • fishをログインシェルにするには[デフォルトシェルをfishに変える]

を読んでください.

以降, プロンプトは簡単のため'>_'で表します.

fishを学ぶ

このチュートリアルではコマンドラインシェルとUnixコマンドの基本的な理解と, fishが動く環境を前提としています.

もし他のシェルのことをよく知っていて, fishがそれとどう異なるのかを知りたい場合は他のシェルと違ってというフレーズを検索してください. これは重要な違いを示す時に使われています.

コマンドの実行

fishは他のシェルと同じように, コマンドに続けて引数を与えることで実行します. スペースはセパレータとなっています.

>_ echo hello world
hello world

空白文字として引数を与えたい場合, バックスラッシュを前置するか或いはシングルクオート, ダブルクオートで囲むことによって実現します.

>_ mkdir My\ Files
>_ cp ~/Some\ File 'My Files'
>_ ls "My Files"
Some File

コマンドはセミコロンを用いることによって繋げることができます.

ヘルプを読む

fishには素晴らしいhelpとmanページが備わっています. helpコマンドを実行するとウェブブラウザでヘルプを開き, manコマンドはターミナル上でmanページを開きます. 特定のコマンドについてのヘルプを読むこともでき, 例えばhelp setとすればウェブブラウザで, mans setとすればターミナルで読むことができます.

>_ man set
set - handle shell variables
  Synopsis...

シンタックスハイライト

fishを使っているとタイプするに従ってシンタックスハイライトが効いていることに すぐに気がつくでしょう. 無効なコマンドはデフォルトでは赤く表示されます.

>_ <eror>/bin/mkd</eror>

コマンドが存在しない或いは実行可能でない場合に無効となり, 有効になると色が変化します.

>_ /bin/mkdir

fishはファイルパスが有効なとき下線を示すでしょう.

>_ cat <u>~/somefi</u>___

これは'somefi'から始まるファイルが存在していることを示していて, タイピングの補助となります.

これらのシンタックスハイライトは他にもたくさんありますが, fish_configを変更したり 変数を直接編集することによって色を変えることができます.

ワイルドカード

fishはワイルドカードの*をサポートしています. 全てのJPEGファイルをリストアップするには次のようにします.

>_ ls *.jpg
lena.jpg
meena.jpg
santa maria.jpg

複数のワイルドカードを用いることもできます.

>_ ls l*.p*
lena.png
lesson.pdf

特に強力なのはディレクトリを再帰的に探索する**です.

>_ ls /var/**.log
/var/log/system.log
/var/run/sntp.log

ディレクトリの探査に時間がかかるときはCtrl-cで中止することができます.

パイプとリダイレクト

|を用いることでコマンドをパイプすることができます.

>_ echo hello world | wc
       1       2      12

stdinとstdoutは馴染み深い<>によってリダイレクトすることができます. stderrは2>によってリダイレクトされます.

>_ grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt

オートサジェスト

fishはタイプに従ってコマンドをサジェストします. サジェストされた結果はカーソルの右側に灰色で示されます.

>_ <eror>/bin/h</eror><s>___ostname</s>

パスやオプションをサジェストすることもできます.

>_ grep --i<s>___gnore-case</s>

もちろん履歴にもはたらきます. 一度コマンドを実行したことがあれば, 数文字タイプしただけで再度 実行することができます.

>_ <eror>r<</eror><s>___sync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo</s>

サジェストの結果を利用するにはまたはCtrl-fを押してください. 最初の1語だけを利用したい場合はAlt-→を押してください. また, サジェストが求めているものと異なればそのまま無視して構いません.

タブ補完

fishはすぐに使えるリッチなタブ補完を備えています. tabを押してみると, fishはコマンドや引数, パスを補完しようとするでしょう.

>_ <eror>/pri</eror> :kbd:`Tab` => /private

複数の候補が見つかれば, それらをリストとして表示します.

>_ <eror>~/stuff/s</eror> :kbd:`Tab`
<mtch>~/stuff/script.sh  <i>(Executable, 4.8kB)</i>  \mtch{~/stuff/s</mtch>ources/  <i>(Directory)</i>}

tabを押すたびにその候補を順にフォーカスします.

fishはgitのブランチのようなものまでも補完することができます.

>_ git merge pr :kbd:`Tab` => git merge prompt_designer
>_ git checkout b :kbd:`Tab`
<mtch>builtin_list_io_merge <i>(Branch)</i> \mtch{b</mtch>uiltin_set_color <i>(Branch)</i> <mtch>b</mtch>usted_events <i>(Tag)</i>}

実際にtabを押して確認してみましょう!

変数

他のシェルと同じように, $によって変数を扱います.

>_ echo My home directory is $HOME
My home directory is /home/tutorial

変数はダブルクオートのなかでは置換されますが, シングルクオートの中では置換されません.

>_ echo "My current directory is $PWD"
My current directory is /home/tutorial
>_ echo 'My current directory is $PWD'
My current directory is $PWD

他のシェルと違って, fishは変数を代入する構文を持ちません. 代わりに変数名とその値を引数にとる, setコマンドを持ちます.

>_ set name 'Mister Noodle'
>_ echo $name
Mister Noodle

(クオートに注意してください. もしこれがなければMisterNoodleは別々の引数として認識され, $nameは2つの要素を持つリストになります.)

他のシェルと違って, 変数は置換後に分割されることはありません.

>_ mkdir $name
>_ ls
Mister Noodle

bashでは上記コマンドで"Mister"と"Noodle"という2つのディレクトリが作られます. fishでは"Mister Noodle"という値を持った変数によって1つのディレクトリが作られます. つまりmkdirにはスペースを含んだ文字列の引数として渡されます. 他のシェルではリストという表現ではなく"配列"という用語が用いられます.

終了ステータス

他のシェルと違って, fishは直前に実行したコマンドの終了ステータスを$?ではなく$statusという変数に格納します.

>_ false
>_ echo $status
1

0は成功, それ以外はエラーを表します. $pipestatusというパイプの過程の終了ステータスを格納する配列の変数もあります.

エクスポート(シェル変数)

他のシェルと違って, fishexportコマンドをサポートしていません. 代わりにsetコマンドの--export或いは-xオプションによって変数をエクスポートします.

>_ set -x MyVariable SomeValue
>_ env | grep MyVariable
MyVariable=SomeValue

変数は-e若しくは--eraseオプションによって削除することができます.

>_ set -e MyVariable
>_ env | grep MyVariable
(no output)

リスト

先に見たsetコマンドはクオートで囲むことによってMister Noodleを1つの引数として扱いました. もし2つの引数だったなら, 変数nameは長さ2のリストになります. 実際, fishの全ての変数はリストであり, いくつでも値を保持できるし全く持たないことも可能です.

$PWDのようないくつかの変数は1つしか値を持ちません. 慣習に従って変数の値というとき, 最初(かつただ1つ)の値を指すことにします.

$PATHのようなその他の変数は複数の値を保持しています. これらの変数は複数の引数として展開されます.

>_ echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin

"PATH"で終わる変数は自動的にコロンで分割されてリストになります. これらはサブコマンドに渡されるときにコロンによって結合されます. この仕様は$PATHはコロンで区切られていると想定している他のツールとの互換性のためにあります. 明示的にパスを変数に加えるにはset --path, 削除するにはset --unpathを用いることができます.

リストは要素として他のリストを保持することはできず, 再帰的ではありません. 変数は文字列のリストであり, 他にはありえません

リストの要素数を得るにはcountコマンドを使います.

>_ count $PATH
5

リスト自身に追加の引数をセットすることで, 要素を追加することができます. $PATH/usr/local/binを追加する例を示します.

>_ set PATH $PATH /usr/local/bin

[]を用いることで個別の要素にアクセスすることができます. インデックスは1から始まり, 最後は-1です.

>_ echo $PATH
/usr/bin /bin /usr/sbin /sbin /usr/local/bin
>_ echo $PATH[1]
/usr/bin
>_ echo $PATH[-1]
/usr/local/bin

"スライス"を用いてある範囲の要素にアクセスすることもできます.

>_ echo $PATH[1..2]
/usr/bin /bin
>_ echo $PATH[-1..2]
/usr/local/bin /sbin /usr/sbin /bin

forループを用いてリスト全体(或いはスライス)に繰り返しアクセスすることもできます.

>_ for val in $PATH
     echo "entry: $val"
   end
entry: /usr/bin/
entry: /bin
entry: /usr/sbin
entry: /sbin
entry: /usr/local/bin

他のリストや文字列と隣り合ったリストは, クオートで囲まなければ直積となります. ([直積], [変数展開] 参照)

>_ set a 1 2 3
>_ set 1 a b c
>_ echo $a$1
1a 2a 3a 1b 2b 3b 1c 2c 3c
>_ echo $a" banana"
1 banana 2 banana 3 banana
>_ echo "$a banana"
1 2 3 banana

これは[ブレース展開]と似た作用です.

コマンド置換

コマンド置換は1つのコマンドの実行結果を他のコマンドの引数として渡す際に使われます. 他のシェルと違って, fish``ではなく()を用います.

>_ echo In (pwd), running (uname)
In /home/tutorial, running FreeBSD

コマンドの結果を変数に代入するときによく使われます.

>_ set os (uname)
>_ echo $os
Linux

コマンド置換はクオートによって展開されません. その代わり一度クオートを閉じ, コマンド置換を行いそれから再びクオートを開くことによって実現できます.

>_ touch "testing_"(date +%s)".txt"
>_ ls *.txt
testing_1360099791.txt

他のシェルと違って, fishは(スペースやタブのような)いかなる空白文字であっても 分割されることはなく, 改行によってのみ分割されます. これはpkg-configのような複数の引数を1行に出力するコマンドを使う際に問題となります. スペースでも分割できるようにするためにはstring splitを用いてください.

>_ printf '%s\n' (pkg-config --libs gio-2.0)
-lgio-2.0 -lgobject-2.0 -lglib-2.0
>_ printf '%s\n' (pkg-config --libs gio-2.0 | string split " ")
-lgio-2.0
-lgobject-2.0
-lglib-2.0

セパレートコマンド(;)

他のシェルと違って, fishは複数のコマンドを独立した行に書くことも同一の行に書くことも許容されます.

ワンライナーで書く場合, ;を用います. 以下の2つの例が等価であることを確認してください.

echo fish; echo chips

# or
echo fish
echo chips

コンバイナ(and, or, not)

fishは馴染みのある&&||, それから否定の!をサポートしています.

>_ ./configure && make && sudo make install

さらにfishand, ornotも同様にサポートしています. 最初の2つはコマンドの修飾子で, 優先順位は低くなっています. 以下に例を挙げます.

>_ cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt ; and echo "Backup successful"; or echo "Backup failed"
Backup failed

セパレートコマンド(;)の項で触れたように複数行にわたって 書くこともできます.

cp file1.txt file1_bak.txt && cp file2.txt file2_bak.txt
and echo "Backup successful"
or echo "Backup failed"

条件式(if, else, switch)

if, else ifそれからelseを使うことでコマンドの終了ステータスによって 実行するコードを条件分岐することができます.

if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
else
    echo Got nothing
end

文字列や数字の比較, ファイルのプロパティ(ファイルが存在するか, 書き込み可能かなど)を確認する場合には次のように[testコマンド]を利用してください.

if test "$fish" = "flounder"
    echo FLOUNDER
end

# or

if test "$number" -gt 5
    echo $number is greater than five
else
    echo $number is five or less
end

コンバイナを使うことでさらに複雑な条件式がかけるようになります.

if grep fish /etc/shells; and command -sq fish
    echo fish is installed and configured
end

もっと複雑になったときにはbeginendを使ってグループ化してください.

また, switchコマンドもあります.

switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!
end

caseはフォールスルーせず, さらに複数の引数やクオートで囲まれたワイルドカードを受け付けることに注意してください.

関数

fishの関数はコマンドのリストであり, オプションとして引数をとることができます. 他のシェルと違って, 引数は$1のような"数字変数"ではなく,$argvという一つのリストとして渡されます. 関数を作るためにビルトインのfunctionコマンドを用います.

>_ function say_hello
     echo Hello $argv
   end
>_ say_hello
Hello
>_ say_hello everybody!
Hello everybody!

他のシェルと違って, fishはエイリアスや特殊なプロンプト構文を持ちません. これらも関数で表現します.

functionsキーワードによって全ての関数名を列挙することができます. (複数形であることに注意!) fishにははじめから数多くの関数が定義されています.

>_ functions
alias, cd, delete-or-exit, dirh, dirs, down-or-search, eval, export, fish_command_not_found_setup, fish_config, fish_default_key_bindings, fish_prompt, fish_right_prompt, fish_sigtrap_handler, fish_update_completions, funced, funcsave, grep, help, history, isatty, ls, man, math, nextd, nextd-or-forward-word, open, popd, prevd, prevd-or-backward-word, prompt_pwd, psub, pushd, seq, setenv, trap, type, umask, up-or-search, vared

functionsに関数名を渡すことでその関数の中身をみることもできます.

>_ functions ls
function ls --description 'List contents of directory'
    command ls -G $argv
end

ループ

Whileループは次のように使えます.

>_ while true
     echo "Loop forever"
end
Loop forever
Loop forever
Loop forever
...

Forループはリスト全体を処理することができます.

>_ for file in *.txt
     cp $file $file.bak
   end

seqコマンドを用いることで数列でループすることができます.

>_ for x in (seq 5)
     touch file_$x.txt
   end

プロンプト

他のシェルと違って, PS1のようなプロンプト変数はありません. プロンプトを表示するために, fishfish_promptという名前の関数を実行し, その出力がプロンプトとして用いられます.

次のように独自のプロンプトを定義することができます.

>_ function fish_prompt
     echo "New Prompt % "
   end
New Prompt %

複数行のプロンプトも可能です. 色はset_colorコマンドにANSI colorsか16進数のRGB値を渡すことによって設定できます.

>_ function fish_prompt
     set_color purple
     date "+%m/%d/%y"
     set_color FF0
     echo (pwd) '>'
     set_color normal
   end
<span style="color: purple">02/06/13</span>
<span style="color: #FF0">/home/tutorial ></span>___

fish_config_prompt関数を実行することでサンプルの中からプロンプトを選ぶことができます. また, fishfish_right_prompt関数によって右プロンプトもサポートしています.

PATH変数

$PATHは環境変数で, fishがコマンドを探索するディレクトリを保持しています. 他のシェルと違って, $PATHリストであり, コロンで区切られた文字列ではありません.

/usr/local/bin/usr/sbin$PATHに追加するためには次のように書きます.

>_ set PATH /usr/local/bin /usr/sbin $PATH

$PATHから/usr/local/binを削除するには次のようにします.

>_ set PATH (string match -v /usr/local/bin $PATH)

また, 他のシェルの.profileのようにconfig.fishを直接編集しても構いません.

より早い方法として$fish_user_pathsという[ユニバーサル変数]を設定すると良いでしょう. これは自動的に$PATHに追加されます. 例えば, $PATHに永続的に/usr/local/binを追加したい場合, 次のようにしてください.

>_ set -U fish_user_paths /usr/local/bin $fish_user_paths

この方法の利点は設定ファイルを汚さなくてよいところです. 一度コマンドラインで実行さえすれば現在のセッションから永久的にパスが有効になります. (注意: これをconfig.fishに書き加えないでください. もしそうした場合, fishを起動するたびに変数に追加されて長くなっていってしまいます!)

起動に際して(.bashrc)

fish~/.config/fish/config.fishに書かれたコマンドを起動時に実行します. もしこのファイルがなかったら新たに作ることができます.

次のようなコマンドを用いる事でconfig.fishに直接関数や変数を定義することができます.

>_ cat ~/.config/fish/config.fish

set -x PATH $PATH /sbin/

function ll
    ls -lh $argv
end

しかし, オートロード関数やユニバーサル変数を使うのが一般的で効果的です.

オートロード関数

fishがコマンドを認識したとき, ~/.config/fish/functions/からそのコマンドを探し, オートロード関数として呼び出そうとします.

例えばllという関数が欲しければ, ll.fishというテキストファイルを~/.config/fish/functions/に追加します.

>_ cat ~/.config/fish/functions/ll.fish
function ll
    ls -lh $argv
end

同様に独自プロンプトを次のように定義するのがより良い方法です.

>_ cat ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
    echo (pwd) "> "
end

こうしたファイルを自動的に作る方法として[funced], [funcsave]を参考にしてください.

ユニバーサル変数

ユニバーサル変数はfishの全てのインスタンスで値が共有される変数で, 現在立ち上げているインスタンスだけでなくリブートした後でさえ継続します. set -Uのオプションを用いることでユニバーサル変数を設定することができます.

>_ set -U EDITOR vim

上記コマンドを実行した後, 他のインスタンスにも引き継がれます.

>_ echo $EDITOR
vim

fishをデフォルトシェルにする

fish(或いはその他のシェル)をデフォルトシェルとして使いたい場合, fishの実行ファイル/usr/local/bin/fish/etc/shellsにも置く必要があります. それからchsh -s /usr/local/bin/fishでデフォルトシェルに変更することができます.

具体的には次のコマンドに従ってください.

fishを/etc/shellsに追加する.

> echo /usr/local/bin/fish | sudo tee -a /etc/shells

デフォルトシェルをfishに変える.

> chsh -s /usr/local/bin/fish

(他のシェルに戻すには上記コマンドの引数/usr/local/bin/fish/bin/bash, /bin/tcsh/bin/zshに置き換えてください.)

より多くを知るには

もっとfishについて知りたければより詳しい[ドキュメント]や 公式メーリングリスト, irc.oftc.netのIRCチャンネル#fish, github pageを参照してください.

よくある質問

環境変数の追加, 削除をするには?

[set]コマンドを使ってください.

set -x key value
set -e key

ログイン時にコマンドを実行するには? fishの.bashrcは?

~/.config/fish/config.fishを編集してください. もし存在しなければ作成することもできます.

独自のプロンプトを設定するには?

プロンプトはfish_prompt関数の出力になります. この関数は~/.config/fish/functions/fish_prompt.fishに配置してください. 簡単な例を下に示します.

function fish_prompt
    set_color $fish_color_cwd
    echo -n (prompt_pwd)
    set_color normal
    echo -n ' > '
end

Web上の設定ツール, [fish_config]を使うこともできます. プロンプトのサンプルから選んで試すことができます.

履歴からコマンドを実行するには?

コマンドの一部を入力し, それから(up)或いは(down)を押してください. マッチした履歴を選択することができます.

サブコマンドを実行するには? バッククオートが動作しません!

fishはサブコマンドを実行するために()を使います.

for i in (ls)
    echo $i
end

pkg-configのような出力が1行の長い文字列のときどうしたらいい?

他のシェルと違って, fishは改行時のみ置換されたコマンドを分割します. スペースやタブ, $IFSに含まれる文字では分割されません.

これは次のことを意味します.

echo x(printf '%s ' a b c)x

を実行するとxa b c xが出力されます. しかし次の場合,

echo x(printf '%s\n' a b c)x

xax xbx xcxが出力されます.

ほぼ全てのケースにおいてスペース区切りは望ましくないので, この仕様は改善点であるといえます.

しかしながら, pkg-configやその周辺ツールなどではスペース区切りが必要となっています. このような場合, string split " "を使ってください.

g++ example_01.cpp (pkg-config --cflags --libs gtk+-2.0 | string split " ")

コマンドの終了ステータスを得るには?

$status変数を使ってください. これは他のシェルで使われている$?変数を置き換えるものです.

somecommand
if test $status -eq 7
    echo "That's my lucky number!"
end

もし単に成功か失敗かを知りたいだけなら, ifのような条件構文に直接渡してください.

if somecommand
    echo "Command succeeded"
else
    echo "Command failed"
end

より詳しくは[test]コマンドや[if]コマンドを参照してください.

一回限りの環境変数を設定するには?

SOME_VAR=1 commandというコマンドは次のエラーを引き起こします. Unknown command "SOME_VAR=1"

このようなときにはenvコマンドを使ってください.

env SOME_VAR=1 command

ブロック中で次のようにローカル変数を宣言することもできます.

begin
    set -lx SOME_VAR 1
    command
end

変数が定義されるているか確認するには?

set -q varコマンドを使ってください.

例えばif set -q --$var; echo variable defined; endのように使います;

複数の変数を確認するには'andorの演算子を使ってください.

if set -q var1; or set -q var2
    echo either variable defined
end

定義済みの変数は空である可能性もあることに注意してください. 次の2つのコマンドで空の変数を定義できます. set var set var ""

変数が空でないか確認するには?

string length -q -- $varを使ってください. 例えばif string length -q -- $var; echo not empty; endのように使います.

string lengthは複数の引数のリストを個別にチェックし, 1つでも空でなければ0を返します.

if string length -q -- $var1 $var2 $var3
    echo at least one of these variables is not empty
end

代わりにtest -n "$var"を使ってください. ただしダブルクオートで変数を括ることを忘れないでください. 例えばif test -n "$var"; echo not empty; endのように使います. testコマンドはオプションとして-a(and)と-o(or)を持ちます.

if test -n "$var1" -o -n "$var2" -o -n "$var3"
    echo at least one of these variables is not empty
end

set -Ux(ユニバーサル変数のエクスポート)が働かない?

既に同じ名前のグローバル変数が設定されています.

EDITORTZといった環境変数はset -Uxによってユニバーサルに設定できます. しかし, fishが起動する前に既に環境変数が設定されている場合(ログインスクリプトやシステムの管理者によって), それはグローバル変数として設定されます. [変数スコープ]は"inside out"の検索方式をとっていて, ローカル変数, グローバル変数それからユニバーサル変数の順に変数を確認していきます.

これはグローバル変数の方がユニバーサール変数よりも優先順位が高いことを意味しています.

この問題を避けるために, fishの継承の設定を変えることが考えられます. これが不可能なら, 次のような設定を[設定ファイル] (大抵の場合, ~/.config/fish/config.fish)に記述してください.

set -gx EDITOR vim

シンタックスハイライトの色を変えるには?

ウェブの設定ツールの[fish_config], 若しくは環境変数の[fish_color]を変更してください.

manページの補完をアップデートするには?

[fish_update_completions]コマンドを使ってください.

間違ってディレクトリのパスを打ってEnter押したらディレクトリが移動してしまいました. 何が起きたの?

fishは与えられたコマンドが存在しなくて, かつ./, ~から始まる場合, その名前のディレクトリが存在しないか確認します. 存在すればディレクトリを移動したいのだと暗黙的に推定して実行します. 例えばホームディレクトリに移動する最速の方法は単に~と打ってEnterを押すだけです.

オープンコマンドが働きません

openコマンドはMIMEデータベースとGnomeやKDEが用いるファイルタイプによってデフォルトの動作を規定する, .desktopファイルを用います. これらの環境が少なくとも1つでも存在するにも関わらずopenコマンドが動作しない場合, これらに関係するファイルが標準的な場所にインストールされていないかもしれません. [困ったときには]も参照ください.

fishをデフォルトシェルにするには?

パッケージマネージャを使わずにコンパイルしてfishをインストールした場合, まず以下のコマンドによってfishをシェルのリストに追加する必要があります. (ただし, fishが/usr/localにインストールされていると仮定します.)

echo /usr/local/bin/fish | sudo tee -a /etc/shells

パッケージマネージャを使ってインストールした場合は既にこの操作は行われています.

デフォルトシェルにするには次のコマンドを打ってください.

chsh -s /usr/local/bin/fish

上記のパスは/usr/bin/fishのように変更する必要があるかもしれません. fishがどこにインストールされているかわからない場合はwhich fishコマンドで確認してください.

残念なことに変更をすぐに反映することはできないので, 一度ログアウトしてから再ログインしてください.

screenを使ってるとき, プロンプトの前に変な出力がでます

手っ取り早い解決策はこちらです.

次のコマンドをfish上で実行してください.

function fish_title; end; funcsave fish_title

これで解決するはずです.

さらに何が起こっているか説明します.

fishはターミナルにタイトルバーメッセージを設定します. screenがこの機能をサポートしており, ターミナルがサポートしていない場合, screenはエスケープコードを出力しターミナルはそれを無視することなくテキストとして表示してしまいます. fishはターミナルの種類がなんであるか判別する方法を持たないので, fish側からこの問題を解決することはできません. したがって, 上記のようにタイトルバーメッセージを空にするしか方法がありません.

fishはデフォルトのタイトルバーメッセージを持っていて, それはfish_title関数が未定義のときに使われることに注意してください. そのため単純にfish_title関数を削除してもうまくいきません.

グリーティングメッセージを変更するには?

fish_greeting変数の値を変更するか, 或いはfish_greeting関数を作成してください. 例えばグリーティングをなくすには次のようにします.

set fish_greeting

履歴置換(!$など)が働かないのはなぜ?

履歴置換は対話形式の編集が可能になる前に開発された行儀の悪いインターフェースであるからです. fishはこのインターフェースを無くし, 代わりに完全な対話形式の履歴想起インターフェースを持ちます. これまでの習慣を少し変える必要があります. 古い行や単語を修正したいときにはまずそれを思い出してそれから編集してください. 例えばsudo !!とは打たないでください. まずUpキーを押してそれからHome, 最後にsudoと打ってください.

fishの履歴想起は以下のようにとてもシンプルかつ効率的です.

  • 他のモダンなシェル同様, は最後に実行した行から順に行全体を呼び出します. 一回押すと!!を置き換え, !-3などを置き換えたい場合には次のようにしてください.

    • ずっと前の履歴を呼び出したいとき, そのコマンドの一部を打ってからを一回或いは複数回押してください. こうすることでその文字列を含んだコマンドに絞って呼び出すことができ, 必要な行をより早く手に入れることができます. これは!vi!?bar.cなどの代わりになります.
  • Alt+↑, Upは直近に実行した行から順番に引数のみを呼び出します. 一回押すと!$を置き換え, !!:4などを置き換えたい場合は次のようにしてください.

    • 使いたい引数が履歴のずっと前にある場合, 引数の一部を打ってからAlt+↑, Upを押してください. こうすることでその文字列を含んだ引数に絞って呼び出すことができ, 必要な行をより早く手に入れることができます. 試してみるととても便利なことがわかるでしょう.
    • 同一の行から複数の引数を再利用したい場合(!!:3*のように), 全体を呼び出した後必要ない部分を削除するといいでしょう. (Alt+DAlt+Backspaceを用いると手早く済みます.)

fishでの行の編集について, 詳細は[ドキュメント]を参照してください.

-cd -のショートカットとして使うには?

2.5.0より前のfishではcd -という動作をする-関数を定義することが可能でした. いくつかのバグフィクスを含んだ2.5.0のリリースによって単なる-は無効な関数(変数も同様)となりました. しかしアブリビエーションを使うことによって同様の操作を行うことができます.

abbr -a -- - 'cd -'

アンインストールするには?

万が一fishをアンインストールしたくなった場合, まずデフォルトシェルに設定されていないことを確認してください. もしそうであればchsh -s /bin/bashで変更してください.

次に以下の操作をしてください. (/usr/localにfishがインストールされていると想定しています.)

rm -Rf /usr/local/etc/fish /usr/local/share/fish ~/.config/fish
rm /usr/local/share/man/man1/fish*.1
cd /usr/local/bin
rm -f fish fish_indent

fishのUnicode private-use charactersについて

fishはU+F600からU+F73Fの Unicode private-use character を内部的に使用しています. この範囲の文字を使用した場合, Unicodeの'replacement character', U+FFFDに変換されます. これにはインタラクティブな入力とファイルによる入力が含まれます. (ただし実行されるプログラムには関係しません.)

fishの拡張機能を探すには?

fishのユーザーコミュニティがfishにバンドルされるほど汎用的ではないが便利で素晴らしいスクリプトを公開しています. プロンプトやテーマ, 便利な関数を含む, こうした拡張機能をいくつかのサードパーティのリポジトリから手に入れることができます.

これは全てのリポジトリを網羅したものではなく, fishプロジェクトとして上記のリポジトリのメリットや含まれるスクリプトについて何か意見するわけではありません.

環境変数の追加, 削除をするには?

[set]コマンドを使ってください.

set -x key value
set -e key

ログイン時にコマンドを実行するには? fishの.bashrcは?

~/.config/fish/config.fishを編集してください. もし存在しなければ作成することもできます.

独自のプロンプトを設定するには?

プロンプトはfish_prompt関数の出力になります. この関数は~/.config/fish/functions/fish_prompt.fishに配置してください. 簡単な例を下に示します.

function fish_prompt
    set_color $fish_color_cwd
    echo -n (prompt_pwd)
    set_color normal
    echo -n ' > '
end

Web上の設定ツール, [fish_config]を使うこともできます. プロンプトのサンプルから選んで試すことができます.

履歴からコマンドを実行するには?

コマンドの一部を入力し, それから(up)或いは(down)を押してください. マッチした履歴を選択することができます.

サブコマンドを実行するには? バッククオートが動作しません!

fishはサブコマンドを実行するために()を使います.

for i in (ls)
    echo $i
end

pkg-configのような出力が1行の長い文字列のときどうしたらいい?

他のシェルと違って, fishは改行時のみ置換されたコマンドを分割します. スペースやタブ, $IFSに含まれる文字では分割されません.

これは次のことを意味します.

echo x(printf '%s ' a b c)x

を実行するとxa b c xが出力されます. しかし次の場合,

echo x(printf '%s\n' a b c)x

xax xbx xcxが出力されます.

ほぼ全てのケースにおいてスペース区切りは望ましくないので, この仕様は改善点であるといえます.

しかしながら, pkg-configやその周辺ツールなどではスペース区切りが必要となっています. このような場合, string split " "を使ってください.

g++ example_01.cpp (pkg-config --cflags --libs gtk+-2.0 | string split " ")

コマンドの終了ステータスを得るには?

$status変数を使ってください. これは他のシェルで使われている$?変数を置き換えるものです.

somecommand
if test $status -eq 7
    echo "That's my lucky number!"
end

もし単に成功か失敗かを知りたいだけなら, ifのような条件構文に直接渡してください.

if somecommand
    echo "Command succeeded"
else
    echo "Command failed"
end

より詳しくは[test]コマンドや[if]コマンドを参照してください.

一回限りの環境変数を設定するには?

SOME_VAR=1 commandというコマンドは次のエラーを引き起こします. Unknown command "SOME_VAR=1"

このようなときにはenvコマンドを使ってください.

env SOME_VAR=1 command

ブロック中で次のようにローカル変数を宣言することもできます.

begin
    set -lx SOME_VAR 1
    command
end

変数が定義されるているか確認するには?

set -q varコマンドを使ってください.

例えばif set -q --$var; echo variable defined; endのように使います;

複数の変数を確認するには'andorの演算子を使ってください.

if set -q var1; or set -q var2
    echo either variable defined
end

定義済みの変数は空である可能性もあることに注意してください. 次の2つのコマンドで空の変数を定義できます. set var set var ""

変数が空でないか確認するには?

string length -q -- $varを使ってください. 例えばif string length -q -- $var; echo not empty; endのように使います.

string lengthは複数の引数のリストを個別にチェックし, 1つでも空でなければ0を返します.

if string length -q -- $var1 $var2 $var3
    echo at least one of these variables is not empty
end

代わりにtest -n "$var"を使ってください. ただしダブルクオートで変数を括ることを忘れないでください. 例えばif test -n "$var"; echo not empty; endのように使います. testコマンドはオプションとして-a(and)と-o(or)を持ちます.

if test -n "$var1" -o -n "$var2" -o -n "$var3"
    echo at least one of these variables is not empty
end

set -Ux(ユニバーサル変数のエクスポート)が働かない?

既に同じ名前のグローバル変数が設定されています.

EDITORTZといった環境変数はset -Uxによってユニバーサルに設定できます. しかし, fishが起動する前に既に環境変数が設定されている場合(ログインスクリプトやシステムの管理者によって), それはグローバル変数として設定されます. [変数スコープ]は"inside out"の検索方式をとっていて, ローカル変数, グローバル変数それからユニバーサル変数の順に変数を確認していきます.

これはグローバル変数の方がユニバーサール変数よりも優先順位が高いことを意味しています.

この問題を避けるために, fishの継承の設定を変えることが考えられます. これが不可能なら, 次のような設定を[設定ファイル] (大抵の場合, ~/.config/fish/config.fish)に記述してください.

set -gx EDITOR vim

シンタックスハイライトの色を変えるには?

ウェブの設定ツールの[fish_config], 若しくは環境変数の[fish_color]を変更してください.

manページの補完をアップデートするには?

[fish_update_completions]コマンドを使ってください.

間違ってディレクトリのパスを打ってEnter押したらディレクトリが移動してしまいました. 何が起きたの?

fishは与えられたコマンドが存在しなくて, かつ./, ~から始まる場合, その名前のディレクトリが存在しないか確認します. 存在すればディレクトリを移動したいのだと暗黙的に推定して実行します. 例えばホームディレクトリに移動する最速の方法は単に~と打ってEnterを押すだけです.

オープンコマンドが働きません

openコマンドはMIMEデータベースとGnomeやKDEが用いるファイルタイプによってデフォルトの動作を規定する, .desktopファイルを用います. これらの環境が少なくとも1つでも存在するにも関わらずopenコマンドが動作しない場合, これらに関係するファイルが標準的な場所にインストールされていないかもしれません. [困ったときには]も参照ください.

fishをデフォルトシェルにするには?

パッケージマネージャを使わずにコンパイルしてfishをインストールした場合, まず以下のコマンドによってfishをシェルのリストに追加する必要があります. (ただし, fishが/usr/localにインストールされていると仮定します.)

echo /usr/local/bin/fish | sudo tee -a /etc/shells

パッケージマネージャを使ってインストールした場合は既にこの操作は行われています.

デフォルトシェルにするには次のコマンドを打ってください.

chsh -s /usr/local/bin/fish

上記のパスは/usr/bin/fishのように変更する必要があるかもしれません. fishがどこにインストールされているかわからない場合はwhich fishコマンドで確認してください.

残念なことに変更をすぐに反映することはできないので, 一度ログアウトしてから再ログインしてください.

screenを使ってるとき, プロンプトの前に変な出力がでます

手っ取り早い解決策はこちらです.

次のコマンドをfish上で実行してください.

function fish_title; end; funcsave fish_title

これで解決するはずです.

さらに何が起こっているか説明します.

fishはターミナルにタイトルバーメッセージを設定します. screenがこの機能をサポートしており, ターミナルがサポートしていない場合, screenはエスケープコードを出力しターミナルはそれを無視することなくテキストとして表示してしまいます. fishはターミナルの種類がなんであるか判別する方法を持たないので, fish側からこの問題を解決することはできません. したがって, 上記のようにタイトルバーメッセージを空にするしか方法がありません.

fishはデフォルトのタイトルバーメッセージを持っていて, それはfish_title関数が未定義のときに使われることに注意してください. そのため単純にfish_title関数を削除してもうまくいきません.

グリーティングメッセージを変更するには?

fish_greeting変数の値を変更するか, 或いはfish_greeting関数を作成してください. 例えばグリーティングをなくすには次のようにします.

set fish_greeting

履歴置換(!$など)が働かないのはなぜ?

履歴置換は対話形式の編集が可能になる前に開発された行儀の悪いインターフェースであるからです. fishはこのインターフェースを無くし, 代わりに完全な対話形式の履歴想起インターフェースを持ちます. これまでの習慣を少し変える必要があります. 古い行や単語を修正したいときにはまずそれを思い出してそれから編集してください. 例えばsudo !!とは打たないでください. まずUpキーを押してそれからHome, 最後にsudoと打ってください.

fishの履歴想起は以下のようにとてもシンプルかつ効率的です.

  • 他のモダンなシェル同様, は最後に実行した行から順に行全体を呼び出します. 一回押すと!!を置き換え, !-3などを置き換えたい場合には次のようにしてください.

    • ずっと前の履歴を呼び出したいとき, そのコマンドの一部を打ってからを一回或いは複数回押してください. こうすることでその文字列を含んだコマンドに絞って呼び出すことができ, 必要な行をより早く手に入れることができます. これは!vi!?bar.cなどの代わりになります.
  • Alt+↑, Upは直近に実行した行から順番に引数のみを呼び出します. 一回押すと!$を置き換え, !!:4などを置き換えたい場合は次のようにしてください.

    • 使いたい引数が履歴のずっと前にある場合, 引数の一部を打ってからAlt+↑, Upを押してください. こうすることでその文字列を含んだ引数に絞って呼び出すことができ, 必要な行をより早く手に入れることができます. 試してみるととても便利なことがわかるでしょう.
    • 同一の行から複数の引数を再利用したい場合(!!:3*のように), 全体を呼び出した後必要ない部分を削除するといいでしょう. (Alt+DAlt+Backspaceを用いると手早く済みます.)

fishでの行の編集について, 詳細は[ドキュメント]を参照してください.

-cd -のショートカットとして使うには?

2.5.0より前のfishではcd -という動作をする-関数を定義することが可能でした. いくつかのバグフィクスを含んだ2.5.0のリリースによって単なる-は無効な関数(変数も同様)となりました. しかしアブリビエーションを使うことによって同様の操作を行うことができます.

abbr -a -- - 'cd -'

アンインストールするには?

万が一fishをアンインストールしたくなった場合, まずデフォルトシェルに設定されていないことを確認してください. もしそうであればchsh -s /bin/bashで変更してください.

次に以下の操作をしてください. (/usr/localにfishがインストールされていると想定しています.)

rm -Rf /usr/local/etc/fish /usr/local/share/fish ~/.config/fish
rm /usr/local/share/man/man1/fish*.1
cd /usr/local/bin
rm -f fish fish_indent

fishのUnicode private-use charactersについて

fishはU+F600からU+F73Fの Unicode private-use character を内部的に使用しています. この範囲の文字を使用した場合, Unicodeの'replacement character', U+FFFDに変換されます. これにはインタラクティブな入力とファイルによる入力が含まれます. (ただし実行されるプログラムには関係しません.)

fishの拡張機能を探すには?

fishのユーザーコミュニティがfishにバンドルされるほど汎用的ではないが便利で素晴らしいスクリプトを公開しています. プロンプトやテーマ, 便利な関数を含む, こうした拡張機能をいくつかのサードパーティのリポジトリから手に入れることができます.

これは全てのリポジトリを網羅したものではなく, fishプロジェクトとして上記のリポジトリのメリットや含まれるスクリプトについて何か意見するわけではありません.