Aggiungi alla variabile tipo PATH senza creare due punti iniziali se non impostato


10

Devo aggiungere una directory a PKG_CONFIG_PATH. Normalmente, userei lo standard

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

ma PKG_CONFIG_PATHnon è stato precedentemente impostato sul mio sistema. Pertanto, la variabile inizia con un :carattere, che le dice di cercare prima nella directory corrente. Non voglio quello. Ho optato per il seguente,

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

ma sembra così brutto. C'è un modo migliore? Qual è il modo appropriato per aggiungere condizionalmente i due punti se e solo se la variabile è già stata impostata?


Risposte:


13

Sei sulla buona strada con l' ${:+}operatore di espansione, devi solo modificarlo leggermente:

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

Le prime parentesi graffe si espandono $V e i due punti iff non Vsono già impostati su niente, il che è esattamente ciò di cui hai bisogno (e probabilmente anche uno dei motivi dell'esistenza dell'operatore).

Quindi nel tuo caso:

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

Ero con quella forma, ma ho deciso contro di esso perché si sentiva (leggermente) meno leggibile: ${V}${V:+:}Wcontro ${V:+${V}:}W. Ad ogni modo, entrambi si sentono davvero brutti. Speravo in qualcosa ... più elegante, immagino?
Scott

@scottbb - questa è la forma della sintassi - è come viene fatta. Se si desidera impostare il valore di una variabile in base a una condizione, è necessario eseguire un test. Puoi fare un test in linea come è scritto qui, oppure puoi fare un test esplicito con test- in entrambi i casi stai testando il valore e scrivendo il varname due volte, ma in questo modo lo fai in una singola istruzione di esecuzione - in questo modo è pratico , ma non ho mai incontrato un computer elegante .
Mikeserv,

@scottbb Pensandoci è davvero lo stesso. Ma temo che non lo otterrai meglio, dal momento che in pratica hai bisogno del nome della variabile nella condizione e quindi nell'espansione - Non penso che ci sia un costrutto di shell che lo farebbe con una sola occorrenza del nome.
peterph,

@mikeserv - Probabilmente avrei dovuto essere più preciso che dire che stavo cercando una soluzione più "elegante". Non l'ho mai visto fare per aggiungere sottostringhe alle variabili di stile PATH, e in qualche modo mi è sembrato che mi mancasse un modo migliore. Nella mia esperienza, quando ho quella sensazione, di solito c'è un modo migliore. Questo è quello che avrei dovuto dire. Ma il tuo punto è ben preso. Grazie per la risposta. Inoltre: in una delle tue modifiche al commento di @ peterph, hai fatto il commento a cui avrei dovuto citare l'intero argomento export. È un ottimo punto, ho anche infastidito quel dettaglio.
Scott

@scottbb - scusate se questo è risultato abrasivo - non ho mai capito il concetto di eleganza per quanto riguarda il calcolo. un computer è una macchina - un miliardi e tre volte composto da gate e / o gate. non può contare più di uno - in ogni modo, ogni cosa che fa è forzata . alcuni concetti intuitivi possono essere più facili da tradurre rispetto ad altri, ma, in tal caso, è solo perché il concetto si trova sopra qualche altra astrazione a forza bruta. l'informatica, nel suo cuore, è sempre tutt'altro che elegante.
Mikeserv,

1

Ultimamente, ho creato GNU Stow sul mio computer per memorizzare roba user-larga come le biblioteche sotto ~/.locale corse in difficoltà al momento di definire LD_LIBRARY_PATH, CPATHe LIBRARY_PATH, inavvertitamente mettendo due punti lì e quindi rompere roba.

Poi ho trovato la tua domanda e la risposta non era esattamente elegante ;-), e ho scritto una piccola funzione per gestirla, la trovi qui: https://gist.github.com/rico-chet/0229e4c080d9f51a02535dd25a656a8a

## Copyright (C) 2018 Alex Thiessen <alex.thiessen.de+github@gmail.com>
## 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 "${*}")"
}

// modificato come suggerito da @Kusalananda


Inoltre:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda

join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
Vale a

... Tranne che "join" è un nome sfortunato in quanto è anche il nome di un'utilità standard.
Kusalananda

Bello, tranne per il fatto che avresti sovrascritto la variabile invece di aggiungerla. Solo aggiungendo ${!variable:+${!variable}:}nel posto giusto ha funzionato per me, tutti i test hanno superato. Trovare un nome appropriato è un'esagerazione per il lettore :)
Superlexx,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.