Tambahkan ke variabel seperti PATH tanpa membuat kolon utama jika tidak disetel

10

Saya perlu menambahkan direktori ke PKG_CONFIG_PATH. Biasanya, saya akan menggunakan standar

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

tetapi PKG_CONFIG_PATHbelum diatur sebelumnya pada sistem saya. Oleh karena itu, variabel dimulai dengan :karakter, yang memerintahkannya untuk mencari di direktori saat ini terlebih dahulu. Saya tidak menginginkan itu. Saya memutuskan hal berikut,

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

tapi itu terlihat sangat jelek. Apakah ada cara yang lebih baik? Apa cara yang tepat untuk menambahkan usus secara kondisional jika dan hanya jika variabel telah ditetapkan?

scottbb
sumber
1
stackoverflow.com/questions/9631228/...
sancho.s ReinstateMonicaCellio

Jawaban:

13

Anda berada di jalur yang benar dengan ${:+}operator ekspansi, Anda hanya perlu sedikit memodifikasinya:

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

Kawat gigi pertama meluas ke $V dan titik dua iff Vsudah diatur untuk apa-apa - yang persis apa yang Anda butuhkan (dan mungkin juga salah satu alasan keberadaan operator).

Jadi dalam kasus Anda:

export "PKG_CONFIG_PATH=${PKG_CONFIG_PATH:+${PKG_CONFIG_PATH}:}$(pyenv prefix)/lib/pkgconfig"
peterph
sumber
Saya menggunakan formulir itu, tapi aku memutuskan untuk tidak melakukannya karena merasa (sedikit) kurang dibaca: ${V}${V:+:}Wvs ${V:+${V}:}W. Either way, mereka berdua merasa sangat jelek. Saya berharap untuk sesuatu ... lebih elegan, saya kira?
scottbb
@ skottbb - ini adalah bentuk sintaks - ini adalah bagaimana hal itu dilakukan. Jika Anda ingin menetapkan nilai variabel berdasarkan kondisi Anda harus melakukan tes. Anda dapat melakukan tes sebaris seperti yang tertulis di sini, atau Anda dapat menguji secara eksplisit test- dengan cara apa pun Anda menguji nilai dan menulis varname dua kali, tetapi dengan cara ini Anda melakukannya dalam satu pernyataan eksekusi - dengan cara itu praktis , tapi saya belum pernah bertemu komputer yang elegan .
mikeserv
@scottbb Memikirkannya benar-benar sama. Tapi saya khawatir Anda tidak akan mendapatkan yang lebih baik, karena pada dasarnya Anda memerlukan nama variabel dalam kondisi dan kemudian dalam ekspansi - saya tidak berpikir ada konstruksi shell yang akan melakukan itu hanya dengan satu kemunculan dari nama.
peterph
@ mikeserv - Saya mungkin seharusnya lebih tepat daripada mengatakan saya sedang mencari solusi yang lebih "elegan". Saya belum pernah benar-benar melihat ini dilakukan untuk menambahkan substring ke variabel gaya PATH, dan rasanya entah bagaimana saya kehilangan cara yang lebih baik. Dalam pengalaman saya, ketika saya mendapatkan perasaan itu, biasanya ada cara yang lebih baik. Itu yang seharusnya saya katakan. Tapi maksud Anda diterima dengan baik. Terimakasih atas tanggapan Anda. Juga: dalam salah satu suntingan komentar @ peterph Anda, Anda membuat komentar yang seharusnya saya kutip dari seluruh argumen export. Itu poin yang sangat bagus, saya jengkel detail itu juga.
scottbb
@scottbb - maaf jika itu dianggap abrasif - ive tidak pernah mengerti konsep keanggunan berkenaan dengan komputasi. komputer adalah mesin - gerbang tiga arah dan / atau miliaran kali lipat. itu tidak bisa dihitung lebih tinggi dari satu - dalam segala hal, setiap hal yang dilakukannya adalah paksa . beberapa konsep intuitif mungkin lebih mudah untuk diterjemahkan daripada yang lain, tetapi, jika demikian, itu hanya karena konsep tersebut berada di atas beberapa abstraksi paksa yang kasar lainnya. komputasi, pada intinya, selalu tidak elegan.
mikeserv
1

Akhir-akhir ini, saya mengatur GNU stow di komputer saya untuk menyimpan barang-barang di seluruh pengguna seperti perpustakaan di bawah ~/.localdan mengalami masalah ketika mendefinisikan LD_LIBRARY_PATH, CPATHdan LIBRARY_PATH, secara tidak sengaja meletakkan titik dua di sana dan dengan demikian memecahkan barang-barang.

Lalu saya menemukan pertanyaan Anda dan jawabannya tidak sepenuhnya elegan ;-), dan saya menulis fungsi kecil untuk menangani ini, silakan temukan di sini: 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 "${*}")"
}

// diedit seperti yang disarankan oleh @Kusalananda

Superlexx
sumber
Juga:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda
Yaitu:join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
Kusalananda
... Kecuali bahwa "bergabung" adalah nama yang tidak menguntungkan karena itu juga nama utilitas standar.
Kusalananda
Bagus, kecuali untuk fakta bahwa Anda akan menimpa variabel daripada menambahkannya. Hanya menambahkan ${!variable:+${!variable}:}di tempat yang tepat berhasil bagi saya, semua tes berlalu. Menemukan nama yang tepat adalah ukuran yang terlalu besar bagi pembaca :)
Superlexx