Ajouter à la variable de type PATH sans créer de deux-points en tête si non défini

10

J'ai besoin d'ajouter un répertoire à PKG_CONFIG_PATH. Normalement, j'utiliserais la norme

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

mais PKG_CONFIG_PATHn'a pas été précédemment configuré sur mon système. Par conséquent, la variable commence par un :caractère, qui lui indique de rechercher d'abord dans le répertoire courant. Je ne veux pas ça. Je me suis installé sur ce qui suit,

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

mais cela semble tellement moche. Y a-t-il une meilleure façon? Quelle est la façon appropriée d'ajouter les deux points conditionnellement si et seulement si la variable a déjà été définie?

scottbb
la source
1
stackoverflow.com/questions/9631228/…
sancho.s ReinstateMonicaCellio

Réponses:

13

Vous êtes sur la bonne voie avec l' ${:+}opérateur d'expansion, il vous suffit de le modifier légèrement:

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

Les premières accolades s'étendent jusqu'à $V et le Vsigne deux-points est déjà défini autrement à rien - ce qui est exactement ce dont vous avez besoin (et probablement aussi l'une des raisons de l'existence de l'opérateur).

Ainsi dans votre cas:

export "PKG_CONFIG_PATH=${PKG_CONFIG_PATH:+${PKG_CONFIG_PATH}:}$(pyenv prefix)/lib/pkgconfig"
peterph
la source
J'utilisais cette forme, mais j'ai décidé contre elle parce qu'elle se sentait ( un peu) moins lisible: par ${V}${V:+:}Wrapport ${V:+${V}:}W. Quoi qu'il en soit, ils se sentent tous les deux vraiment laids. J'espérais quelque chose ... plus élégant, je suppose?
scottbb
@scottbb - c'est la forme de la syntaxe - c'est ainsi que cela se fait. Si vous souhaitez définir la valeur d'une variable en fonction d'une condition, vous devez effectuer un test. Vous pouvez faire un test en ligne comme il est écrit ici, ou vous pouvez explicitement tester avec test- de toute façon vous testez la valeur et écrivez le nom de variable deux fois, mais de cette façon vous le faites dans une seule instruction d'exécution - de cette façon, c'est pratique , mais je n'ai jamais rencontré un ordinateur élégant .
mikeserv
@scottbb En y réfléchissant, c'est vraiment la même chose. Mais je crains que vous ne l'obtiendrez pas mieux, car vous avez essentiellement besoin du nom de variable dans la condition, puis dans l'expansion - je ne pense pas qu'il existe une construction de shell qui le ferait avec une seule occurrence de la Nom.
peterph
@mikeserv - J'aurais probablement dû être plus précis que de dire que je cherchais une solution plus "élégante". Je n'ai jamais vraiment vu cela pour ajouter des sous-chaînes aux variables de style PATH, et j'ai eu l'impression que je manquais d'une meilleure façon. D'après mon expérience, quand j'ai ce sentiment, il y a généralement une meilleure façon. Voilà ce que j'aurais dû dire. Mais votre point est bien compris. Merci pour votre réponse. Aussi: dans l'une de vos modifications du commentaire de @ peterph, vous avez fait le commentaire que j'aurais dû citer l'intégralité de l'argument export. C'est un très bon point, j'ai également vexé ce détail.
scottbb
@scottbb - désolé si cela s'est avéré abrasif - ive n'a jamais compris le concept d' élégance en ce qui concerne l'informatique. un ordinateur est une machine - un portail à trois voies et / ou composé des milliards de fois. il ne peut pas compter plus d'un - dans tous les sens, tout ce qu'il fait est forcé par la force . certains concepts intuitifs peuvent être plus faciles à traduire que d'autres, mais, si c'est le cas, c'est uniquement parce que le concept se trouve au sommet d'une autre abstraction forcée par la force. l'informatique, en son cœur, est toujours loin d'être élégante.
mikeserv
1

Ces derniers temps, je mis en place Stow GNU sur mes machines pour stocker des choses à l' échelle utilisateur comme les bibliothèques sous ~/.localet RAN dans des problèmes lors de la définition LD_LIBRARY_PATH, CPATHet LIBRARY_PATH, par inadvertance mettre un là deux points et donc le casser.

Ensuite, j'ai trouvé votre question et la réponse n'était pas exactement élégante ;-), et j'ai écrit une petite fonction pour gérer cela, veuillez la trouver ici: https://gist.github.com/rico-chet/0229e4c080d9f51a02535dd25a656a8a

## Copyright (C) 2018 Alex Thiessen <[email protected]>
## Copyright (C) 2018 /unix//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 "${*}")"
}

// modifié comme suggéré par @Kusalananda

Superlexx
la source
Aussi:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda
C'est à dire:join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
Kusalananda
... Sauf que "join" est un nom malheureux car c'est aussi le nom d'un utilitaire standard.
Kusalananda
Nice one, sauf pour le fait que vous écraseriez la variable au lieu de l'ajouter. L'ajout ${!variable:+${!variable}:}au bon endroit a fonctionné pour moi, tous les tests ont réussi. Trouver un nom approprié est une exersize pour le lecteur :)
Superlexx