Bash: comment savoir si la sortie de la dernière commande se termine par une nouvelle ligne ou non?

10

La plupart du temps, la sortie d'une commande se termine par le caractère de nouvelle ligne. Mais parfois, ce n'est pas le cas, donc l'invite suivante du shell est imprimée sur la même ligne avec la sortie.

Exemple:

root @ hostname [~] # echo -n bonjour
helloroot @ hostname [~] #

J'ai toujours trouvé ça très ennuyeux.
Maintenant, je pourrais simplement ajouter un "\ n" au début de la variable PS1, mais la plupart du temps cela imprimera une ligne supplémentaire dont je n'ai pas besoin.

Est-il possible de savoir si la sortie de la dernière commande s'est terminée par une nouvelle ligne ou non?


Solution:
(Merci à Dennis)

PS1='$(printf "%$((`tput cols`-1))s\r")\u@\h [\w]\$ '
GetFree
la source
Cela devrait être déplacé vers le superutilisateur.
ℝaphink
J'aime ta version! Vous l'avez utilisé $()à un endroit et vous avez fait des retours dans un autre. Vous pouvez utiliser $()dans les deux.
pause jusqu'à nouvel ordre.
Je sais. Mais pour moi, c'est plus facile à lire de cette façon
GetFree
Je ne l'emploierais pas tput colscar il ne produit que la valeur de la variable COLUMNS de toute façon, et il est plus lent car ce n'est pas un shell intégré. Vous souhaiterez également inclure \e[K(équivalent à tput el) pour supprimer les espaces insérés afin de ne pas obtenir un tas d'espaces de fin lors de la copie et du collage dans le cas par défaut. Enfin, vous devez inclure toute cette magie entre \[et \]sinon bash essaiera de deviner la position de votre curseur et cela gâchera lorsque vous éditerez votre commande / historique.
dlitz
1
Le tout peut être fait simplement:PS1='\[\e[7m%\e[m$( printf "%*s" "$((COLUMNS-1))" "" )\r\e[K\]\u@\h [\w]\$ '
dlitz

Réponses:

6

J'ai expérimenté les éléments suivants pour émuler la fonctionnalité de zshBash:

$ unset PROMPT_SP; for ((i = 1; i <= $COLUMNS + 52; i++ )); do PROMPT_SP+=' '; done
$ PS1='\[\e[7m%\e[m\]${PROMPT_SP: -$COLUMNS+1}\015$ '

Il émet un signe de pourcentage vidéo inverse, suivi d'un tas d'espaces pour le faire passer à la ligne suivante, puis d'un retour chariot, suivi d'un signe dollar et d'un espace. Vous pouvez ajouter des échappements d'invite après le "\ 015" pour personnaliser votre invite.

Son utilisation dépend de la façon dont votre terminal gère l'habillage de la ligne de marge droite (marges automatiques). La longueur de PROMPT_SP est arbitraire, mais doit être d'au moins 80 ou quelle que soit la largeur de terminal habituelle. Vous devrez peut-être coder en dur cette valeur si $ COLUMNS n'est pas encore défini au moment de l' forexécution de la boucle ~/.bashrc. Vous voudrez peut-être shopt -s checkwinsizesi ce n'est pas déjà fait.

En pause jusqu'à nouvel ordre.
la source
Je me demande pourquoi quelqu'un a voté pour chaque réponse . Hmmm ... aucune explication. Comme c'est utile.
pause jusqu'à nouvel ordre.
Voici une autre façon, sans utiliser de boucle, de créer la chaîne de pad:printf -v PROMPT_SP '%*s' $((COLUMNS + 52)) ''
pause jusqu'à nouvel ordre.
Qu'est-ce qu'un "signe de pourcentage de vidéo inversé"? Le mot "vidéo" m'a confondu et je n'ai pas pu trouver la réponse sur Google.
davidchambers
1
@davidchambers: l'arrière-plan du personnage est affiché dans la couleur de premier plan et le personnage lui-même est affiché dans la couleur d'arrière-plan. Voir man 5 terminfoet rechercher «vidéo inverse» pour voir une documentation qui utilise cette terminologie.
pause jusqu'à nouvel ordre.
0

Non ce n'est pas possible. Bash lui-même ne traite pas ou ne voit pas la sortie du programme qu'il a démarré.

Il m'est juste venu à l'esprit qu'il pourrait être possible d'écrire un programme à définir PROMPT_COMMAND, qui vérifierait la position actuelle du curseur et émettrait une nouvelle ligne si le curseur n'était pas sur le bord gauche.

Teddy
la source
Bonne idée. Le seul problème est ... est-il possible de connaître la position du curseur?
GetFree
0

zshessaie de résoudre votre problème. Si la dernière sortie se termine sans nouvelle ligne, vous obtiendrez:

$ echo -n 'abc'
abc%
$ 

%utilise l'arrière-plan / premier plan inversé. Je ne sais pas s'il est portable de bashquelque manière que ce soit.

viraptor
la source