入門編:Fish文法の基本とBashとの違い
Bash との意図的な構文の違い、クォーティングの仕組み、丸括弧を用いたコマンド置換、およびパイプラインとリダイレクトの基本文法を解説します。
Bash から移行する際の最重要の違い
fish は Bash や POSIX の歴史的制約を排除して設計されたため、基本構文に明確な違いがあります。
| 項目 | Bash / Zsh | fish |
|---|---|---|
| 変数への代入 | NAME="Alice" | set NAME "Alice" |
| コマンド置換 | $(date) または `date` | (date) |
| ブロックの終端 | fi, done, esac, } | すべて end で統一 |
| 外部環境変数 | export PATH=... | set -gx PATH ... |
| リスト(配列)展開 | "${arr[@]}" | $arr |
Bash の癖で VAR=value と入力すると、fish は「そのようなコマンドは存在しません」とエラーを出力します。
変数代入と参照の基本
fish では、変数の定義や変更にはすべて set コマンドを使用します。
# 変数に文字列を代入
set TARGET "Production"
# 変数の参照
echo "Deploying to $TARGET..."
# 変数の削除(未定義化)
set -e TARGET
変数名の直前にドル記号($)をつけて値を展開します。
コマンド置換(丸括弧構文)
コマンドの出力を別のコマンドの引数として渡す「コマンド置換」は、単純な丸括弧 (...) で行います。ドル記号は不要です。
# 現在の日付を取得してファイル名に埋め込む
tar -czf backup-(date +%Y%m%d).tar.gz ./data
# ファイル一覧をコマンド置換で渡す
count (ls -1 *.md)
丸括弧内の出力が改行で区切られている場合、fish はそれを自動的にリスト(配列)の各要素として解釈します。
クォーティングのルール
文字列の扱い方について説明します。
» ダブルクォート(“…”)
内部の変数は展開されます。ただし、Bash のように空白文字によって引数が勝手にバラバラに分割される現象(単語分割: Word Splitting)は起きません。1つの安全な引数として保持されます。
set GREETING "Hello World"
echo "$GREETING, Alice"
» シングルクォート(‘…’)
内部のすべての文字をそのままの文字として解釈します。変数や丸括弧によるコマンド置換は一切展開されません。
echo '$GREETING'
# 出力結果: $GREETING
パイプラインとリダイレクト
ストリームの受け渡しや保存の構文です。
» パイプライン(|)
左側の標準出力を右側の標準入力へ接続します。標準エラー出力をパイプで渡したい場合は 2>| を使用します。
# 通常のパイプライン
cat access.log | grep "ERROR" | wc -l
# エラー出力のみをパイプラインで渡す
build_project 2>| tee errors.log
» リダイレクト
標準的な記号(>、>>、<)を使用します。
# 出力をファイルに上書き
echo "Configuration" > config.txt
# 末尾に追記
echo "New Entry" >> config.txt
# エラー出力をファイルに保存
command_name 2> error.log
# 正常出力とエラー出力の両方を保存
command_name &> output_and_error.log
» 連続実行演算子(&& と ||)
fish 3.0 以降、一般的なシェルと同様に &&(成功時実行)と ||(失敗時実行)が完全にサポートされています。
make test && make deploy || echo "Build failed!"