CloudShell のシェルプロンプトが [cloudshell-user@ip-xx-xx-xx-xx ~]$ から ~ $ に変わっていたので調べてみた
コーヒーが好きな emi です。
最近、比較的新しい AWS アカウントで初めて CloudShell を使ったらシェルプロンプトが [cloudshell-user@ip-xx-xx-xx-xx ~]$
から ~ $
になっているのに気付きました。もっと前から変わっていたのかもしれないのですが、本件について調査してみたのでメモとして残しておきます。
これまでの CloudShell
これまでは以下のようにプロンプトに [cloudshell-user@ip-xx-xx-xx-xx ~]$
と表示されていました。
新しい CloudShell
新しいアカウント、もしくは初めて CloudShell を使うアカウントでは、以下のように ~ $
と表示されるようです。
最初に結論
プロンプトが ~ $
になっている原因は、~/.bashrc
で PS1
の設定が export PS1='\W $ '
に変わったからのようです。
再起動などを試す
特に問題なくそのまま利用できますが、再読み込みなどで元のプロンプトに戻るかもしれないと思い、いくつか試行してみました。
1. exit でセッション終了して再接続する
exit
を実行して CloudShell を終了し、再度開いてみます。一時的な環境ロードの遅れが原因の場合はこれで以前のシェルプロンプトに戻るかもしれません。
[exited] となりました。Enter を押下して再度プロンプトに戻ります。
変わりませんね。
2. シェルをリロードしてみる
exec $SHELL
で現在のシェルをリロードしてみます。
▼実行結果
~ $ exec $SHELL
~ $
変わりませんね。
補足: exec $SHELL について
長めの補足です。ブログの本筋とは関係ないので読み飛ばしていただいて構いません。
$SHELL
は現在のユーザーのデフォルトログインシェル
◆ $SHELL
は、現在のユーザーのデフォルトのログインシェルを示す環境変数- 「ユーザーがログインしたときに最初に起動するシェルのパス」が格納されている
~ $ echo $SHELL
/bin/bash
~ $
- ログインシェル(Login Shell)ユーザーがシステムにログインしたときに最初に起動されるシェルのこと
- ログインシェルでないシェルはサブシェル(Non-login Shell)と呼ばれ、ターミナルの中で新しく起動されるシェルのこと
ログインシェル (Login Shell) | 非ログインシェル (Non-login Shell) | |
---|---|---|
起動のタイミング | SSH ログイン時 | すでに開いているシェルの中でbash を実行したとき |
設定ファイルの適用 | ~/.bash_profile , ~/.profile , /etc/profile など |
~/.bashrc |
環境変数の適用 | システムの初期設定を読み込む | すでに設定された環境変数を引き継ぐ |
確認方法 | echo $0 → -bash のように - が付いている |
echo $0 → bash または /usr/bin/bash (プレフィックスなし) |
ログインシェルで起動したいケース
.bash_profile
や.profile
の環境変数を適用したい場合- システムのログイン時と同じ環境を再現したい場合
exec
コマンドを使わない場合
◆ 今のプロセス ID が 500 だとすると、
$ ls
という外部コマンドを実行する前、新しいプロセス ID(例えば 501)が生成され、新しいプロセス ID(501)で ls
コマンドが実行される。コマンド実行時に子プロセスを起動するということ。
exec
コマンドを使う場合
◆ 今のプロセス ID が 500 だとすると、
$ exec ls
を実行すると、元のプロセス ID 500 の中で ls
コマンドが実行される。
- 参考
exec $SHELL
を実行すると
◆ $SHELL
に格納されたパスのプログラムを実行するexec
により、現在のシェルプロセス(例えば PID 500)は終了せずに、新しいシェルプロセスが同じ PID 500 のまま実行される- つまり、シェルの置き換え(リロード)が行われる
===補足ここまで===
3. 再起動
CloudShell のアクションから再起動してみます。
変わりませんでした。
4. bash プロンプトの設定を手動で適用する
source ~/.bashrc
を実行し bash の設定を適用してみます。
▼実行結果
~ $ source ~/.bashrc
~ $
変わりませんでした。
補足: .bashrc について
補足です。ブログの本筋とは関係ないので読み飛ばしていただいて構いません。
.bashrc
は Bash シェルの設定ファイル であり、非ログインシェルが起動するときに実行されるスクリプト.bashrc
はホームディレクトリ (~/.bashrc
) にある隠しファイル.bashrc
の中には環境変数・エイリアス・プロンプトの設定 (PS1
) などを記述できる
~ $ ls -la ~
total 44
drwxrwxrwx. 4 cloudshell-user cloudshell-user 4096 Feb 14 02:57 .
drwxr-xr-x. 3 root root 4096 Feb 16 09:56 ..
-rw-------. 1 cloudshell-user cloudshell-user 198 Feb 16 08:16 .bash_history
-rw-r--r--. 1 cloudshell-user cloudshell-user 18 Feb 14 02:23 .bash_logout
-rw-r--r--. 1 cloudshell-user cloudshell-user 546 Feb 14 02:23 .bash_profile
-rw-r--r--. 1 cloudshell-user cloudshell-user 939 Feb 14 02:23 .bashrc
drwxr-xr-x. 4 cloudshell-user cloudshell-user 4096 Feb 14 02:23 .config
-rw-------. 1 cloudshell-user cloudshell-user 20 Feb 14 02:57 .lesshst
drwxr-xr-x. 4 cloudshell-user cloudshell-user 4096 Feb 14 02:27 .local
-rw-r--r--. 1 cloudshell-user cloudshell-user 684 Feb 14 02:23 .zprofile
-rw-r--r--. 1 cloudshell-user cloudshell-user 1174 Feb 14 02:23 .zshrc
~ $
===補足ここまで===
4. CloudShell 環境の確認
echo $USER
で現在のユーザー名を表示します。
▼実行結果
~ $ echo $USER
cloudshell-user
~ $
現在のユーザーは cloudshell-user
で、想定通りです。
続いて
hostname
で現在のマシン(ホスト)の名前を表示してみます。
▼実行結果
~ $ hostname
bash: hostname: command not found
~ $
なるほど、CloudShell に hostname
コマンドはインストールされていないか、パスが通っていないようです。
.bashrc
の設定を新旧 CloudShell で比較する
cat ~/.bashrc
を実行して新旧 .bashrc
の設定を比較してみます。
~ $
)の .bashrc
新しい CloudShell(~ $ cat ~/.bashrc
# Amazon Q pre block. Keep at the top of this file.
[[ -f "${HOME}/.local/share/amazon-q/shell/bashrc.pre.bash" ]] && builtin source "${HOME}/.local/share/amazon-q/shell/bashrc.pre.bash"
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
if [ -d ~/.bashrc.d ]; then
for rc in ~/.bashrc.d/*; do
if [ -f "$rc" ]; then
. "$rc"
fi
done
fi
unset rc
complete -C '/usr/local/bin/aws_completer' aws
export PS1='\W $ '
# Amazon Q post block. Keep at the bottom of this file.
[[ -f "${HOME}/.local/share/amazon-q/shell/bashrc.post.bash" ]] && builtin source "${HOME}/.local/share/amazon-q/shell/bashrc.post.bash"
~ $
[cloudshell-user@ip-xx-xx-xx-xx ~]$
)の .bashrc
古い CloudShell([cloudshell-user@ip-10-132-70-78 ~]$ cat ~/.bashrc
# Amazon Q pre block. Keep at the top of this file.
[[ -f "${HOME}/.local/share/amazon-q/shell/bashrc.pre.bash" ]] && builtin source "${HOME}/.local/share/amazon-q/shell/bashrc.pre.bash"
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=
# User specific aliases and functions
complete -C '/usr/local/bin/aws_completer' aws
export AWS_EXECUTION_ENV=CloudShell
# Amazon Q post block. Keep at the bottom of this file.
[[ -f "${HOME}/.local/share/amazon-q/shell/bashrc.post.bash" ]] && builtin source "${HOME}/.local/share/amazon-q/shell/bashrc.post.bash"
[cloudshell-user@ip-10-132-70-78 ~]$
主な違い
PS1
) の有無
1. プロンプト設定 (- プロンプトが
~ $
になっている新しいアカウントにはexport PS1='\W $ '
という設定があるPS1
は Bash のプロンプトを設定する環境変数\W
は現在のディレクトリの最後の部分だけを表示する (=basename $PWD
) が、ホームディレクトリ ($HOME
) にいる場合、\W
は~
に置き換えられるという Bash の仕様のためプロンプトが~ $
になる
補足: \W について
PS1
は Bash のプロンプトを設定する環境変数です。
PS1='MyPrompt> '
というように設定すると、プロンプトが MyPrompt>
に変わります。
PS1
では以下のように特別なエスケープシーケンスを使うことができます。
記号 | 意味 |
---|---|
\u |
ユーザー名 |
\h |
ホスト名(最初の部分) |
\H |
ホスト名(フル) |
\w |
現在のディレクトリ(フルパス) |
\W |
現在のディレクトリ(最後の部分) |
\d |
日付(例: "Mon Feb 19") |
\t |
時間(HH:MM:SS) |
\T |
12時間形式の時間 |
\@ |
AM/PM 付きの時間 |
\n |
改行 |
\$ |
標準ユーザーなら $ 、root ユーザーなら # |
basename
は、パスの最後の部分(ディレクトリ名やファイル名)だけを取得するコマンドです。
▼実行結果例
~ $ basename /home/cloudshell-user
cloudshell-user
~ $
$PWD
は「現在のディレクトリの絶対パス」を示す環境変数です。
▼実行結果例
~ $ echo $PWD
/home/cloudshell-user
~ $
したがって以下のようになります。
▼実行結果例
~ $ basename $PWD
cloudshell-user
~ $
\W
は basename $PWD
と同様、現在のディレクトリの「最後の部分」だけを表示しますが、ホームディレクトリ ($HOME
) にいる場合、\W
は ~
に置き換えられるという Bash の仕様があります。
このため
PS1='\W $ '
を実行すると、プロンプトが ~ $
になります。
===補足ここまで===
- プロンプトが
[cloudshell-user@ip-xx-xx-xx-xx ~]$
になっている古いアカウントには.bashrc
にPS1
の設定がないため、デフォルトの Bash のプロンプト ([cloudshell-user@ip-xxx-xxx-xxx-xxx ~]$
) が適用されている
AWS_EXECUTION_ENV=CloudShell
の設定
2. 環境変数 - プロンプトが
[cloudshell-user@ip-xx-xx-xx-xx ~]$
になっている古いアカウントには設定されているが、プロンプトが~ $
になっている新しいアカウントにはない
PATH
の設定
3. - プロンプトが
~ $
になっている新しいアカウントでは、以下のようにPATH
変数が変更されている
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH
- プロンプトが
[cloudshell-user@ip-xx-xx-xx-xx ~]$
になっている古いアカウントにはこの設定がない
~/.bashrc.d/
の設定
4. - プロンプトが
~ $
になっている新しいアカウントでは、~/.bashrc.d/
にある設定ファイルをロードする処理がある
if [ -d ~/.bashrc.d ]; then
for rc in ~/.bashrc.d/*; do
if [ -f "$rc" ]; then
. "$rc"
fi
done
fi
- プロンプトが
[cloudshell-user@ip-xx-xx-xx-xx ~]$
になっている古いアカウントにはこの処理がない
結論
プロンプトが ~ $
になっている原因は、~/.bashrc
で PS1
の設定が export PS1='\W $ '
に変わったからのようです。
元のプロンプトに戻してみる
プロンプトを元に戻せるか試してみます。
export PS1='[\u@\h \W]\$ '
\u
: ユーザー名 (cloudshell-user
)\h
: ホスト名 (ip-xxx-xxx-xxx-xxx
)\W
: 現在のディレクトリ
▼実行結果
~ $ export PS1='[\u@\h \W]\$ '
[cloudshell-user@ip-10-132-75-244 ~]$
[cloudshell-user@ip-10-132-75-244 ~]$
戻りました。
しかし、CloudShell を再起動すると元に戻ってしまいます。
この変更を永続化する場合は ~/.bashrc
に変更を書き込み保存します。
echo 'export PS1="[\u@\h \W]\\$ "' >> ~/.bashrc
▼実行結果
~ $ echo 'export PS1="[\u@\h \W]\\$ "' >> ~/.bashrc
~ $
~/.bashrc
を再読み込みします。
source ~/.bashrc
▼実行結果
~ $ source ~/.bashrc
[cloudshell-user@ip-10-134-29-109 ~]$
反映されました。
CloudShell を再起動します。
元のプロンプトに戻りました。
終わりに
CloudShell の ~/.bashrc
の設定が変わり、プロンプトが [cloudshell-user@ip-xx-xx-xx-xx ~]$
から ~ $
になったようです。AWS CLI を使う分には特に影響はありません。
ちょっとびっくりしたのと、「このコマンドは CloudShell で実行したんだぞ」というのを明確に確認するのに以前のプロンプト表示が分かりやすかったので、戻す方法も調べてみました。
本記事への質問やご要望については画面下部のお問い合わせ「DevelopersIO について」からご連絡ください。記事に関してお問い合わせいただけます。
参考