Je suis sûr que j'ai vu que quelqu'un a une partie de leur invite alignée à droite dans la fenêtre de leur borne, puis au départ du curseur réel sur une deuxième ligne. Je sais que je peux atteindre la deuxième ligne avec un "\ n" dans le PS1, mais je ne peux pas comprendre comment aligner la partie de cela à droite. Était ce que j'ai vu juste des espaces ajoutés entre les deux cordes?
Ce que vous voulez peut assez facilement être fait en affichant la première ligne avant d'afficher l'invite. Par exemple, les éléments suivants affichent une invite de \w
à gauche de la première ligne et une invite de \u@\h
à droite de la première ligne. Il utilise le $COLUMNS
variable contenant la largeur du terminal et le $Prompt_COMMAND
Paramètre qui est évalué avant que Bash affiche l'invite.
print_pre_Prompt ()
{
PS1L=$PWD
if [[ $PS1L/ = "$HOME"/* ]]; then PS1L=\~${PS1L#$HOME}; fi
PS1R=$USER@$HOSTNAME
printf "%s%$(($COLUMNS-${#PS1L}))s" "$PS1L" "$PS1R"
}
Prompt_COMMAND=print_pre_Prompt
Sur la base des informations que j'ai trouvées ici, j'ai pu découvrir une solution plus simple à un alignement correct tout en accumulant une teneur en longueur variable à droite ou à gauche, y compris la prise en charge de la couleur. Ajouté ici pour votre commodité ...
Remarque sur les couleurs : en utilisant le \033
échapper en faveur des alternatives, sans \[\]
groupements, prouve le plus compatible et celui-ci recommandé.
L'astuce consiste à écrire d'abord le côté droit, puis utilisez le retour du chariot (\r
) Pour revenir au début de la ligne et continuer à écraser le contenu latéral gauche en plus de cela, comme suit:
Prompt() {
PS1=$(printf "%*s\r%s\n\$ " "$(tput cols)" 'right' 'left')
}
Prompt_COMMAND=Prompt
J'utilise tput cols
sur Mac OS X pour récupérer la largeur du terminal/de la console de terminfo
depuis mon $COLUMNS
var n'est pas renseigné dans env
mais vous pouvez remplacer le "*
"valeur dans %*s
, en fournissant "${COLUMNS}
", ou toute autre valeur que vous préférez, à la place.
L'exemple suivant utilise $RANDOM
Pour générer un contenu de longueur différente inclut les couleurs et montre comment extraire des fonctions pour refacturer la mise en œuvre sur des fonctions réutilisables.
function Prompt_right() {
echo -e "\033[0;36m$(echo ${RANDOM})\033[0m"
}
function Prompt_left() {
echo -e "\033[0;35m${RANDOM}\033[0m"
}
function Prompt() {
compensate=11
PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(Prompt_right)" "$(Prompt_left)")
}
Prompt_COMMAND=Prompt
Etant donné que printf
suppose que la longueur de la chaîne soit le nombre de caractères que nous devons compenser la quantité de caractères requise pour rendre les couleurs, vous le trouverez toujours à la fin de l'écran en raison de l'ANSI non imprimé. caractères sans compensation. Les caractères requis pour la couleur restent constants et vous constaterez que, aussi, PrintF prend en compte la longueur de la longueur, comme retourné par $RANDOM
Par exemple ', qui maintient notre bon alignement dans le tact.
Ce n'est pas le cas avec des séquences d'échappement rapides de Bash spéciales (c.-à-d. \u
, \w
, \h
, \t
) cependant, comme cela ne fera que enregistrer une longueur de 2 car Bash les traduira que lorsque l'invite est affichée, une fois que PrintF a rendu la chaîne. Cela n'affecte pas le côté gauche mais préférable de les éviter à droite.
D'aucune conséquence si le contenu généré restera à une longueur constante. Comme avec le temps \t
Option qui rendra toujours la même quantité de caractères (8) pour 24 heures. Nous n'avons besoin que de prendre en compte la compensation requise pour accueillir la différence entre 2 caractères comptés, ce qui entraîne 8 caractères lorsqu'il est imprimé, dans ces cas.
Gardez à l'esprit que vous devrez peut-être tripler échapper \\\
Certaines séquences d'échappement qui tiennent autrement une signification à des cordes. Comme avec l'exemple suivant, la répertoire de travail actuelle Escape \w
ne tient aucune signification autrement, donc cela fonctionne comme prévu, mais le temps \t
, ce qui signifie un caractère d'onglets, ne fonctionne pas comme prévu sans triple l'échappant en premier.
function Prompt_right() {
echo -e "\033[0;36m\\\t\033[0m"
}
function Prompt_left() {
echo -e "\033[0;35m\w\033[0m"
}
function Prompt() {
compensate=5
PS1=$(printf "%*s\r%s\n\$ " "$(($(tput cols)+${compensate}))" "$(Prompt_right)" "$(Prompt_left)")
}
Prompt_COMMAND=Prompt
nJOY!
En utilisant printf
avec $COLUMNS
Très bien, quelque chose comme:
printf "%${COLUMNS}s\n" "hello"
Il est juste la justifié parfaitement pour moi.
Je pensais juste que je voudrais jeter le mien ici. C'est presque la même chose que l'invite de GML ZSH (à l'exception des mises à jour de ZSH, il est un peu plus rapide sur de nouvelles lignes et espaces de dos - ce qui est impossible à reproduire en bash ... bien très difficile à ce stade, au moins).
J'ai passé trois bonnes journées à ce sujet (seulement testé sur un ordinateur portable en cours d'exécution), alors voici une capture d'écran et ensuite les choses qui vont dans mon ~/.bashrc :)
AVERTISSEMENT - C'est un peu fou
Mis à part - Chaque ^[
(tel que ^[[34m
) est vraiment le personnage d'évacuation (char)27
. La seule façon de savoir comment insérer ceci est d'entrer ctrl+ ([v) (c'est-à-dire frappé les deux [ et v tandis que ctrl est maintenu en panne.
# grml battery?
GRML_DISPLAY_BATTERY=1
# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
_PS1_bat_dir='BAT0';
else
_PS1_bat_dir='BAT1';
fi
# ps1 return and battery
_PS1_ret(){
# should be at beg of line (otherwise more complex stuff needed)
RET=$?;
# battery
if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
# linux
STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
if [ "$STATUS" = "Discharging" ]; then
bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
Elif [ "$STATUS" = "Charging" ]; then
bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
Elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
else
bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
fi;
fi
fi
if [[ "$RET" -ne "0" ]]; then
printf '\001%*s%s\r%s\002%s ' "$(tput cols)" ":( $bat " "^[[0;31;1m" "$RET"
else
printf '\001%*s%s\r\002' "$(tput cols)" "$bat "
fi;
}
_HAS_GIT=$( type 'git' &> /dev/null );
# ps1 git branch
_PS1_git(){
if ! $_HAS_GIT; then
return 1;
fi;
if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then
return 2;
fi
branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )"
if [ "$branch" ]; then
printf ' \001%s\002(\001%s\002git\001%s\002)\001%s\002-\001%s\002[\001%s\002%s\001%s\002]\001%s\002' "^[[0;35m" "^[[39m" "^[[35m" "^[[39m" "^[[35m" "^[[32m" "${branch}" "^[[35m" "^[[39m"
fi;
}
# grml PS1 string
PS1="\n\[\e[F\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "
Je travaille toujours sur la configuration des couleurs, mais je suis content des couleurs telles qu'elles sont maintenant.
Travailler actuellement sur une solution pour le fou ^[
caractère et commutation de couleur facile :)
Voici une solution basée sur Prompt_COMMAND
et tput
:
function __Prompt_command() {
local EXIT="$?" # This needs to be first
history -a
local COL=$(expr `tput cols` - 8)
PS1="???? \[$(tput setaf 196)\][\[$(tput setaf 21)\]\W\[$(tput setaf 196)\]]\[$(tput setaf 190)\]"
local DATE=$(date "+%H:%M:%S")
if [ $EXIT != 0 ]; then
PS1+="\[$(tput setaf 196)\]\$" # Add red if exit code non 0
tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 196)$DATE"; tput rc
else
PS1+="\[$(tput setaf 118)\]\$"
tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 118)$DATE"; tput rc
fi
PS1+="\[$(tput setaf 255)\] "
}
Prompt_COMMAND="__Prompt_command"
La magie est effectuée par:
tput sc;tput cuu1; tput cuf $COL;echo "$(tput setaf 196)$DATE"; tput rc
Qui est décomposé par:
tput sc # saved the cursor position
tput cuu1 # up one line
tput cuf $COL # move $COL characters left
echo "$(tput setaf 196)$DATE" # set the colour and print the date
tput rc # restore the cursor position
En PS1, tput
est échappé avec\[\] de sorte qu'il ne soit pas compté dans la longueur affichée.
Ajout de la réponse de Giles, j'ai écrit quelque chose pour mieux gérer les couleurs (à condition qu'ils soient correctement enfermés dans \[
et \]
. C'est cas par cas et ne gère pas chaque cas, mais cela me permet de régler mon ps1l dans la même syntaxe que PS1 et utilise la date (non colorée) comme PS1R.
function title {
case "$TERM" in
xterm*|rxvt*)
echo -en "\033]2;$1\007"
;;
*)
;;
esac
}
print_pre_Prompt() {
PS1R=$(date)
PS1L_exp="${PS1L//\\u/$USER}"
PS1L_exp="${PS1L_exp//\\h/$HOSTNAME}"
SHORT_PWD=${PWD/$HOME/~}
PS1L_exp="${PS1L_exp//\\w/$SHORT_PWD}"
PS1L_clean="$(sed -r 's:\\\[([^\\]|\\[^]])*\\\]::g' <<<$PS1L_exp)"
PS1L_exp=${PS1L_exp//\\\[/}
PS1L_exp=${PS1L_exp//\\\]/}
PS1L_exp=$(eval echo '"'$PS1L_exp'"')
PS1L_clean=$(eval echo -e $PS1L_clean)
title $PS1L_clean
printf "%b%$(($COLUMNS-${#PS1L_clean}))b\n" "$PS1L_exp" "$PS1R"
}
Ici, c'est sur GitHub: dbartett/dotfiles/droit_promppt.sh . Je l'utilise dans mon .bashrc comme ceci:
source $HOME/dotfiles/right_Prompt.sh
PS1L='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]'
PS1='\[\033[01;34m\]\w\[\033[00m\]\$ '
Prompt_COMMAND=print_pre_Prompt
Remarque: J'ai également ajouté une nouvelle ligne après la PS1R, ce qui ne fait aucune différence visuelle, mais semble conserver l'invite de se faire brandir si vous faites défiler les commandes de votre historique de commandement.
Je suis sûr que quelqu'un d'autre peut s'améliorer à ce sujet, et peut-être généraliser une partie de l'inessesse spéciale.