🐚
bashとzshの違いについて少しだけ掘り下げてみる
はじめに
bashとzshで若干詰まってモヤモヤしたのでここで掘り下げてみます。
マシンスペック
MacBook Air M2 arm64
事前知識
shell
シェルは、ユーザーとOSカーネルの橋渡しをするコマンドインタプリタです。
コマンド実行、スクリプト処理、環境管理を担う重要な役割を持ちます 。
bash
正式名:Bourne Again SHell(1989年、GNUプロジェクト)。
POSIX標準に準拠し、LinuxやmacOS(High Sierra以前)ではデフォルトのインタプリタとして広く使われていました。
ヒストリ機能、補完、ファイルグロブ、変数処理など標準的な機能を備えています。
zsh
正式名:Z shell(1990年、Paul Falstad)
Bourne系の機能を拡張し、bash/ksh/tcshからも多くの機能を取り入れた強力なインタラクティブシェル。
macOS Catalina以降ではデフォルトシェルとなっています 。
高度な補完、配列・グロブ拡張、カスタマイズ性(プラグイン、テーマなど)が強み。
比較表
項目 | bash | zsh |
---|---|---|
開発開始 | 1989年, GNU(Brian Fox) | 1990年, Paul Falstad |
POSIX準拠 | 高い | 準拠しつつ多数の拡張あり |
デフォルトシェル | Linux, macOS High Sierra以前 | macOS Catalina以降 |
配列のインデックス | 0始まり | 1始まり(※変更可) |
補完・グロブ | 基本的 | 拡張(qualifiers やプラグイン) |
カスタマイズ性 | シンプル&堅牢 | プラグイン・テーマ豊富 |
起動時ファイル |
.bashrc , .bash_profile
|
.zshrc , .zprofile
|
準備
今回は、docker上とで比較します。
Docekrの準備
# 作業ディレクトリ作成
mkdir -p ~/shell-compare && cd ~/shell-compare
# Dockerfile を作成
cat << 'EOF' > Dockerfile
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y \
bash zsh vim curl git
# デフォルトは bash
CMD ["bash"]
EOF
# イメージビルド
docker build -t shell-compare:latest .
bashの設定で接続
docker run --rm -it shell-compare:latest
# 接続後
bash --version
GNU bash, version 5.2.21(1)-release (aarch64-unknown-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
zshの設定で接続
docker run --rm -it shell-compare:latest zsh
# 接続後
zsh --version
zsh 5.9 (aarch64-unknown-linux-gnu)
検証
配列のインデックス
事前にファイルを準備してそれぞれの挙動を確認します。
# array_test.sh
#!/usr/bin/env sh
a=(one two three)
echo "a[0]: ${a[0]}"
echo "a[1]: ${a[1]}"
bashの場合
./array_test.sh
a[0]: one
a[1]: two
普段使っているCやPythonなどと同じようなインデックスとなります。
zshの場合
zsh ./array_test.sh
a[0]:
a[1]: one
配列の1の場所が先頭ポインタとなります。
パイプとサブシェルの挙動
bashの場合
echo foo | read x; echo "$x"
(空)
左辺と右辺をパイプで繋いで実行していますが、bashは左辺と右辺が別のプロセスで実行されるため、共有メモリを取らないことから空が返ります。
zshの場合
echo foo | read x; echo "$x"
foo
zshはパイプで繋がった両方のコマンドを同一プロセス内で実行しており、fooという戻り値が返ってきています。
まとめ
今回は、zshとbashの違いを少しだけ掘り下げました。
環境依存はzsh、bashの違いもあり得ますのでご注意ください。
Discussion