tl;dr
-
source
で読み込んだスクリプト内でexit
すると、呼び出し元スクリプトごと終了する - ↑ を .bashrc でやってしまうとログインができなくなる
- そうなってしまったらログイン時に Ctrl+C を連打する
背景
自作の便利スクリプトをサーバーログイン時 (厳密には Bash 起動時) に実行させるようにしました。
[togawa@remote01 ~]$ echo 'source ./myscript.sh' >> ./.bashrc
このサーバーを remote01 とし、ログイン元サーバーを local01 とします。
問題
一度 remote01 からログアウトし、再度ログインしたところ そのままログアウト されてしまいました。
[togawa@remote01 ~]$ logout
Connection to xxx.xx.x.xx closed.
[togawa@local01 ~]$ ssh remote01
togawa@xxx.xx.x.xx's password:
Last login: Fri Feb 10 19:04:02 2017 from xxx.xx.x.xx
Connection to xxx.xx.x.xx closed.
[togawa@local01 ~]$
原因は以下の2つが成り立ってしまったためです。
- スクリプトを .bashrc の
source
から呼び出していること - スクリプト中で
exit
していること
試したこと
ssh rm
このままではサーバーにログインができません。
とはいえ、 .bashrc が発動する前に問題のスクリプト (myscript.sh) を消せれば良いはずです。
ssh
に引数を与えるとそれをコマンドとして実行してくれるので、 rm
を渡してみます。
[togawa@local01 ~]$ ssh remote01 rm myscript.sh
togawa@xxx.xx.x.xx's password:
Connection to xxx.xx.x.xx closed.
[togawa@local01 ~]$
結果はだめ。
scp
ssh がだめなら scp はどうだ、ということで空のファイルを転送してスクリプトを 0 byte にする作戦です。
[togawa@local01 ~]$ touch myscript.sh
[togawa@local01 ~]$ ls -l myscript.sh
-rw-r--r-- 1 togawa togawa 0 2月 10 19:48 myscript.sh
[togawa@local01 ~]$ scp ./myscript.sh remote01:~
togawa@xxx.xx.x.xx's password:
Connection to xxx.xx.x.xx closed.
[togawa@local01 ~]$
これもだめでした。 ssh/scp では律儀に .bashrc が読み込まれてしまいます。
Bash の起動を止める
ServerFault という Stackoverflow 風味のサイトでは、「.bashrc がロードされる前に Ctrl + C
で Bash の起動を中止させるといいよ」という回答がありました。
http://serverfault.com/questions/206544/i-screwed-up-exit-in-bashrc
ssh
実行 → ログイン先サーバーで bash 起動 → (*) → .bashrc ロード
↑ の (*) のタイミングで Ctrl + C
を叩け、とのこと。タイミングがシビアそう。
ssh
にデバッグモードの -v
オプションをつけてやってみました。
確かにコツが必要でしたが、成る程、何度かやったらうまくいきました。
[togawa@local01 ~]$ ssh -v remote01
OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
debug1: Reading configuration data /home/togawa/.ssh/config
debug1: Applying options for remote01
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to xxx.xx.x.xx [xxx.xx.x.xx] port 22.
debug1: Connection established.
debug1: identity file /home/togawa/.ssh/identity type -1
debug1: identity file /home/togawa/.ssh/id_rsa type 1
debug1: identity file /home/togawa/.ssh/id_dsa type -1
debug1: loaded 3 keys
debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1
debug1: match: OpenSSH_6.6.1 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_4.3
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'xxx.xx.x.xx' is known and matches the RSA host key.
debug1: Found key in /home/togawa/.ssh/known_hosts:42
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/togawa/.ssh/identity
debug1: Offering public key: /home/togawa/.ssh/id_rsa
debug1: Authentications that can continue: publickey,password
debug1: Trying private key: /home/togawa/.ssh/id_dsa
debug1: Next authentication method: password
togawa@xxx.xx.x.xx's password:
debug1: Authentication succeeded (password).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = ja_JP.UTF-8
Last login: Fri Feb 10 19:30:13 2017 from xxx.xxx.x.xx
^C-bash-4.2$ ^C
-bash-4.2$ ^C
-bash-4.2$ ^C
-bash-4.2$ ^C
-bash-4.2$ ^C
-bash-4.2$
-bash-4.2$ ls
myscript.sh
-bash-4.2$ rm myscript.sh
-bash-4.2$ ls
-bash-4.2$
-bash-4.2$
Bash キャンセル (各ゲーっぽい) が成功すると $PS1
が読み込まれていない、すなわち .bashrc が読み込まれていないことがわかります。
これによりログイン先サーバーで操作が可能になるので、問題のスクリプトを rm
すれば万事解決です。
教訓
シェルスクリプトではむやみに source
を使わない。