fish-shell

文書の過去の版を表示しています。


fish-shell

  • シェル言語の一つ
  • zsh 並の補完機能がある
    • さらに予測機能 (tab を押さなくても履歴機能を表示) がある
  • 軽量
  • プロンプトは fish_prompt 関数で定義する。
  • 無銘闇人の現在のプロンプト
    function fish_prompt
    	printf "%s %s%s%s%s %s%s %s\n%s" (set_color -o bryellow)"["(date +"%Y/%m/%d %H:%M:%S")"]" (set_color -o green)$USER (set_color normal)"@" (set_color -o green)(hostname) (set_color -o white)"(fish)" (set_color -o blue)"["(jobs | wc -l)"]" (set_color normal)":" (set_color -o cyan)(prompt_pwd) (set_color normal)"\$ "
    end
    • 表示:
      [YYYY/MM/DD hh:mm:ss] USERNAME@HOSTNAME(fish) [JOB_NUBER]: CURRENT_DIR
      $ 
    • 表示例:
      [2018/03/07 10:43:45] mumeiyamibito@hoge(fish) [0]: ~
      $ 
  • function fish_prompt を何度も実行して、プロンプトが決まったら、funcsave fish_prompt で関数を保存するか、この関数を ~/.config/fish/config.fish に保存することで、次回起動時から設定したプロンプトが適用される。後者の方法がおすすめ。
  • 参考サイト:
  • 文字の色はコマンドの直前に set_color コマンドで設定する。
    set_color [OPTION] COLOR; COMMAND
    • COLOR: 色名 (black, red, green, yellow, blue, magenta, cyan, white, brblack, brred, brgreen, bryellow, brblue, brmagenta, brcyan, brwhite, その他 16 進数の RGB でも指定可)
    • OPTION
      • -o: 太字モード (bold)
      • -i: 斜体モード (italic)
      • -u: 下線モード (underline)
      • -b: background color
      • -r: 反転モード
    • 色名を normal にすると色やモードがリセットされる。
  • 定義
    • set コマンドを使って定義する。
      $ set VAR_NAME VALUE1 [VALUE2 VALUE3 ...]
      • 意味
        • VAR_NAME: 変数名
        • VALUE1: 値
      • 配列の場合、VALUE をスペースで区切って指定する。
      • 他のシェルと同じように変数名には $ を付けずに指定する。
      • 他のシェルの変数と異なりグローバル変数ではなく、ローカル変数となるため、注意。
      • グローバル変数にする場合は、-g オプションを付ける。
        $ set -g VAR_NAME VALUE
      • 子プロセスにも伝播させるためには -x オプションを付ける。
        $ set -x VAR_NAME VALUE
  • 呼び出し
    • 他のシェルと同様に $VAR_NAME で呼び出す。
      $ echo $VAR_NAME
    • 配列の場合、1 から始まるインデックス (INDEX) で指定する。
      $ echo $VAR_NAME[INDEX]
    • 変数展開は以下の 2 種類
      • ダブルクォーテーションで囲む: “$VAR_NAME”, “$VAR_NAME”TEXT
      • {} で変数全体を囲む: {$VAR_NAME}, {$VAR_NAME}TEXT
        • B シェルのように ${VAR_NAME} だとエラーになるため注意する。
  • 配列の要素数の取得
    $ count $VAR_NAME
    • count コマンドを使って取得する。
  • 定義
    • functionend で囲む。
      function FUNC_NAME
          DO_SOMETHING
      end
    • FUNC_NAME: 関数名 (関数名の後に (){} を付けない)
    • DO_SOMETHING: 関数で実行するコマンド
    • 引数は $argv で受け取る。複数の引数の場合は 1 から始まるインデックスを付けて受け取る (例: $argv[1])。
  • 呼び出し
    • 他のシェルスクリプトと同じ
      FUNC_NAME
  • コマンドの結果を引数化する方法。
  • bash などでは、以下のように実行することで中間ファイルを生成せずに目的の結果が得られる。
    $ echo "$(cat a.txt | wc -l) + $(cat b.txt | wc -l)" | bc
    1. a.txt の行数を wc -l コマンドでカウントする。→ 例: 100
    2. b.txt の行数を wc -l コマンドでカウントする。→ 例: 120
    3. それぞれの行数を用いて数式を echo で表示する。→ 例: 100 + 120
    4. 数式を bc コマンドで演算する。→ 例: 220
    • なお、$()`` (バッククォーテーションで囲む) でも代用できる (ただし、ネストできない)。
  • fish-shell では、単なる括弧 (()) でコマンド置換をする。
    $ echo (cat a | wc -l)"+"(cat b | wc -l) | bc
  • マッチ
    $ string match [-a|-i|-r|-n|-v] PATTERN STRING
    • PATTERN: パターン
    • STRING: 対象文字列
    • -a: 繰り返しマッチ
    • -i: 大文字小文字を区別しない
    • -r: 正規表現でパターンを指定 (デフォルトは glob (ワイルドカード))
    • -n: マッチした位置を返す
    • -v: 逆の結果を返す
  • 文字の長さを取得
    $ string length STRING
    • STRING: 対象文字列
  • 文字の置換
    $ string replace [-a|-i|-r|-q|] PATTERN REPLACE STRING
    • PATTERN: パターン
    • REPLACE: 置換後の文字列
    • STRING: 対象文字列
    • -a: 繰り返しマッチ
    • -i: 大文字小文字を区別しない
    • -r: 正規表現でパターンを指定 (デフォルトは glob (ワイルドカード))
  • リストの文字列を結合
    $ string join SEP LIST
    • SEP: 区切り文字
    • LIST: 文字列リスト
  • 文字列をリストに分割
    $ string split [-m|-r] SEP STRING
    • -m: 最大分割数
    • -r: 右側から分割 (デフォルトは左側から分割)
    • SEP: 区切り文字
    • STRING: 対象文字列
  • 文字列のトリム (末端の文字列削除)
    $ string trim [-l|-r|-c] STRING
    • -l: 左側末端の文字列を削除 (デフォルトは両端)
    • -r: 右側末端の文字列を削除 (デフォルトは両端)
    • -c: 削除する文字列を指定 (デフォルトは空白)
    • STRING: 対象文字列
  • 位置を指定して文字列抽出
    $ string sub [-s|-l] STRING
    • -s: 取得する文字列の開始位置
    • -l: 取得する文字列の長さ
    • STRING: 対象文字列
  • エスケープ文字を追加
    $ string escape [-n] STRING
    • -n: 出力結果をクォーテーションで囲まない
    • STRING: 対象文字列
  • リダイレクト
    • 標準出力
      $ COMMAND > FILE
    • 標準出力 (追記)
      $ COMMAND >> FILE
    • 標準エラー
      $ COMMAND ^ FILE
    • 標準エラー (追記)
      $ COMMAND ^^ FILE
    • 標準出力と標準エラーを同時出力
      $ COMMAND 2>&1 | cat > FILE
  • パイプ (通常のシェルと同じ)
    $ COMMAND1 | COMMAND2
  • 2 通りのコマンドがある
    $ type -q <COMMAND>


    OR

    $ command -sq <COMMAND>
  • 結果は、$status で受け取るか、; and; or (fish-shell 3.0 以降なら &&|| でも可) でつなげて受け取る。
    • 成否を受け取るなら、$status を用いる
      $ echo $status
    • 続けて、コマンド (コマンドが存在する場合は COMMAND1 を実行し、存在しない場合は COMMAND2 を実行する。)
      $ type -q <COMMAND>; and <COMMAND2>; or <COMMAND3>
  • 参考サイト:
  • fish_config コマンドで、ウェブインターフェースの設定画面が現れるので、そこで変更する。
  • リモート環境でウェブインターフェースが使えない場合は、set -U | grep fish_color で表示された内容を、リモート環境でも set -U で設定していくと同じテーマになる。
  • 設定されている環境変数で、出力する内容が変わるプログラムがいくつか存在する。
    • date コマンドなどは、使用している OS の言語で、日時のフォーマットが変わる。
    • 出力する環境によっては、正常に動作しないプログラムもいくつか存在する。
  • 元の言語 (たいていは英語) での出力を望む場合は直前に LANG=C を付けると良い。
    • bash や zsh では、コマンド (実行プログラム) の場合、素直に LANG=C を付ける。
      $ LANG=C date
    • fish の場合は、env コマンドを使う。
      $ env LANG=C date
  • fish-shell では if 文の条件で () を使って優先度を変えることができない (() がコマンド置換 (bash の $()) に割り当てられているため)
  • 対策: begin 〜 end; and; or を使う
    • 例:
      • Python での表記
        if True and not True and False:
            print("OK")
        ---> 
        if True and not(True and False):
            print("OK")
        ---> OK
      • fish-shell での表記
        if true; and not true; and false
            echo "OK"
        ---> 
        if true; and not begin true; and false; end
            echo "OK"
        ---> OK
  • 【症状】fish-shell を導入したリモートに rsync や scp でファイルを転送しようとすると以下のエラーメッセージが表示される
    protocol version mismatch -- is your shell clean?
    (see the rsync man page for an explanation)
    rsync error: protocol incompatibility (code 2) at compat.c(178) [sender=3.1.2]
  • 【原因】リモートに ssh にログインした際に、標準出力 (リモートサーバの状況やグリーティングなど) されるものがある場合にエラーになるらしい (bash など他のシェルでも同様の原因の問題があるらしい)。
  • 【解決方法】
    • ログイン時に実行される config.fish から、標準出力 (echo など) を削除、あるいはコメントアウトする。
    • ログイン時に実行される config.fish の標準出力部分を if status –is-interactive … end ブロックで囲む。
      • 対話シェルの時のみ表示するようにする。
      • 例:
        if status --is-interactive
            echo "test"
        end
  • fish-shell.1591935751.txt.gz
  • 最終更新: 2020/06/12 13:22
  • by mumeiyamibito