.bashrcとは?.bash_profileとの読み込み順の違いと書き方・反映手順

.bashrcとは?.bash_profileとの読み込み順の違いと書き方・反映手順

エイリアスを~/.bashrcに書いたのに、SSHでログインすると効かない。逆に、scpを実行したら謎のエラーで止まった。どちらも原因は同じで、Bashが「どの起動形態のときにどのファイルを読むか」を把握していないことにあります。この記事では、2026年9月時点で最新のBash 5.3系の公式マニュアルを根拠に、.bashrcが読まれる条件と.bash_profile・.profileとの違い、書く設定と分ける設定の線引き、source ~/.bashrcでの反映と起動しなくなったときの復旧、さらにssh・scp・cron・CIで.bashrcが原因になる不具合の防ぎ方までを、コピーして使える設定例付きで整理します。

まとめ:.bashrcに書くもの・書かないものと読み込まれない問題の要点

.bashrcは対話的な非ログインシェルが起動するたびに読む設定ファイルです。エイリアス、シェル関数、プロンプト、履歴、shoptのようなシェル自身の挙動はここに書きます。PATHなど子プロセスへ引き継ぐ環境変数は、ログイン時に1回だけ読まれる~/.bash_profileでexportし、その中から.bashrcを読み込ませる構成が基本形です。

「書いたのに効かない」の大半は、ログインシェルとして開いた端末で.bashrcが読まれていないケースです。~/.bash_profileに1行足せば解消します。反対に「関係ない操作が壊れる」のは、sshd経由の非対話起動でも.bashrcが読まれる仕様が原因です。先頭に対話判定のガードを置き、echoや重い初期化を対話時だけに限定してください。

cronのジョブとCIのステップでは.bashrcに頼らないこと。必要な変数はスクリプトの中か、ジョブの定義側で明示的に渡します。macOSは10.15以降の既定がzshなので、Bashの設定ファイルを直しても反映されない点も先に確認しておきます。

.bashrcが読まれる条件とログインシェル・対話シェルの4分類

読まれるファイルは、シェルが「ログインか」「対話か」の2軸で決まります。2軸を混同したまま設定を足すと、どこに書いても効かない状態に陥ります。

対話と非対話・ログインと非ログインで変わる読込ファイルの対応表

GNU Bashマニュアルの起動ファイルの節が定める読み込み対象を、起動形態ごとに並べると次の通りです。実務で出会う頻度が高い順に並べています。

起動形態 典型的な場面 読むファイル
対話・非ログイン 端末アプリの新規タブ、bashと打って入る子シェル ~/.bashrc
対話・ログイン SSHでのログイン、コンソールログイン /etc/profile→個人設定1つ
非対話(sshd経由) ssh host コマンド、scp、sftp ~/.bashrc
非対話(通常) シェルスクリプト、cron、CIのステップ BASH_ENV が指すファイルのみ
shとして起動 /bin/sh がBashを指す環境 ログイン用2ファイル・対話時はENV

対話・ログインでは/etc/profileを読んだ後、~/.bash_profileなどの個人設定ファイルを1つ読み込みます。shとして起動する場合のログイン用2ファイルは/etc/profileと~/.profileで、対話時に読む設定はENVで指定する形です。表の3行目が見落とされやすい箇所です。「非対話なら.bashrcは読まれない」と覚えていると、sshd経由の起動で.bashrcが走る挙動を説明できません。この仕様が引き起こす問題は後半の章で扱います。

.bash_profileがあると.profileが読まれない探索順の落とし穴

対話ログインシェルは/etc/profileを読んだ後、~/.bash_profile、~/.bash_login、~/.profileの順に探し、最初に見つかって読めた1つだけを実行します。3つとも読むわけではありません。

よくある事故は、あるツールのインストーラが~/.bash_profileを新規作成した瞬間に、それまで効いていた~/.profileの設定が丸ごと読まれなくなるものです。既定の~/.profileに.bashrcを読み込む記述が入っている環境では、エイリアスまで一斉に消えたように見えます。ls -la ~ | grep -E 'bash_profile|bash_login|profile'で、どのファイルが存在するかを最初に確かめてください。

自分のシェルがどの起動形態かをshoptと$-で判定する確認コマンド

推測で直す前に、いま動いているシェルの形態を確かめます。Bashの起動オプションの節によれば、ログインシェルとは「引数0の1文字目が-のもの、または--loginで起動したもの」です。対話シェルかどうかは、$-にiが含まれるかで判定できます。

# ログインシェルかどうか
shopt -q login_shell && echo "login" || echo "non-login"

# 対話シェルかどうか($- に i が含まれるか)
case $- in
  *i*) echo "interactive" ;;
  *)   echo "non-interactive" ;;
esac

# 引数0の先頭が - ならログインシェルとして起動されている
echo "$0"

# 実行中のBashの版
echo "$BASH_VERSION"

echo "$0"が-bashと出れば、ログインシェルです。端末アプリの設定によって新規ウィンドウをログインシェルで開くものもあるため、同じPCでも端末ごとに結果が変わります。$BASH_VERSIONは後述の設定例が前提とする版を確かめる用途です。

.bashrcに書く設定と.bash_profileへ分ける設定の実務上の線引き

判断基準は「子プロセスへ引き継ぐかどうか」です。引き継がれるのはexportした環境変数だけで、エイリアスや関数、シェルオプションは起動したシェルの中にしか存在しません。

エイリアス・関数・プロンプトを.bashrcへ置く理由と引き継がれない範囲

エイリアスは子プロセスへ継承されないため、新しいシェルが起動するたびに定義し直す必要があります。毎回読まれる.bashrcに置く理由はここにあります。PS1によるプロンプト、shopt -s histappendのようなシェルオプション、completeによる補完の登録も同じ扱いです。

aliasという語はDNSやメールでも使われ、文脈で意味が変わります。シェルのaliasを含む別名の文脈別の意味は別記事にまとめました。ここではBashのaliasに限り、「定義の置き場所は.bashrc」とだけ押さえてください。

PATHのexportと.bash_profile経由で.bashrcを読む構成

PATHはログイン時に1回組み立てれば、以降に起動する子シェルとコマンドへ継承されます。.bashrcでPATH="$HOME/bin:$PATH"と書くと、子シェルを開くたびに同じパスが先頭へ積み重なり、echo $PATHが重複だらけになります。環境変数の仕組みとOS別の設定方法で扱う「継承される変数」は、ログイン側で1回だけ組むのが原則です。

# ~/.bash_profile
# ログイン時に1回だけ実行される

export PATH="$HOME/.local/bin:$HOME/bin:$PATH"
export EDITOR="vim"
export LANG="ja_JP.UTF-8"

# 対話設定は .bashrc に集約し、ここから読み込む
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

末尾のif文は、公式マニュアルが「典型的に.bash_profileに入る行」として示している形と同じです。この1行があれば、ログインシェルで開いた端末でも.bashrcのエイリアスが効きます。ディストリビューション既定の~/.profileを使い続けるなら、そちらに同等の記述があるかをgrep bashrc ~/.profileで確認してください。

履歴のHISTSIZEとHISTCONTROLで作業ログを残す.bashrcの設定例

サーバー作業では、直前に何を実行したかを後から追えることが障害対応の速度を左右します。Bash変数の節によれば、HISTCONTROLにignorespaceを含めると先頭が空白の行は履歴に残らず、ignoredupsは直前と同じ行を保存しません。

# ~/.bashrc

# 非対話なら何もしない(理由は後述)
case $- in
  *i*) ;;
  *) return ;;
esac

# 履歴:件数を増やし、複数端末の履歴を上書きせず追記する
HISTSIZE=10000
HISTFILESIZE=20000
HISTCONTROL=ignoreboth
HISTTIMEFORMAT="%F %T "
shopt -s histappend

# 端末幅の変化に追従する
shopt -s checkwinsize

# エイリアス
alias ll='ls -alF'
alias grep='grep --color=auto'

# プロンプト表示の直前に毎回実行するコマンド(配列で複数登録)
PROMPT_COMMAND=('history -a')

# 個人の追加設定は別ファイルに分ける
[ -f ~/.bashrc.local ] && . ~/.bashrc.local

ignorebothはignorespaceとignoredupsの両方を指定する値です。パスワードを含むコマンドを誤って打つ場面に備え、先頭に空白を付ければ履歴に残らない運用を覚えておくと役立ちます。PROMPT_COMMANDは、配列として設定すれば各要素が順にプロンプト表示前に実行される仕様です。古い版で配列が効かない場合は、文字列でPROMPT_COMMAND='history -a'と書いてください。

編集後にsourceで反映する手順と設定ミスで端末が開かないときの復旧

設定の変更は、既に開いている端末には反映されません。反映の方法は2つあり、効果の範囲が違います。

source ~/.bashrcとexec bashの違いと使い分けの基準

source ~/.bashrc(短縮形は. ~/.bashrc)は、今のシェルの中で.bashrcをもう一度実行します。追加したエイリアスはすぐ使えますが、削除した設定は残り続けます。消したはずのaliasが効いたままになるのはこのためです。

# 追記した設定を今のシェルへ反映する
source ~/.bashrc

# 設定を削除・変更した場合は、シェルを置き換えて読み直す
exec bash

# ログインシェルとして読み直したい場合(.bash_profile から読む)
exec bash -l

# 反映されたかを確認する
type ll
alias | grep ll

exec bashは現在のシェルを新しいBashで置き換えるため、定義の削除も反映されます。追記だけならsource、削除や書き換えを含むならexec bash。この基準で使い分けると、古い定義が残る混乱を避けられます。

構文エラーで起動しなくなったときにbash –norcで入り直す復旧手順

.bashrcの末尾でexitを書いてしまった、存在しないファイルをexecしている、といった誤りがあると、端末を開いた瞬間に閉じてしまいます。起動オプションの節が定める--norcは「対話シェルで~/.bashrcを読まない」、--noprofileは「ログイン時の起動ファイルを読まない」指定です。これで設定ファイルを迂回して入れます。

  1. 端末アプリの起動コマンドをbash --norc --noprofileに一時変更するか、別の端末からssh -t user@host bash --norc --noprofileで入る
  2. bash -n ~/.bashrcで構文だけを検査し、エラーの行番号を確かめる
  3. 該当行を直し、bash -x -i -c exitで1行ずつの実行内容を表示させて止まる箇所がないかを見る
  4. 問題がなければ端末の起動コマンドを元に戻す

編集前にcp ~/.bashrc ~/.bashrc.bakを取る習慣があれば、手順2と3を飛ばして戻すだけで済みます。本番サーバーで直接編集する場合は、既存のSSHセッションを1本残したまま、別セッションで新規ログインできることを確かめてから閉じてください。

ssh・scp・cron・CIで.bashrcが原因になる不具合と対話判定ガード

競合の解説記事がほとんど触れていない論点です。ここを知らないと、.bashrcへの1行が、ファイル転送や定期ジョブを黙って壊します。

sshd経由の非対話起動でも.bashrcが読まれる仕様とscpが止まる理由

起動ファイルの節には、標準入力がネットワーク接続につながった状態、つまりsshdなどから非対話で起動されたとBashが判断した場合に~/.bashrcを読む、と明記されています。sshd(8)のマニュアルも、ログイン処理の最後にユーザーのシェルまたはコマンドを実行し、コマンドはすべてユーザーのログインシェルの下で動くと記しています。

この経路で.bashrcがechoやfortuneのように何かを出力すると、転送の通信路へその文字列が混ざります。scpとsftpはシェルの標準出力をプロトコルの通信路として使うため、先頭に余計なバイトが来た時点で通信が壊れて止まります。OpenSSH 9.0のリリースノート(2022年4月8日公開)でscpの既定はSFTPプロトコルへ移りましたが、どちらもリモート側でシェル経由の起動を伴う点は変わりません。SCPコマンドの構文とオプションが正しいのに転送だけ失敗するなら、まず相手側の.bashrcを疑ってください。

先頭の対話判定ガードでecho出力と重い初期化を止める書き方

対策は、.bashrcの先頭で非対話なら即座に戻ることです。前章の設定例の冒頭に置いたcase文がこれに当たります。途中に置くと、ガードより上の行はscpのときにも実行されてしまいます。

# ~/.bashrc の先頭に置く
case $- in
  *i*) ;;
  *) return ;;
esac

# ここから下は対話シェルでのみ実行される
echo "Welcome to $(hostname)"

# 起動に数百ミリ秒かかる初期化も対話時だけに限定する
if command -v pyenv >/dev/null 2>&1; then
  eval "$(pyenv init - bash)"
fi

ガードを入れた後の動作確認は、別の端末からssh host true | wc -cを実行し、出力が0になることで判断できます。1以上なら、ガードより前か/etc/bash.bashrcなど別の場所で何かが出力されています。pyenvのshimを有効化する初期化やnvmのように起動を遅くする処理も、ガードの下へ置けばssh経由のコマンド実行を遅くしません。

cronとCIでは.bashrcに頼らずスクリプト側で環境を明示する判断

ここは言い切ります。cronのジョブとCIのステップで.bashrcを読ませる設計は採用しません。どちらも通常の非対話シェルで、公式マニュアルの通り.bashrcは読まれず、読まれるのはBASH_ENVが指すファイルだけです。対話判定ガードを入れた.bashrcは、仮にBASH_ENVで読ませても先頭で戻るため役に立ちません。

# crontab:必要な変数はここで明示する
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * /opt/app/bin/backup.sh >> /var/log/backup.log 2>&1

# スクリプト側:共通の変数は専用ファイルに分けて明示的に読む
#!/usr/bin/env bash
set -euo pipefail
. /opt/app/etc/env.sh

ジョブが依存する変数は、.bashrcとは別の専用ファイルに置き、スクリプトの中から明示的に読み込ませます。こうすると「手元では動くのにcronでは動かない」という差が構造的に生まれません。CIでは、ジョブ定義のenvで渡すのが筋です。サーバー台数が増え、ユーザー環境とジョブの実行環境を全台で揃える段階では、インフラ構築(AWS・Google Cloud・Azure)の運用設計として引き受けることもできます。

macOS・WSL・Git Bashで.bashrcが読まれる条件と設定先の違い

Linuxサーバー以外の環境では、既定のシェルと端末の起動方法が違うため、同じ.bashrcでも読まれ方が変わります。

macOSは10.15以降zshが既定のため.zshrcへ書く場面と戻す手順

Appleのサポート文書は、macOS 10.15以降ではzshがデフォルトのログインシェルおよびインタラクティブシェルだと明記しています。この環境で.bashrcを編集しても、zshは読みません。書く先は~/.zshrcです。

Bashを使い続けたいなら、同文書が示すchsh -s /bin/bashで既定のシェルを変更します。変更後は、macOSのターミナルが新規ウィンドウをログインシェルとして開く点に注意してください。~/.bash_profileから.bashrcを読む前述の構成が、そのまま必要になります。チームで設定を配る場合は、Bashとzshで共通化できる環境変数だけを別ファイルへ切り出し、両方の設定ファイルから読む形にすると二重管理を避けられます。

WSLとGit Bashで端末がログインシェルとして開く場合の確認と対処

WindowsでBashを使う経路は主に2つあり、どちらも端末の設定次第で起動形態が変わります。WSLで開発環境を構築した場合は、Linuxのディストリビューション既定の~/.profileと~/.bashrcがそのまま使われます。Git Bashが読み込む対象は、ユーザーのホームディレクトリ直下に置かれた設定ファイルです。

どちらの環境でも、最初に前述のshopt -q login_shellで起動形態を確かめてください。ログインシェルとして開いているなら、~/.bash_profileか~/.profileから.bashrcを読む1行が要ります。非ログインとして開いている場合、読み込ませる設定ファイルは.bashrcだけで十分です。WindowsとWSLで改行コードが混ざるとCRが残り、$'\r': command not foundというエラーで設定が途中で止まります。Windows側のエディタで編集した場合は、改行コードをLFに揃えてから保存してください。

よくある質問

.bashrcの設定で相談の多い5点に答えます。

.bashrcはどこにありますか?見つからない場合は作ってよいですか?

ユーザーごとの.bashrcはホームディレクトリ直下の~/.bashrcです。先頭がドットの隠しファイルなので、lsでは表示されずls -a ~で確認します。存在しなければ新規作成して構いません。Bashはファイルがあれば読み、無ければ何もしない仕様です。全ユーザー共通の設定を置く場所はディストリビューションで異なり、/etc/bash.bashrcや/etc/bashrcが使われます。作成後は、ログインシェルで読ませるための1行を~/.bash_profileに足すことも忘れないでください。

.bashrcと.bash_profileはどちらに書けばよいですか?

子プロセスへ引き継ぐ環境変数(PATH、EDITOR、LANGなど)は~/.bash_profileでexportし、エイリアス・関数・プロンプト・履歴・shoptは.bashrcに書きます。そのうえで~/.bash_profileの末尾から.bashrcを読み込めば、どの起動形態でも設定が揃います。迷ったときは「新しいシェルを開くたびに定義し直す必要があるか」で判断してください。必要なら.bashrc、1回で足りるなら.bash_profileです。

source ~/.bashrcを実行しても反映されないのはなぜですか?

原因は3つに絞れます。第1に、編集したファイルと実行中のシェルが違うケースです。echo $0がzshなら.bashrcは関係ありません。第2に、ファイルの途中でエラーが起きて読み込みが止まっているケースで、bash -n ~/.bashrcで構文を検査できます。第3に、削除した設定が残っているだけのケースで、sourceは削除を反映しないためexec bashで読み直してください。

rootユーザーの.bashrcに設定を書いても問題ありませんか?

rootの.bashrcは/root/.bashrcで、一般ユーザーと同じく読まれます。ただし、sudoでコマンドを実行しても呼び出し元ユーザーの.bashrcのエイリアスは効きません。sudo -iやsu -でrootのログインシェルに入ったときに、rootの設定が読まれます。rootの設定にrmの上書きエイリアスなどを入れると、他の管理者の想定と挙動が変わるため、複数人で運用するサーバーでは最小限に留めるのが安全です。

プロジェクトごとに環境変数を切り替えたいときも.bashrcに書きますか?

書かない方がよい設定です。.bashrcはシェル全体に効くため、案件Aの接続先と案件Bの接続先を両方書くと、変数名の衝突と取り違えが起きます。ディレクトリに入ったときだけ変数を読み込み、出たら戻すdirenvのような仕組みを使ってください。direnvでディレクトリ単位に環境変数を切り替える手順で、.bashrcへのhook追記から扱っています。.bashrcに残すのは、どのプロジェクトでも共通の設定だけにします。

関連記事

お気に入りに入れた記事の一覧

資料請求

RELATED POSTS 関連記事

目次