EC2でUbuntu 16.04にデプロイする時に環境変数を設定する場所
Amazon LinuxだとCapistranoでrailsアプリをデプロイする時、特に設定しなくてもデプロイユーザーの環境変数がそのまま設定されていたのに、Ubuntuでは設定されていなかった。non interactive、non loginセッションで実行される場合、Ubuntuでは読み込むファイルが違うようだった。
結論を先に書くと、Ubuntu 16.04では~/.bashrc
はnon interactive、non loginセッションでも読み込まれるので、ここに書いておけば良い。
各種スクリプトの読み込み順
sshでログインした場合
- /etc/profile
- /etc/bash.bashrc
- ~/.profile
- ~/.bashrc
non interactiveセッションの場合
- /etc/bash.bashrc
- ~/.bashrc
この場合、/etc/profile
も~/.profile
も読み込まれない。/etc/profile
では
/etc/bash.bashrc
の読み込み/etc/profile.d/*.sh
の読み込み
が実行されている。
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "$PS1" ]; then
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
つまり、/etc/profile.d
の配下にrbenvやnodebrewといったツールの環境変数設定用スクリプトを置いても、non interactiveセッションでは適用されない。Capistranoでデプロイする時の落とし穴であった。
さらに、non interactiveセッションの場合([ -z "$PS1" ]
)、/etc/bash.bashrc
ではすぐにreturnされているので、このスクリプトも実質的に何も実行されないのと変わらない。
# System-wide .bashrc file for interactive bash(1) shells.
# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
というわけで、Ubuntu 16.04でnon interactiveセッションでも環境変数などの設定ができる唯一の場所は~/.bashrc
となる。