Dołącz do zmiennej podobnej do ŚCIEŻKI bez tworzenia dwukropka wiodącego, jeśli nie jest ustawiony

10

Muszę dołączyć katalog do PKG_CONFIG_PATH. Normalnie użyłbym standardu

export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:$(pyenv prefix)/lib/pkgconfig

ale PKG_CONFIG_PATHnie zostało wcześniej ustawione w moim systemie. Dlatego zmienna zaczyna się od :znaku, który każe jej najpierw zajrzeć do bieżącego katalogu. Nie chcę tego. Ustaliłem, co następuje:

export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}${PKG_CONFIG_PATH:+:}$(pyenv prefix)/lib/pkgconfig

ale to wydaje się takie brzydkie. Czy jest lepszy sposób? Jaki jest właściwy sposób warunkowego dołączenia dwukropka, jeśli i tylko wtedy, gdy zmienna została już ustawiona?

scottbb
źródło
1
stackoverflow.com/questions/9631228/…
sancho.s ReinstateMonicaCellio

Odpowiedzi:

13

Jesteś na dobrej drodze z ${:+}operatorem ekspansji, wystarczy go nieco zmodyfikować:

V=${V:+${V}:}new_V

Pierwsze nawiasy klamrowe rozszerzają się do, $V a dwukropek iff Vjest już ustawiony inaczej na nic - co jest dokładnie tym, czego potrzebujesz (i prawdopodobnie także jednym z powodów istnienia operatora).

Zatem w twoim przypadku:

export "PKG_CONFIG_PATH=${PKG_CONFIG_PATH:+${PKG_CONFIG_PATH}:}$(pyenv prefix)/lib/pkgconfig"
Peter
źródło
Byłem za pomocą tego formularza, ale zdecydowaliśmy się nią, ponieważ czuł (nieco) mniej czytelny: ${V}${V:+:}WVs. ${V:+${V}:}W. Tak czy inaczej, oboje czują się naprawdę brzydcy. Miałem nadzieję na coś ... chyba bardziej eleganckiego?
scottbb
@scottbb - jest to forma składni - tak się to robi. Jeśli chcesz ustawić wartość zmiennej na podstawie warunku, musisz wykonać test. Możesz wykonać test wbudowany, tak jak jest tutaj napisane, lub możesz bezpośrednio testować test- w dowolny sposób testujesz wartość i zapisujesz nazwę zmiennej dwa razy, ale w ten sposób robisz to w pojedynczym poleceniu wykonania - w ten sposób jest to praktyczne , ale nigdy nie spotkałem eleganckiego komputera.
mikeserv
@scottbb Myślenie o tym jest naprawdę takie samo. Ale obawiam się, że nie uzyskasz tego lepiej, ponieważ w zasadzie potrzebujesz nazwy zmiennej w warunku, a następnie w rozszerzeniu - nie sądzę, że istnieje konstrukcja powłoki, która zrobiłaby to z jednym wystąpieniem imię.
peterph
@ mikeserv - prawdopodobnie powinienem był być bardziej precyzyjny niż powiedzieć, że szukałem bardziej „eleganckiego” rozwiązania. Nigdy tak naprawdę nie widziałem tego w przypadku dodawania podciągów do zmiennych w stylu PATH, i czułem, że brakuje mi lepszego sposobu. Z mojego doświadczenia wynika, że ​​gdy mam to uczucie, zwykle jest lepszy sposób. Tak powinienem był powiedzieć. Ale twój punkt widzenia jest słuszny. Dzięki za twoją odpowiedź. Ponadto: w jednej ze zmian komentarza @ peterph napisałeś komentarz, do którego powinienem zacytować cały argument export. To bardzo dobra uwaga, poprawiłem również ten szczegół.
scottbb
@ scottbb - przepraszam, jeśli to zadziałało jako materiał ścierny - nigdy nie rozumiałem pojęcia elegancji w odniesieniu do komputerów. komputer jest maszyną - trójstronną i / lub bramą złożoną miliardy razy. nie może liczyć więcej niż jeden - pod każdym względem wszystko, co robi, jest brutalnie zmuszane . niektóre intuicyjne koncepcje mogą być łatwiejsze do przetłumaczenia niż inne, ale jeśli tak, to tylko dlatego, że koncepcja znajduje się na szczycie jakiejś brutalnej wymuszonej abstrakcji. przetwarzanie w jego sercu zawsze jest eleganckie.
mikeserv
1

Ostatnio założyłem GNU Stow na moich maszynach do sklepu użytkownika szeroki rzeczy jak biblioteki mocy ~/.locali pobiegł do kłopotów przy określaniu LD_LIBRARY_PATH, CPATHi LIBRARY_PATH, przypadkowo umieszczenie dwukropka tam i tak łamiąc rzeczy.

Potem znalazłem twoje pytanie i odpowiedź nie była do końca elegancka ;-) i napisałem małą funkcję do obsługi tego, znajdź go tutaj: https://gist.github.com/rico-chet/0229e4c080d9f51a02535dd25a656a8a

## Copyright (C) 2018 Alex Thiessen <[email protected]>
## Copyright (C) 2018 https://unix.stackexchange.com/users/116858/kusalananda
## SPDX-License-Identifier: GPL-2.0-or-later
## <https://spdx.org/licenses/GPL-2.0-or-later.html>

function join() {
    if [ ${#} -eq 0 ]
    then
        echo "\`join\` appends elements separated by colons to a \`bash\` variable " >&2
        echo "usage: join <variable> <element> [element ...]" >&2
        return 1
    fi
    variable="${1}"

    shift
    export ${variable}="${!variable:+${!variable}:}$(IFS=:; echo "${*}")"
}

// edytowane zgodnie z sugestią @Kusalananda

Superlexx
źródło
Również:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda
To join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
znaczy
... Z wyjątkiem tego, że „dołącz” jest niefortunną nazwą, ponieważ jest to również nazwa standardowego narzędzia.
Kusalananda
Fajny, z wyjątkiem faktu, że nadpisałeś zmienną zamiast do niej dołączyć. Po prostu dodanie ${!variable:+${!variable}:}w odpowiednim miejscu działało dla mnie, wszystkie testy przeszły pomyślnie. Znalezienie odpowiedniej nazwy jest zbyt duże dla czytelnika :)
Superlexx,