Co oznacza $ {PATH: +: $ {PATH}}?

25

Niedawno zauważyłem w moim profilu cygwin, a dokładniej:

/usr/local/bin:/usr/bin${PATH:+:${PATH}}

Co to znaczy? Dlaczego nie jest tylko ŚCIEŻKA $? Czy to jest „jeśli $ PATH istnieje, to dodaj: $ PATH”? Moim celem jest zamiana kolejności i umieszczenie ścieżek cygwin za ścieżką systemu Windows. W przeszłości miałbym

$PATH:/usr/local/bin:/usr/bin

ale to mnie dezorientuje. Może powinienem to robić

PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"

dołączyć: na końcu $ PATH?

tofutim
źródło
1
Twój tytuł pytania naprawdę pomieszany z formatowaniem w pasku bocznym SE Hot Questions i.imgur.com/g6pPmzf.png
Brad

Odpowiedzi:

39

:+Jest formą ekspansji parametrów :

$ {parametr: + [słowo]} : Użyj wartości alternatywnej.

Jeśli parametr jest nieustawiony lub ma wartość NULL, wartość NULL należy zastąpić; w przeciwnym razie rozwinięcie słowa (lub pusty ciąg znaków, jeśli słowo zostanie pominięte) zostanie zastąpione.

Innymi słowy, jeśli zmienna $varjest zdefiniowana, echo ${var:+foo}wydrukuje, fooa jeśli nie, wydrukuje pusty ciąg.

Drugi :to nic specjalnego. Jest to znak używany jako separator na liście katalogów w $PATH. Jest więc PATH="/usr/local/bin:/usr/bin${PATH:+:${PATH}}"skrótowym sposobem pisania:

if [ -z "$PATH" ]; then
    PATH=/usr/local/bin:/usr/bin
else
    PATH=/usr/local/bin:/usr/bin:$PATH
fi

To tylko sprytna sztuczka, aby uniknąć dodawania dodatkowych, :gdy $PATHnie jest ustawiona. Na przykład:

$ PATH="/usr/bin"
$ PATH="/new/dir:$PATH" ## Add a directory
$ echo "$PATH"
/new/dir:/usr/bin

Ale jeśli PATHjest rozbrojony:

$ unset PATH
$ PATH="/new/dir:$PATH"
$ echo "$PATH"
/new/dir:

:Sam dodaje aktualny katalog $PATH. Używanie PATH="/new/dir${PATH:+:$PATH}"pozwala tego uniknąć. Więc na pewno możesz użyć, PATH="${PATH:+${PATH}:}/usr/local/bin:/usr/bin"jeśli chcesz, lub możesz użyć, PATH="$PATH:/usr/local/bin:/usr/bin"jeśli wolisz. Jedyna różnica polega na tym, że ten pierwszy może dodać dodatkowy :, a tym samym dodać bieżący katalog do twojego $PATH.

terdon
źródło
Czy to dodatkowe :szkodliwe?
kot
4
@tac nie naprawdę, to po prostu dodaje bieżący katalog do listy $PATH(patrz @ AndyB za odpowiedź ). W niektórych sytuacjach może to stanowić zagrożenie bezpieczeństwa (powiedzmy, że osoba atakująca przesłała destrukcyjny skrypt do bieżącego katalogu i nadała mu nazwę lslub coś takiego), ale w większości przypadków naprawdę nie masz nic przeciwko. W rzeczywistości niektóre systemy i tak dodają bieżący katalog do PATHdomyślnego.
terdon
Ścieżka to jedyne miejsce, w którym wolałbym, aby były cshobsługiwane przez tablicę.
hometoast
8

Masz rację, to znaczy „jeśli $ PATH istnieje - i nie ma wartości null - to dodaj: $ PATH”.

Musisz sprawdzić, czy $ PATH istnieje, ponieważ nie chcesz dodawać wiodącego (lub końcowego) dwukropka, jeśli $ PATH jest niezdefiniowany. Nazwa katalogu o zerowej długości (null) w ścieżce, jak w :/usr/local/bin:/usr/bin, lub /usr/local/bin:/usr/bin:, lub /usr/local/bin::/usr/binoznacza wyszukiwanie w bieżącym katalogu .

Wyciąg z man bash:

   PATH   ...
          A zero-length (null) directory name in the value of PATH indicates 
          the current directory.  A  null  directory name may appear as two 
          adjacent colons, or as an initial or trailing colon.
          ...

Prawdopodobnie nie to chcesz zrobić.

Poniższe dwie linie robią to samo:

PATH=":/bin"        # search current directory, then /bin
PATH=".:/bin"
AndyB
źródło