🐚

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