Додайте до змінної PATH, не створюючи провідної кишки, якщо її не встановлено


10

Мені потрібно додати каталог PKG_CONFIG_PATH. Як правило, я б використовував стандарт

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

але PKG_CONFIG_PATHраніше не було встановлено в моїй системі. Тому змінна починається з :символу, який підказує її спочатку переглянути в поточній директорії. Я цього не хочу. Я зупинився на наступному,

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

але це просто здається таким некрасивим. Чи є кращий спосіб? Який відповідний спосіб умовно додати двокрапку лише тоді, коли змінну вже встановлено?


Відповіді:


13

Ви знаходитесь на правильному шляху з ${:+}оператором розширення, просто потрібно його трохи змінити:

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

Перші дужки розширюються до, $V і iff товстої кишки Vвстановлюється вже в іншому випадку - це саме те, що вам потрібно (і, мабуть, також одна з причин існування оператора).

Таким чином у вашому випадку:

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

Я використав цю форму, але я вирішив проти нього , тому що він відчував (трохи) менш читаються: ${V}${V:+:}Wvs. ${V:+${V}:}W. Так чи інакше, вони обидва відчувають себе справді некрасиво. Я сподівався на щось ... більш елегантне, я думаю?
scottbb

@scottbb - це синтаксична форма - це, як це робиться. Якщо ви хочете встановити значення змінної на основі умови, ви повинні зробити тест. Ви можете зробити вбудований тест, як написано тут, або ви можете явно протестувати за допомогою testбудь-якого способу ви тестуєте значення та записуєте varname двічі, але таким чином ви це робите в одному операторі виконання - таким чином це практично , але я ніколи не зустрічав елегантного комп’ютера.
mikeserv

@scottbb Думаючи, що це насправді те саме. Але я боюся, що ви не отримаєте це краще, оскільки вам в основному потрібна назва змінної в умові, а потім у розширенні - я не думаю, що існує конструкція оболонки, яка могла б зробити це лише одним явищем назва.
петерф

@mikeserv - Мабуть, я мав би бути більш точним, ніж сказати, що шукав більш "елегантне" рішення. Я ніколи не бачив цього робити для додавання підрядів до змінних у стилі PATH, і мені здавалося, що я пропускаю кращий шлях. З мого досвіду, коли я відчуваю це почуття, зазвичай є кращий спосіб. Це я мав сказати. Але ваша думка добре прийнята. Дякую за Вашу відповідь. Також: в одному зі своїх редагувань коментаря @ peterph ви зробили коментар, на який я повинен був цитувати весь аргумент export. Це дуже вдалий момент, я також змінив цю деталь.
scottbb

@scottbb - вибачте, якщо це виявилося абразивним - я ніколи не розумів поняття елегантності щодо обчислень. комп'ютер - це машина - триходова та / або ворота, складена в мільярди разів. це не може розраховувати вище, ніж один - у будь-якому випадку, кожна річ, яку він робить, є грубо вимушеною . деякі інтуїтивні поняття можуть бути простішими для перекладу, ніж інші, але, якщо так, то це лише тому, що концепція розташована на вершині якоїсь іншої грубої абстракції. Обчислювальна техніка - це все, крім елегантного.
mikeserv

1

Останнім часом я налаштував GNU stow на своїх машинах для зберігання загальнокористувацьких речей, таких як бібліотеки, ~/.localі зіткнувся з проблемами при визначенні LD_LIBRARY_PATH, CPATHі LIBRARY_PATH, ненароком, поклавши туди двокрапки і так розбиваючи речі.

Тоді я знайшов ваше запитання, і відповідь була не зовсім елегантною ;-), і я написав невелику функцію для вирішення цього питання, будь ласка, знайдіть його тут: 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 "${*}")"
}

// відредаговано згідно з пропозицією @Kusalananda


Також:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda

Тобто:join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
Кусалаланда

... За винятком того, що "приєднатися" - це нещасне ім'я, оскільки це також назва стандартної утиліти.
Кусалаланда

Хороший, за винятком того, що ви замінили б змінну замість того, щоб до неї додавати. Просто додавання ${!variable:+${!variable}:}в потрібному місці працювало для мене, всі тести пройшли. Знайти відповідне ім'я читач читає :)
Superlexx
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.