Edited at

Vagrantfile の Shell プロビジョンで anyenv のインストールなど `exec $SHELL -l` するような処理を書くとき

More than 1 year has passed since last update.


結論

exec $SHELL -l の代わりに、 . ~/.bash_profile とか . ~/.bashrc を適宜やろう。


. <FilePath> ってなんぞ

. (ドット1文字)っていうコマンドがあります。

bash の場合は、 sourceのエイリアスです。

Vagrant を使う際に、 Shell Provision で、 exec $SHELL -l したいときありますよね。 「anyenv を使って Node.js とかインストールしたい」とか「dotfiles をインストールして、それを読み込んだ前提で何か書きたい」っていうときです。


でも、 各種Provision のなかで exec $SHELL -l しても、 .bash_profile とかの更新分は、反映されません。 exec $SHELL したところで、その分の Shell プロビジョンが終了します。


exec $SHELL -l との違い

exec $SHELL -l は、現在のログインシェルを再起動する に近いです。(解説は『シェルを再起動させる簡単な方法』とか読むといいです。)

それに対して、 source は、読み込むファイルを明示しなければいけないので、シェルの起動プロセスとかを把握してないと使えないです。


  • 使用する shell に応じて、 source するファイルを変える

  • /etc/profile.d に追加するとかの場合は、そっちを source する


Shell プロビジョンが終了することの確認

以下のようなファイルを準備して、検証しました。

要するに、 Shell プロビジョン内で exec $SHELL はしてはいけない っぽいです。


Vagrantfile

Vagrant.configure("2") do |config|

config.vm.box = "centos/7"
# PID 確認
config.vm.provision :shell, inline: 'ps -f | egrep "$$|PID"'
config.vm.provision :shell, inline: 'ps -f | egrep "$$|PID"'
# anyenv で git 使う
config.vm.provision :shell, inline: "yum -y -q install git"
config.vm.provision :shell, "privileged": false, path: "./anyenv.sh"
###
config.vm.provision :shell, "privileged": false, path: "./nodenv.sh"
end


anyenv.sh

echo anyenv.sh

echo tick1
git clone https://github.com/riywo/anyenv ~/.anyenv
echo tick2
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
echo tick3
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
echo tick4
exec $SHELL -l
echo tick5
exec $SHELL
echo tick6
anyenv install nodenv
echo tick7
exec $SHELL -l
echo tick8
exec $SHELL
echo tick9



nodenv.sh

echo nodenv.sh

echo tick101
anyenv install nodenv
echo tick102
exec $SHELL -l
echo tick103
exec $SHELL
echo tick104
nodenv install 6.9.5
echo tick105

出力結果

C:\tmp\vm>vagrant destroy -f && vagrant up

==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos/7'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'centos/7' is up to date...
==> default: Setting the name of the VM: vm_default_1489040647386_94904
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2200
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: No guest additions were detected on the base box for this VM! Guest
default: additions are required for forwarded ports, shared folders, host only
default: networking, and more. If SSH fails on this machine, please install
default: the guest additions and repackage the box to continue.
default:
default: This is not an error message; everything may continue to work properly,
default: in which case you may ignore this message.
==> default: Rsyncing folder: /cygdrive/c/tmp/vm/ => /vagrant
==> default: Running provisioner: shell...
default: Running: inline script
==> default: UID PID PPID C STIME TTY TIME CMD
==> default: root 10106 10097 0 06:24 ? 00:00:00 bash -l
==> default: root 10107 10106 0 06:24 ? 00:00:00 ps -f
==> default: root 10108 10106 0 06:24 ? 00:00:00 grep -E 10106|PID
==> default: Running provisioner: shell...
default: Running: inline script
==> default: UID PID PPID C STIME TTY TIME CMD
==> default: root 10181 10172 0 06:24 ? 00:00:00 bash -l
==> default: root 10182 10181 0 06:24 ? 00:00:00 ps -f
==> default: root 10183 10181 0 06:24 ? 00:00:00 bash -l
==> default: Running provisioner: shell...
default: Running: inline script
==> default: Public key for perl-Carp-1.26-244.el7.noarch.rpm is not installed
==> default: warning: /var/cache/yum/x86_64/7/base/packages/perl-Carp-1.26-244.el7.noarch.rpm: Header V3 RSA/SHA256 Sign
ature, key ID f4a80eb5: NOKEY
==> default: Importing GPG key 0xF4A80EB5:
==> default: Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
==> default: Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
==> default: Package : centos-release-7-3.1611.el7.centos.x86_64 (@anaconda)
==> default: From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
==> default: Running provisioner: shell...
default: Running: C:/Users/XXXXXX~1/AppData/Local/Temp/vagrant-shell20170309-8564-1mmitjh.sh
==> default: anyenv.sh
==> default: tick1
==> default: Cloning into '/home/vagrant/.anyenv'...
==> default: tick2
==> default: tick3
==> default: tick4
==> default: Running provisioner: shell...
default: Running: C:/Users/XXXXXX~1/AppData/Local/Temp/vagrant-shell20170309-8564-1dbhwan.sh
==> default: nodenv.sh
==> default: tick101
==> default: /tmp/nodenv.20170309062507.11853 ~
==> default: Cloning https://github.com/nodenv/nodenv.git...
==> default: Cloning into 'nodenv'...
==> default: ~
==> default: ~/.anyenv/envs/nodenv/plugins ~
==> default: Cloning https://github.com/nodenv/node-build.git...
==> default: Cloning into 'node-build'...
==> default: ~
==> default: ~/.anyenv/envs/nodenv/plugins ~
==> default: Cloning https://github.com/nodenv/nodenv-default-packages.git...
==> default: Cloning into 'nodenv-default-packages'...
==> default: ~
==> default: ~/.anyenv/envs/nodenv/plugins ~
==> default: Cloning https://github.com/nodenv/nodenv-vars.git...
==> default: Cloning into 'nodenv-vars'...
==> default: ~
==> default:
==> default: Install nodenv succeeded!
==> default: Please reload your profile (exec $SHELL -l) or open a new session.
==> default: tick102