Przestrzenie w zmiennych środowiskowych Linuksa?

4

Podany katalog: /media/foo/can haz/bar, Próbowałem edytować bash.rc z:

export Foo=/media/foo/can haz/bar
export Foo=/media/foo/can\ haz/bar
export Foo='/media/foo/can haz/bar'
export Foo="/media/foo/can haz/bar"
export Foo='"/media/foo/can haz/bar"'
export Foo="'/media/foo/can haz/bar'"

Za każdym razem nie mogłem jednak uzyskać czegoś takiego jak poniżej (bez użycia "$Foo" ):

cd $Foo

Jak ustawić zmienną środowiskową ze spacjami w systemie Linux?

A T
źródło
Może jeśli ustawię alias lub coś takiego?
A T

Odpowiedzi:

8

Problemem nie jest to, że zmienna środowiskowa zawiera spację. Zapominasz o cytuj swoje argumenty :

cd "$Foo"

Jeśli nie cytujesz $Foo, the cd polecenie rzeczywiście zobaczy dwa (lub więcej) argumenty, ponieważ białe znaki domyślnie oddzielają argumenty . W twoim konkretnym przypadku zdasz /media/foo/can i haz/bar oddzielnie, ponieważ powłoka dzieli je w przestrzeni. Zmienne z podwójnym cytowaniem są dobrym nawykiem do rozwijania i pozwalają zaoszczędzić w wielu przypadkach, w które zaangażowane są białe znaki.

Jeśli chcesz naprawdę brzydki sposób na osiągnięcie tego bez cytatów, nadpisz swój cd wbudowany tak:

cd() { builtin cd "$*"; }

To zadziała, jeśli ścieżka zawiera spacje, ponieważ $* będzie zawierać indywidualne argumenty ( /media/foo/can i haz/bar ), oddzielone pierwszym znakiem IFS (zazwyczaj spacją), a następnie sklej je razem z podwójnymi cudzysłowami.

Jednak nigdy nie jest dobrym pomysłem nadpisywanie takich wbudowanych plików.

slhck
źródło
Jak wspomniano, chcę tego uniknąć; to jest cały problem, który próbuję rozwiązać.
A T
Czy wkradłeś się do tej części? Nie pamiętam, żeby był tam w pierwszej wersji pytania, które widziałem :) Tak czy inaczej, twoje pytanie brzmi: „Jak ustawić zmienną środowiskową ze spacją?”, A odpowiedź brzmi: możesz to zrobić. Sposób, w jaki sobie z tym poradzisz, jest innym problemem i nie można go uruchomić bez cudzysłowów, to tylko kwestia tego, jak działa powłoka.
slhck
@AT Czy widziałeś moją aktualizację?
slhck
2

Jak powiedział @slhck, właściwym sposobem na to jest umieszczenie podwójnych cudzysłowów wokół zmiennej referencyjnej (np. cd "$Foo" ). Powodem tego jest kolejność, w jakiej powłoka analizuje różne aspekty linii poleceń: najpierw skanuje w poszukiwaniu cudzysłowów i ucieczek (i usuwa je, gdy stosuje swoje efekty), a następnie zastępuje zmienne odniesienia swoimi wartościami (np. $Foo - & gt; /media/foo/can haz/bar ), następnie powraca przez zastąpione wartości i stosuje rozszerzenie wieloznaczne ( *.txt - & gt; a.txt b.txt itp.) i dzielenie słów ( /media/foo/can haz/bar - & gt; „/ media / foo / can” „haz / bar”), ale nigdy nie wraca i szuka cudzysłowów i / lub ucieczek w wartościach zmiennych. W rezultacie osadzanie cudzysłowów i / lub ucieczek w wartości zmiennej ma nic nawet trochę użytecznego ; zanim staną się częścią linii poleceń, jest już za późno na zamierzony efekt. Znam tylko trzy sposoby uniknięcia dzielenia wyrazów na rozszerzonej wartości:

  1. Podaj podwójnie odwołanie do zmiennej. To nie jest tak wygodne, ale wymaga standardowej składni powłoki.
  2. Zmień wartość IFS (listy znaków używanych do dzielenia wyrazów na zmiennych rozszerzonych). Następnie obserwuj, jak wszystkie skrypty, które zależą od standardowego zachowania dzielenia słów, dziwnie się psują. Nie rób tego. Poważnie.
  3. Przełącz się na powłokę, która nie wykonuje dzielenia słów na zmiennych rozszerzonych: zsh. Będziesz musiał przyzwyczaić się do innych różnic od basha, ale jeśli naprawdę tego chcesz, to jest najlepszy sposób. Nie używam go osobiście, ale ci, którym się to bardzo podoba ...
Gordon Davisson
źródło
Zsh ładnie się uzupełnia cd $Foo do cd /path\ with/spaces. Znalazłem Bash, aby zrobić to źle, jeśli go uruchomisz Ctrl-A-E, ale od jakiegoś czasu nie używałem Basha, więc może to być również możliwe.
slhck