目次
- 環境変数を設定・解除するには?
- ログインのたびにコマンドを実行するには?fishでは何が.bashrc相当?
- プロンプトを設定するには?
- 履歴からコマンドを実行するには?
- サブコマンドを実行するには?バッククォートが動作しません!
- コマンドの終了ステータスを得るには?
- 今実行するコマンドだけに環境変数を設定するには?
- シンタックスハイライトの色を設定するには?
- manページ補完を更新するには?
- なぜ、cd/pwdその他のfishコマンドはいつもシンボリックリンクを正規のパスに変換するの?
- 間違ってディレクトリを入力したらfishがcdしてきた。何が起きた?
- openコマンドが動かない
- fishをデフォルトシェルにするには?
- Screenを使うとプロンプトの前に変な出力がある、なんなの?
- 挨拶のメッセージを変えるには?
- 履歴置換(!$など)はなぜ動かないの?
- fishをアンインストールするには?
- fish内部が使う予約Unicode文字について
環境変数を設定・解除するには?
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
fish_config コマンドを使うと、Webインターフェースで設定できます。
そこでは設定済みのサンプルのプロンプト集を一覧して選択することができます。
履歴からコマンドを実行するには?
コマンドの一部を入力し、↑か↓キーを押してマッチした履歴を辿ることができます。
サブコマンドを実行するには?バッククォートが動作しません!
fishではサブコマンドを()で囲みます。たとえば、
for i in (ls) echo $i end
コマンドの終了ステータスを得るには?
他のシェルでは「$?」を使いますが、fishでは「$status」変数を使います。
今実行するコマンドだけに環境変数を設定するには?
「SOME_VAR=1 command」を実行すると「Unknown command "SOME_VAR=1".」と出力されます。
envコマンドを使ってください。
env SOME_VAR=1 command
ブロックでローカル変数を使用することもできます。
(訳注:-lでローカルスコープ、-xでexport(環境変数化))
begin set -lx SOME_VAR 1 command end
シンタックスハイライトの色を設定するには?
fish_config コマンド(Webインターフェース設定)を使うか、 fish_color_* 環境変数群を変更 してください。
manページ補完を更新するには?
fish_update_completions コマンドを使ってください。
なぜ、cd/pwdその他のfishコマンドはいつもシンボリックリンクを正規のパスに変換するの?
たとえば、 ~/images が ~/Documents/Images へのシンボリックリンクだとします。
そのとき、「cd images」を実行したら(訳注:ホームディレクトリから)、プロンプトは ~/Documents/Images となり、 ~/images とはなりません。
なぜなら、シンボリックリンクされたディレクトリを未解決のままにして一貫性を保つことが不可能だからです。
実際には部分的には可能で、他のシェルではそうしています。
しかし、このことが悪さをする事例がたくさんあると思います。
そのような問題のほとんどは「..」をどのように扱うかについてであり、以下のような例があります。
上記のディレクトリ構造において「cd images; ls ..」を実行すると、 ~ の内容ではなくて ~/Documents の内容を表示します。
たとえ「cd ..」でカレントディレクトリが ~ になり、今のプロンプト、pwdビルトイン、他のディレクトリ情報源がカレントディレクトリは ~/images で親が ~ だと示していてもです(訳注:どんなシェルでも)。
この問題はすべてのコマンドをビルトインにしてUnixの哲学を破るか、すべてのコマンドでその場しのぎの対策を講じない限り、修復不可能です。
この問題はI/Oリダイレクトを行うときにも見られます。
ほかに関連する問題は、findコマンドのように再帰的にディレクトリツリーを操作するたくさんのプログラムがシンボリックリンクされたディレクトリを黙って無視していることです。
たとえば「find $PWD -name '*.txt'」はシンボリックリンクされたパスを解決しないシェルにおいては黙って失敗します。
訳注:具体例を示します
原文だけだと理解できないかもしれませんので、具体例を示します。
$ cd # ホームディレクトリにいる $ mkdir -p ~/Documents/Images $ ln -s ~/Documents/Images images $ touch ~/Documents/Images/test.png # fishではcd images は cd ~/Documents/Images となる $ cd images; ls .. Images/ journal/ $ pwd /r/Documents/Images
# どのシェルもls ..での..は~/Documentsを指すが、pwdはすべて異なる # /rは実体ディレクトリで /home/rubikitch は /r へのシンボリックリンク $ cd $ bash -c 'cd images; echo $PWD; ls ..; cd ..; echo $PWD' /r/images Images journal /r $ zsh -c 'cd images; echo $PWD; ls ..; cd ..; echo $PWD' /home/rubikitch/images Images journal /home/rubikitch # fishではディレクトリのシンボリックリンクは解決される $ cd images; echo $PWD; ls ..; cd ..; echo $PWD /r/Documents/Images Images/ journal/ /r/Documents
他のシェルで「ls ..」と「cd ..」の指す..が異なるのは一貫性がないと思いませんか?
$ cd # bashやzshではfindを実行しても$PWDのみを表示する $ bash bash $ cd images bash $ echo $PWD /r/images bash $ find $PWD /r/images bash $ exit $ zsh zsh $ cd images zsh $ echo $PWD /home/rubikitch/images zsh $ find $PWD /home/rubikitch/images # fishではそのようにならない $ cd images $ echo $PWD /r/Documents/Images $ find $PWD /r/Documents/Images /r/Documents/Images/test.png
この例が示すようにfishでは「..」の指す先をrealpath化した親ディレクトリを指すように一貫しています。
fishにおいてはディレクトリへのシンボリックリンクは、深いディレクトリに入るためのショートカットと思うべきです。
他のシェルとは異なるこの挙動については賛否両論あると思いますが、僕はfishの挙動の方が好きです。
確かに他のシェルからfishに乗り換えた人にとって、この挙動は慣れないうちは確かに違和感を感じるでしょう。
でも、ディレクトリのシンボリックリンクのせいでfindが動かなくて困ったことは僕は何度もあります。
結論を言うと、ディレクトリシンボリックリンク問題について考慮する必要をなくしたfishの挙動にしたのは英断だと思います。
間違ってディレクトリを入力したらfishがcdしてきた。何が起きた?
fishでは、「.」「/」「~」から始まる名前のコマンドを見付けられなかった場合、その名前のディレクトリの存在確認を行ないます。
もし、存在するならば暗黙的にcdします。
たとえばホームディレクトリへ行く最短の方法は「~」を実行するだけです。
openコマンドが動かない
openコマンドはMIMEタイプデータベースとGNOMEやKDEの.desktopファイルを使ってファイルタイプとデフォルトのアクションを決定します。
それらのうち少なくとも1つの環境がインストールされているもののopenコマンドが動作しないのならば、関連ファイル群が非標準の場所にインストールされている可能性があります。
ください。
わからなければ 質問することを考えて ください。
fishをデフォルトシェルにするには?
fishを手動でインストール(たとえばパッケージシステムを使わずにコンパイルした場合)したのならば、まずは以下のコマンドを実行してfishをシェルのリストに加える必要があります。(/usr/local/以下にfishがインストールされていると想定します)
echo /usr/local/bin/fish | sudo tee -a /etc/shells
もしパッケージ化されたfishをインストールした場合、パッケージシステムがすでにそれをやっているべきです。
デフォルトのシェルを変更するには、以下のコマンドを実行します。
chsh -s /usr/local/bin/fish
もしかしたらパスを調整する必要があるかもしれません(たとえば/usr/bin/fishのように)。
もしどこにfishをインストールしたのかがわからない場合は「which fish」を実行してください。
残念ながら、その変更をすぐに反映させる方法はありません。
一旦ログアウトしてから再びログインする必要があるでしょう。
Screenを使うとプロンプトの前に変な出力がある、なんなの?
短い答え
以下のコマンドをfishから実行してください。
function fish_title; end; funcsave fish_title
問題は解決します。
(訳注:funcsaveコマンドにより空の関数定義が ~/.config/fish/functions/fish_title.fish に保存されますので一回実行するだけで済みます)
長い答え
fishは端末のタイトルバーのメッセージを設定しようとします。
Screenそのものはこの機能をサポートしているけれど、あなたの使っている端末はサポートしていません。
何年ながらfishを動かしている端末がタイトルバーを設定できない場合、Screenはエスケープコードとテキストを無視するのではなくてそのまま端末に垂れ流してしまいます。
fish内部からはこの問題を発見・解決することは不可能です。なぜならfishはどんな端末で動作しているのかを知る由がないからです。
よって現在のところ、この問題を解決するには、上記のようにタイトルバーメッセージを解除するしかありません。
fishでは、fish_title関数が未定義のときに使われるデフォルトのタイトルバーメッセージがあることに注意してください。
よって単にfish_title関数を空にすることでその挙動をやめさせることができます。
(訳注:「未定義」と「空定義」は異なります。その関数を呼び出しても何もしないのが空定義です。)
挨拶のメッセージを変えるには?
fish_greeting変数の値を変更するか、fish_greeting関数を定義してください。
挨拶メッセージを非表示にするには、以下のコマンドを実行してください。
set fish_greeting
履歴置換(!$など)はなぜ動かないの?
履歴置換(ヒストリ置換)は対話的行編集が可能になる前の時代に生まれたぎこちないインターフェースだからです。
fishは履歴呼び出しインターフェースを完成させるために、履歴置換を削除しました。
(訳注:僕はGNU/Linuxを20年以上使っていますが、履歴置換を使ったことがありません。生理的に受け付けなかったのか、どうしても覚えられなかったのです。)
新しいインターフェースに切替えるにはほんのちょっとだけ習慣を変える必要があります。
前の行や単語を修正したいならば、それを呼び出してから編集します。
たとえば、「sudo !!」と打つ代わりに↑キーとHomeキーを押してから「sudo 」と打ちます。(訳注:Ctrl+P→Ctrl+Aでもよい)
fishの履歴呼び出しはとてもシンプルで効果的です。
- 現在のシェルのように、↑キー(訳注:Ctrl+Pも可)は最後の実行されたコマンドラインを呼び出せます。
一回の↑キーが「!!」の代わりになり、何度も押すことで「!-3」などを置き換えます。 - ずっと前に実行した履歴を呼び戻したいならば、その行の一部を入力して↑キーを1度以上押してください。
この操作により、打ち込んだ文字列を含む行のみを呼び出せますので、とても素早く欲しいコマンドラインを得ることができます。
これは「!vi」や「!?bar.c」などを置き換えます。 - Alt+↑は直前に実行されたコマンドラインの最後の引数から順次単一の引数を呼び出します。
1回押すと「!$」を置き換え、何度も押すことで「!!:4」などを置き換えます。 - 引数が履歴の深いところにある場合(たとえばたくさんの単語がある2行前)、その引数の一部を入力してAlt+↑を押してください。
この操作により、打ち込んだ文字列を含む引数のみを呼び出せますので、とても素早く欲しい引数を得ることができます。
試してみてください、これはとても便利ですよ! - 同じ行の複数の引数を再利用する場合(「!!:3*」など)、コマンドラインすべてを呼び出して不要な部分を削除することを考慮してください。(Alt+DやAlt+Backspaceが役立ちます)
fishの行編集の詳細はドキュメント を見てください。
fishをアンインストールするには?
fishをアンインストールしたいのですか?
ならば、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文字について
fishは U+F600 〜 U+F73F の範囲のUnicode文字を 予約文字として使用 しています。
この範囲内の文字をfishに渡そうとすると、fishはその文字をUnicodeの「repacement character」である U+FFFD に置き換えます。
これは対話的入力でもfishによって読み込まれたファイルに対してもあてはまります。(ただし、fishが実行するプログラムについてはそうではありません。)
最後までお読みいただき、ありがとうございました。参考になれば嬉しいです。