私はUbuntu 18.04を実行しており、次のようにbashプロンプトを設定したいと思います。
user:~/Documents [14:22:07] 1 $
私のPS1は次のとおりです
ALERT_COLOR="$(tput setaf 1)"
# Display unsuccessful exit codes
function exit_status {
last_status=$?
if [[ $last_status != 0 ]]; then
echo "$ALERT_COLOR[$last_status]"
fi
}
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u:\[\033[01;34m\]\w\[\033[01;31m\]$(parse_git_branch)\[\033[00m\] \[\033[36m\][\t] \[$ALERT_COLOR\]$exit_status \[\033[0;37m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u:\w$(parse_git_branch)\$ '
fi
unset color_prompt force_color_prompt
終了コードを除いて、すべてがうまく機能します。終了コードは表示されません。$?
PS1でこれを行うと、常に表示されます。0
答え1
問題はここにあります:
PS1='...\[$ALERT_COLOR\]$exit_status ...\$ '
^^
これはパラメータ拡張であるため、設定した関数は呼び出されません。たとえば$(exit_status)
、fromなどのコマンド置換から関数を呼び出す必要がありますPROMPT_COMMAND
。これは脱出に注意してください\[ .. \]
。 Bashはこれを解釈します。今後プロンプトは別の拡張であるため、プロンプト文字列にハードコードする必要があります(プロンプトで拡張変数やその他の項目の一部にすることはできません)。
変数を拡張せずに素早く逃げることがあなたに逆さまに見える場合、私はあなたを責めることはできません。しかし、このように記録されています。:
また、次の表では、プロンプト変数に表示される特殊文字について説明します
PS1
。PS4
[...] 文字列をデコードした後、パラメータ拡張、コマンド置換による拡張、[...]
次のように動作する必要があります。
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
set_exit_color() {
if [ "$?" != 0 ]; then
exit_color=$red_color
else
exit_color=$normal_color
fi
}
PROMPT_COMMAND=set_exit_color
PS1='\[$exit_color\][$?]\[$normal_color\] \w\$ '
終了状態を維持するには一時変数が必要だと思いましたが、明らかにプロンプトで拡張された値は変更PROMPT_COMMAND
されません。$?
プロンプト文字列内でコマンド置換を使用して関数を呼び出す場合は、コマンド置換の終了コードが適用されるため、回避策が必要です。このような:
normal_color=$'\033[00m'
red_color=$'\033[41m'
exit_color=$normal_color
exit_color() {
exit_code=$?
if [ "$exit_code" != 0 ]; then
echo "$red_color"
else
echo "$normal_color"
fi
return "$exit_code"
}
PS1='\[$(exit_color)\][$?]\[$normal_color\] \w\$ '
コマンドの置換によって引き起こされるサブシェル分岐を保存するためにwithバージョンを使用しますPROMPT_COMMAND
が、実際にはほとんど効果がありません。
答え2
私は3行のプロンプトが欲しいので、次のようにします。
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 10:56:52
jackman@jackmanVM:~/tmp
+$ cat ~/.bash_prompt
# ... some other stuff ...
__bash_prompt() {
local last_status=$1
local cwd=$( sed "s,^$HOME,~," <<<"$PWD" )
local user_host_path="${debian_chroot:+($debian_chroot) }$(id -un)@$(hostname -s):$cwd"
# terminal title
echo -ne "\e]0;$user_host_path\a"
# separator and date
local char="۰"
printf "%s bash %s " "$(jot -s "" -b "$char" $(( $(tput cols) - 18 )) )" "$char$char"
date '+%T'
if ((last_status != 0)); then
local color_bold='\e[0;1m'
local color_reset='\e[0m'
printf "$color_bold[%d]$color_reset " $last_status
fi
# user@host, directory, git branch
printf "%s%s\n" "${user_host_path}$(git_current_branch " (%s)")"
}
# ref: https://stackoverflow.com/questions/1039713/different-bash-prompt-for-different-vi-editing-mode
# a single-line PS1 allows the show-mode-in-prompt inputrc setting to be useful
PROMPT_COMMAND='__bash_prompt $?'
PS1='\$ '
~/.bashrcからファイルを取得します。
終了ステータスは次のように表示されます
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:10
jackman@jackmanVM:~/tmp
+$ sh -c 'exit 42'
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:14
[42] jackman@jackmanVM:~/tmp
+$ false
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:16
[1] jackman@jackmanVM:~/tmp
+$ true
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 11:05:17
jackman@jackmanVM:~/tmp
+$
関数で最初にすることは、他のコマンドを実行する前に最後の終了状態を保存することです。
私はPROMPT_COMMANDを使ってすべての素晴らしいものを出力し、viモードを使用してviモードインジケータを見るのが好きなので、単純なPS1しか持っていません。私もこれを持っています:
۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰۰ bash ۰۰ 10:57:21
jackman@jackmanVM:~/tmp
+$ cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
$if Bash
# not until bash 4.4, I believe
# escape sequences: https://stackoverflow.com/a/42107711/7552
#set vi-ins-mode-string "+\1\e[5 q\2"
#set vi-cmd-mode-string ":\1\e[1 q\2"
set vi-ins-mode-string +
set vi-cmd-mode-string :
$endif
私は使う魚ログインシェルとして使用し、時にはkshに使用するため、プロンプト区切り文字にシェル名を入れて、入力している内容を追跡できます。