Bash: jak się dowiedzieć, czy wyjście ostatniego polecenia kończy się na nowej linii, czy nie?

10

W większości przypadków wyjście polecenia kończy się znakiem nowej linii. Ale czasami tak nie jest, więc następny monit powłoki jest drukowany w tym samym wierszu wraz z wyjściem.

Przykład:

root @
nazwa hosta [~] # echo -n hello helloroot @ nazwa hosta [~] #

Zawsze uważałem to za bardzo denerwujące.
Teraz mógłbym po prostu dodać „\ n” na początku zmiennej PS1, ale przez większość czasu wydrukuje jedną dodatkową linię, której nie potrzebuję.

Czy można wiedzieć, czy wyjście ostatniego polecenia zakończyło się znakiem nowej linii, czy nie?


Rozwiązanie:
(Dzięki Dennis)

PS1='$(printf "%$((`tput cols`-1))s\r")\u@\h [\w]\$ '
Uwolnić się
źródło
Należy to przenieść do administratora.
ℝaphink
Podoba mi się twoja wersja! Użyłeś $()w jednym miejscu, a backty w innym. Możesz używać $()obu.
Wstrzymano do odwołania.
Wiem. Ale dla mnie łatwiej jest czytać w ten sposób
GetFree
Nie użyłbym tego, tput colsponieważ i tak wyświetla wartość zmiennej COLUMNS, i jest wolniejszy, ponieważ nie jest wbudowany w powłokę. Będziesz także chciał uwzględnić \e[K(równoważne tput el), aby usunąć wstawioną białą spację, aby nie dostać wiązki końcowych białych spacji podczas kopiowania i wklejania w przypadku domyślnym. Wreszcie, musisz zamknąć całą tę magię pomiędzy \[i, \]inaczej bash spróbuje odgadnąć twoją pozycję kursora i będzie bałagan, kiedy edytujesz swoje polecenie / historię.
dlitz
1
Wszystko to można zrobić tak:PS1='\[\e[7m%\e[m$( printf "%*s" "$((COLUMNS-1))" "" )\r\e[K\]\u@\h [\w]\$ '
dlitz

Odpowiedzi:

6

Eksperymentowałem z następującymi elementami, aby emulować tę funkcję zshw Bash:

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

Wydaje odwrotny znak procentu wideo, a następnie kilka spacji, aby zawinąć do następnej linii, następnie znak powrotu karetki, a następnie znak dolara i spację. Możesz dodać znaki zachęty po „\ 015”, aby dostosować monit.

Korzystanie z tego zależy od tego, jak terminal obsługuje owijanie prawego marginesu (automatyczne marginesy). Długość PROMPT_SP jest dowolna, ale powinna wynosić co najmniej 80 lub jakąkolwiek zwykłą szerokość terminala. Może zajść potrzeba zakodowania tej wartości, jeśli $ COLUMNS nie jest jeszcze ustawione do czasu uruchomienia forpętli ~/.bashrc. Możesz chcieć, shopt -s checkwinsizejeśli nie jest jeszcze ustawiony.

Wstrzymano do odwołania.
źródło
Zastanawiam się, dlaczego ktoś ocenił każdą odpowiedź . Hmmm ... bez wyjaśnienia. Jak pomocne.
Wstrzymano do odwołania.
Oto inny sposób, bez użycia pętli, aby utworzyć ciąg pada:printf -v PROMPT_SP '%*s' $((COLUMNS + 52)) ''
Wstrzymano do odwołania.
Co to jest „znak procentowy odwrotnego wideo”? Słowo „wideo” wprawiło mnie w zakłopotanie i nie udało mi się znaleźć odpowiedzi w Google.
davidchambers
1
@davidchambers: Tło postaci jest wyświetlane w kolorze pierwszego planu, a sama postać jest wyświetlana w kolorze tła. Zobacz man 5 terminfoi wyszukaj „wideo odwrócone”, aby zobaczyć dokumentację używającą tej terminologii.
Wstrzymano do odwołania.
0

Nie, to nie jest możliwe. Sam Bash nie przetwarza ani nie wyświetla danych wyjściowych uruchomionego programu.

Właśnie przyszło mi do głowy, że może być możliwe napisanie programu do ustawienia PROMPT_COMMAND, który sprawdzałby bieżącą pozycję kursora i wydawał nowy wiersz, gdyby kursor nie znajdował się na lewej krawędzi.

Miś
źródło
Dobry pomysł. Jedynym problemem jest ... czy można poznać pozycję kursora?
GetFree
0

zshpróbuje rozwiązać problem. Jeśli ostatnie wyjście zakończy się bez nowej linii, otrzymasz:

$ echo -n 'abc'
abc%
$ 

Gdzie %wykorzystuje odwrócone tło / pierwszy plan. Nie jestem pewien, czy jest bashw jakikolwiek sposób przenośny .

viraptor
źródło