PROMPT_COMMAND może zawierać zwykłe instrukcje bash, podczas gdy zmienna PS1 może również zawierać w zmiennej znaki specjalne, takie jak „\ h” dla nazwy hosta.
Na przykład tutaj jest moja zachęta bash, która używa zarówno PROMPT_COMMAND, jak i PS1. Kod bash w PROMPT_COMMAND sprawdza, w jakiej gałęzi git możesz się znajdować i wyświetla to po znaku zachęty, wraz z kodem zakończenia ostatniego uruchomionego procesu, nazwą hosta i podstawową nazwą pwd. Zmienna RET przechowuje wartość zwracaną przez ostatnio wykonany program. Jest to wygodne, aby sprawdzić, czy wystąpił błąd i kod błędu ostatniego programu, który uruchomiłem w terminalu. Zwróć uwagę na zewnętrzne „otaczające całe wyrażenie PROMPT_COMMAND. Zawiera PS1, więc ta zmienna jest ponownie oceniana za każdym razem, gdy oceniana jest zmienna PROMPT_COMMAND.
PROMPT_COMMAND='RET=$?;\
BRANCH="";\
ERRMSG="";\
if [[ $RET != 0 ]]; then\
ERRMSG=" $RET";\
fi;\
if git branch &>/dev/null; then\
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2);\
fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
Przykładowe wyjście wygląda następująco w katalogu innym niż git:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
aw katalogu git zobaczysz nazwę gałęzi:
sashan@dhcp-au-122 rework mybranch $
Aktualizacja
Po przeczytaniu komentarzy i odpowiedzi Boba myślę, że pisanie tego tak, jak opisuje, jest lepsze. Jest łatwiejszy w utrzymaniu niż to, co pierwotnie napisałem powyżej, gdzie zmienna PS1 jest ustawiana wewnątrz PROMPT_COMMAND, który sam jest bardzo skomplikowanym ciągiem, który jest oceniany w czasie wykonywania przez bash. Działa, ale jest bardziej skomplikowane, niż powinno. Aby być uczciwym napisałem to PROMPT_COMMAND dla siebie około 10 lat temu i zadziałało i nie myślałem o tym zbyt wiele.
Dla tych, którzy są ciekawi, jak zmieniłem swoje rzeczy, po prostu umieściłem kod PROMPT_COMMAND w oddzielnym pliku (jak opisał Bob), a następnie powtórzyłem ciąg, który mam zamiar być PS1:
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
ERRMSG=" $RET"
fi
if which git &>/dev/null; then
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2)
else
BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
i w moim .bashrc
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
if git branch &>/dev/null ; then\
. Przekierowuje zarówno stdout, jak i stderr do / dev / null. tldp.org/LDP/abs/html/io-redirection.htmlPROMPT_COMMAND
.Don't set PS1 in PROMPT_COMMAND! Set variables in PROMPT_COMMAND and use them in PS1
PS1
online w ciąguPROMPT_COMMAND
jest niekorzystna. To doskonały, przydatny kod. W przeciwieństwie do odpowiedzi Boba,PS1
zmienna została poprawnie skonstruowana. Pozwala to na znacznie bardziej wyrafinowany monit basha w zależności od aktualnej sytuacji.PS1
wnętrza @ChristianWolfPROMPT_COMMAND
jest bezcelowa. jest przykładem, jak tego nie robić. konstruujPS1
raz w.bash_profile
, po prostu użyj pojedynczych cudzysłowów zamiast podwójnych cudzysłowów, aby podstawienia zmiennych były oceniane podczas każdego zachęty.Różnica polega na tym, że PS1 jest rzeczywiście używanym ciągiem zachęty, a PROMPT_COMMAND jest poleceniem wykonywanym tuż przed zachętą. Jeśli chcesz mieć najprostszy i najbardziej elastyczny sposób tworzenia monitu, wypróbuj następujące rozwiązania:
Umieść to w swoim .bashrc:
Następnie napisz skrypt (bash, perl, ruby: twój wybór) i umieść go w ~ / bin / bash_prompt.
Skrypt może użyć dowolnych informacji do skonstruowania zachęty. Jest to znacznie prostsze IMO, ponieważ nie musisz uczyć się nieco barokowego języka zastępowania, który został opracowany tylko dla zmiennej PS1.
Możesz pomyśleć, że możesz zrobić to samo, po prostu ustawiając PROMPT_COMMAND bezpośrednio na ~ / bin / bash_prompt i ustawiając PS1 na pusty łańcuch. Na początku wydaje się to działać, ale wkrótce odkrywasz, że kod readline oczekuje, że PS1 zostanie ustawiony na właściwy znak zachęty, a kiedy przewijasz wsteczne hasła w historii, w rezultacie wszystko się pogmatwa. To obejście powoduje, że PS1 zawsze odzwierciedla najnowszy znak zachęty (ponieważ funkcja ustawia rzeczywisty PS1 używany przez wywołujące wystąpienie powłoki), a to sprawia, że readline i historia poleceń działają dobrze.
źródło
PS1
wPROMPT_COMMAND
! Ustaw zmiennePROMPT_COMMAND
i używaj ich w programiePS1
. W przeciwnym razie stracisz możliwość korzystania zPS1
sekwencji ucieczki, takich jak\u
lub\h
. Musisz je wymyślić na nowoPROMPT_COMMAND
. Może to być możliwe, ale nie da się obejść utraty\[
i\]
oznaczania początku i końca niedrukowalnych znaków. Oznacza to, że nie można używać kolorów bez pomylenia terminala co do długości podpowiedzi. I to jest mylącereadline
podczas edycji polecenia powodującego powstanie dwóch linii. W końcu na ekranie jest wielki bałagan.PROMPT_COMMAND
jest wykonywana przed drukowaniemPS1
. Nie widzę problemówPS1
z ustawieniem od wewnątrzPROMPT_COMMAND
, bo poPROMPT_COMMAND
skończeniu będzie drukować powłokaPS1
, która była modyfikowana odPROMPT_COMMAND
(czy w tym przypadku od wewnątrzprompt_command
)?export PS1='$(~/bin/bash_prompt)'
robi to samo, błąd wygląda rozsądnieOd
man bash
:Jeśli chcesz po prostu ustawić ciąg zachęty,
PS1
wystarczy użyć samego:Jeśli chcesz zrobić coś innego tuż przed wydrukowaniem monitu, użyj
PROMPT_COMMAND
. Na przykład, jeśli chcesz zsynchronizować zapisane w pamięci podręcznej zapisy na dysku, możesz napisać:źródło
PS1
bez potrzebyPROMPT_COMMAND
, ponieważ sekwencja, która ustawia tytuł, może być zawarta wPS1
opakowaniach\[
i\]
.PS1
, po prostu zostanie ona ustawiona w podpowłoce, więc nie możesz odzyskać jej wartości. ale twój przykład jest trywialnyPS1='$(sync)user \u on host \h$ '
różnica polega na tym
PROMPT_COMMAND
, spieprzy to twój znak zachęty bashPS1
substytuty\H
i przyjacielePROMPT_COMMAND
uruchamia swoją zawartość,PS1
używa jej zawartości jako zachęty.PS1
wykonuje interpretację zmiennych i podstawianie poleceń w każdym znaku zachęty, nie ma potrzebyPROMPT_COMMAND
przypisywania wartości doPS1
lub uruchamiania dowolnego kodu. możesz łatwo zrobićexport PS1='$(uuidgen) $RANDOM'
raz w.bash_profile
, po prostu użyj pojedynczych cudzysłowówźródło
Tak, więc spróbuj naprawdę to naprawić:
PROMPT_COMMAND
to poręczna zmienna / funkcja zapewniająca wygodę basha , ale ściśle mówiąc, nie ma niczego, czego nie można zrobićPS1
samodzielnie, prawda?Chodzi mi o to, że jeśli ktoś chce ustawić inną zmienną z zakresem poza monitem: w zależności od powłoki, ta zmienna prawdopodobnie musiałaby zostać zadeklarowana jako pierwsza na zewnątrz
$PS1
lub (w najgorszym przypadku) można by wymyślić coś czekającego na FIFO przed dzwoni$PS1
(i ponownie uzbrojony pod koniec$PS1
);\u
\h
może powodować pewne problemy, zwłaszcza jeśli używasz wymyślnej regex; ale poza tym: można osiągnąć wszystko, coPROMPT_COMMAND
można, stosując podstawianie poleceń w obrębie$PS1
(i, może w przypadkach narożnych, jawnych podpowłok)?Dobrze?
źródło