Dlaczego po wprowadzeniu tego polecenia wiersz zmienia się w mój katalog?
PS1='$(pwd)'
Używam pojedynczych cudzysłowów, co oznacza brak interpolacji, alias echo '$(pwd)'
—— →$(pwd)
Co więcej, powiedzmy, że wyjaśniliśmy, dlaczego to działa ... dlaczego działa inaczej niż PS1=$(pwd)
? (w ogóle nie ma cytatów)
Mówiąc inaczej, mam na myśli, że jeśli użyję cudzysłowów, monit będzie przechodził do mojego bieżącego katalogu podczas przeglądania terminala. Ale jeśli nie użyję cudzysłowów, to monit zawsze pozostanie katalogiem, w którym byłem, kiedy po raz pierwszy wprowadziłem poleceniePS1=$(pwd)
dlaczego?
Odpowiedzi:
Gdy po prostu przypisujesz wartość do zmiennej,
$(...)
wyrażenie jest oceniane, chyba że jest ujęte w pojedyncze cudzysłowy (lub znaki specjalne z odwrotnym ukośnikiem). Aby zrozumieć, spróbuj porównać te dwa:Wartość parametru
A
natychmiast staje się ciągiem/home/yourusername
i oczywiście nie jest pamiętane, skąd ten ciąg pochodzi, pozostaje taki sam, nawet jeśli zmienisz katalog. WartośćB
staje się jednak dosłownym ciągiem$(pwd)
bez interpretacji.Teraz w wartości
PS1
czegoś wyjątkowego dzieje się: za każdym razem, gdy drukowany jest monit, interpretowane są pewne konstrukcje specjalne, np. Podstawianie poleceń$(...)
jest wykonywane dokładnie tak, jak miało to miejsce powyżej przy przypisaniu doA
zmiennej. Oczywiście, jeśliPS1
zawiera dosłowny ciąg twojego katalogu domowego (jak wyżej zA
), to nie ma możliwości, aby to zmienić. Ale jeśli zawiera ciąg$(pwd)
(jak powyżej zB
), to jest oceniany za każdym razem, gdy drukowany jest monit, a tym samym wyświetlany jest rzeczywisty katalog.źródło
Zarówno w bash, jak i zsh, wartość
PS1
nie jest używana jako natychmiastowa zachęta, lecz podlega pewnym rozszerzeniom. Reguły różne dla obu powłok, ale w obydwu przypadkach jedną z etapem jest przeprowadzanie „dolara” rozszerzenia (podstawienie zmiennych, podstawień, ocena arytmetyczna) z tymi samymi składni jak w normalnym składni powłoki ( , , i , , ) .$VARIABLE
${VARIABLE}
$(COMMAND)
`COMMAND`
$((EXPRESSION))
$[EXPRESSION]
shopt -u promptvars
.setopt prompt_subst
.Przy włączonej ekspansji dolara w podpowiedzi
PS1='$(pwd)'
ustawianaPS1
jest wartość 6-znakowa,$(pwd)
co powoduje$(pwd)
podstawienie, a zatempwd
polecenie do wykonania, za każdym razem, gdy powłoka wyświetla nowy monit. Z drugiej strony,PS1=$(pwd)
ustawiaPS1
na dowolny katalog roboczy powłoki w tym czasie. Jeśli wyłączyłeś ekspansję dolaraPS1='$(pwd)'
, spowoduje to, że podpowiedź będzie ciągiem literalnym$(pwd)
.Zauważ, że istnieją wygodniejsze sposoby uzyskania katalogu roboczego w wierszu polecenia:
\w
, który skraca katalog domowy do~
i może zostać przycięty przez ustawieniePROMPT_DIRTRIM
.%/
lub%~
(%/
jest taki sam jak$PWD
,%~
skraca katalogi domowe), który może mieć ustawienie przycinania.$PWD
jest to równoważne z$(pwd)
: nie trzeba uruchamiać podprocesu, aby uzyskać bieżący katalog roboczy.źródło
Ponieważ bez cudzysłowów wartość $ (pwd) jest obliczana, gdy ustawiony jest PS1. W przypadku cudzysłowów ocena $ (pwd) jest odraczana do momentu wyświetlenia monitu.
Bez cudzysłowów PS1 jest ustawiany na bieżący katalog w momencie ustawiania PS1. W przypadku pojedynczych cudzysłowów PS1 jest ustawione na $ (pwd), co oznacza, że będzie oceniać i drukować bieżący katalog za każdym razem, gdy zostanie wyświetlony monit.
źródło