日常的にMacやLinux(WSL含む)を利用しているんですが、基本的には各OSのデフォルトシェルを使いたいので、bashとzshのどちらを使ったとしても、なるべく動きが同じになるように.bashrcや.zshrcをカスタマイズして、プロンプトもなるべく見た目が同じになるようにしています。
zshの右プロンプトや、コマンドを実行したら右プロンプトが消えるようにするtransient_rpromptが便利で重宝してるんですが、transient_rpromptと同じ機能がbashにはない。
そこでzshのtransient_rpromptをbashで再現した設定がこちら。
# プロンプト
ZLE_RPROMPT_INDENT=0
PROMPT="%{${fg[blue]}%}%n%{${reset_color}%}@%{${fg[green]}%}%m%{${reset_color}%} %# "
RPROMPT="[ %{${fg[yellow]}%}%~%{${reset_color}%} ]"
setopt transient_rprompt # コマンド実行時に右プロンプトを消す
一方、.bashrcの抜粋はこちら
クリックして全て表示
# --- PROMPT ---
blue_p="\[\e[34m\]"
green_p="\[\e[32m\]"
reset_p="\[\e[0m\]"
if [ "${BASH_VERSINFO[0]}" -ge 4 ]; then
# ===== Bash 4+: 右プロンプト + transient =====
_RPROMPT_LEN=0
_rprompt_erase() {
[[ "${BASH_COMMAND}" == "_build_prompt" ]] && return
(( _RPROMPT_LEN > 0 )) && \
printf "\033[999C\033[%dD\033[K\r" "$_RPROMPT_LEN"
}
trap '_rprompt_erase' DEBUG
_build_prompt() {
local symbol="$"
[[ $UID -eq 0 ]] && symbol="#"
local cur_dir="${PWD/$HOME/\~}"
local r_len=$(( ${#cur_dir} + 4 ))
local col=$(( COLUMNS - r_len ))
(( _RPROMPT_LEN > 0 )) && \
printf "\033[%dG\033[K" $(( COLUMNS - _RPROMPT_LEN + 1 ))
_RPROMPT_LEN=$r_len
printf "\033[%dG[ \033[33m%s\033[0m ]\r" "$(( col + 1 ))" "$cur_dir"
PS1="${blue_p}\u${reset_p}@${green_p}\h${reset_p} ${symbol} "
}
# \C-m → 未使用キー(\C-o)に付け替え
# \C-o → _transient_enter(関数) → \C-o は元々 operate-and-get-next
# という多段は複雑なので、シンプルに:
_transient_enter() {
(( _RPROMPT_LEN > 0 )) && \
printf "\033[999C\033[%dD\033[K\r" "$_RPROMPT_LEN" > /dev/tty
}
# \C-m に「_transient_enter を実行してから accept-line」を設定
bind -x '"\C-x\C-e": _transient_enter' # 未使用キーに関数を割り当て
bind '"\C-m": "\C-x\C-e\C-j"' # Enter → 関数起動 → \C-j(accept-line)
bind '"\C-j": accept-line' # \C-j は素のaccept-line(再帰しない)
else
# ===== Bash 3.x: 右プロンプトあり(transientなし)=====
[[ "$(uname)" == "Darwin" ]] && export BASH_SILENCE_DEPRECATION_WARNING=1
_build_prompt() {
local symbol="$"
[[ $UID -eq 0 ]] && symbol="#"
local cur_dir="${PWD/$HOME/~}"
local cols=${COLUMNS:-$(tput cols)}
local r_len=$(( ${#cur_dir} + 4 ))
local col=$(( cols - r_len ))
printf "\033[%dG[ \033[33m%s\033[0m ]\r" "$(( col + 1 ))" "$cur_dir"
PS1="${blue_p}\u${reset_p}@${green_p}\h${reset_p} ${symbol} "
}
fi
# 共通設定
PROMPT_COMMAND=_build_prompt
hwd() { PROMPT_COMMAND=''; PS1="${blue_p}\u${reset_p}@${green_p}\h${reset_p} \$ "; }
swd() { PROMPT_COMMAND=_build_prompt; }
# --- End PROMPT ---
Macの場合、デフォルトがbash 3.xなので、右プロンプトを自動的に消すのはあきらめて、pwd(print w orking directory)に似せた以下のコマンドで表示・非表示を切り替えられるようにしています。
| コマンド | 補足 |
|---|---|
| hwd | hide working directory |
| swd | show working directory |
主なLinuxディストリビューションなど、bash 4.x以上の場合は、zshみたいにコマンド実行時に右プロンプトが消えるようにできました。
例えばWSL上のUbuntuではこんな動きになります。
user@wsl % bash
user@wsl $ bash --version
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
user@wsl $ ls -l
total 8
-rw-r--r-- 1 user user 7 4月 12 15:54 sample.txt
-rw-r--r-- 1 user user 39 4月 12 15:57 test.md
user@wsl $ [ /tmp/test ]
zshの場合はこんな感じ
user@wsl $ zsh
user@wsl % ls -l
total 8
-rw-r--r-- 1 user user 7 4月 12 15:54 sample.txt
-rw-r--r-- 1 user user 39 4月 12 15:57 test.md
user@wsl % pwd
/tmp/test
user@wsl % [ /tmp/test ]
超細かいですが、zshなら % 、bashは $ となっているので、そこを見ればどちらを使っているか見分けられるようになっています。