Nối vào biến giống PATH mà không tạo dấu hai chấm đầu nếu không đặt


10

Tôi cần phải thêm một thư mục vào PKG_CONFIG_PATH. Thông thường, tôi sẽ sử dụng tiêu chuẩn

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

nhưng PKG_CONFIG_PATHtrước đây chưa được thiết lập trên hệ thống của tôi. Do đó, biến bắt đầu bằng một :ký tự, cho biết nó tìm trong thư mục hiện tại trước. Tôi không muốn điều đó. Tôi giải quyết sau đây,

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

nhưng điều đó có vẻ rất xấu Có cách nào tốt hơn? Cách thích hợp để nối có điều kiện dấu hai chấm khi và chỉ khi biến đã được đặt là gì?


Câu trả lời:


13

Bạn đang đi đúng hướng với ${:+}toán tử mở rộng, bạn chỉ cần sửa đổi nó một chút:

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

Niềng răng đầu tiên mở rộng $V iff dấu hai chấm Vđược đặt thành không có gì - đó chính xác là những gì bạn cần (và có lẽ cũng là một trong những lý do cho sự tồn tại của toán tử).

Vì vậy, trong trường hợp của bạn:

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

Tôi đã sử dụng hình thức đó, nhưng tôi đã quyết định chống lại nó bởi vì nó cảm thấy (hơi) ít có thể đọc: ${V}${V:+:}Wvs ${V:+${V}:}W. Dù bằng cách nào, cả hai đều cảm thấy thực sự xấu xí. Tôi đã hy vọng cho một cái gì đó ... thanh lịch hơn, tôi đoán?
scottbb

@scottbb - đây là dạng cú pháp - đó là cách nó được thực hiện. Nếu bạn muốn đặt giá trị của biến dựa trên điều kiện bạn phải thực hiện kiểm tra. Bạn có thể thực hiện kiểm tra nội tuyến như được viết ở đây hoặc bạn có thể kiểm tra rõ ràng test- bằng cách nào đó, bạn đang kiểm tra giá trị và viết varname hai lần, nhưng theo cách này bạn thực hiện nó trong một câu lệnh thực thi - theo cách đó là thực tế , nhưng tôi chưa bao giờ gặp một máy tính thanh lịch .
mikeerv

@scottbb Nghĩ về nó nó thực sự giống nhau. Nhưng tôi e rằng bạn sẽ không nhận được nó tốt hơn, vì về cơ bản bạn cần tên biến trong điều kiện và sau đó trong bản mở rộng - Tôi không nghĩ có một cấu trúc shell sẽ làm điều đó chỉ với một lần xuất hiện của Tên.
peterph

@mikeerv - Có lẽ tôi nên chính xác hơn là nói rằng tôi đang tìm kiếm một giải pháp "thanh lịch" hơn. Tôi chưa bao giờ thực sự thấy điều này được thực hiện để nối các chuỗi con vào các biến kiểu PATH và có cảm giác như tôi đang thiếu một cách tốt hơn. Theo kinh nghiệm của tôi, khi tôi có được cảm giác đó, thường có một cách tốt hơn. Đó là những gì tôi nên nói. Nhưng quan điểm của bạn cũng thực hiện. Cám ơn phản hồi của bạn. Ngoài ra: trong một trong những chỉnh sửa nhận xét của @ peterph, bạn đã đưa ra nhận xét mà tôi nên trích dẫn toàn bộ đối số export. Đó là một điểm rất tốt, tôi cũng đánh giá chi tiết đó.
scottbb

@scottbb - xin lỗi nếu điều đó bị bào mòn - tôi chưa bao giờ hiểu khái niệm về sự thanh lịch liên quan đến điện toán. một máy tính là một cỗ máy - ba chiều và / hoặc cổng gộp hàng tỷ lần. nó không thể đếm cao hơn một - theo mọi cách, mọi thứ nó làm đều bị ép buộc . một số khái niệm trực quan có thể dễ dịch hơn các khái niệm khác, nhưng, nếu vậy, đó chỉ là do khái niệm này nằm trên một số trừu tượng bắt buộc khác. điện toán, tại trung tâm của nó, luôn luôn là bất cứ điều gì nhưng thanh lịch.
mikeerv

1

Gần đây, tôi đã thiết lập GNU stow trên các máy của mình để lưu trữ những thứ toàn người dùng như thư viện bên dưới ~/.localvà gặp rắc rối khi xác định LD_LIBRARY_PATH, CPATHLIBRARY_PATH, vô tình đặt dấu hai chấm ở đó và phá vỡ mọi thứ.

Sau đó, tôi thấy câu hỏi của bạn và câu trả lời là không chính xác nhã ;-), và tôi đã viết một hàm nhỏ để xử lý việc này, hãy tìm nó ở đây: https://gist.github.com/rico-chet/0229e4c080d9f51a02535dd25a656a8a

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

// được chỉnh sửa theo đề xuất của @Kusalananda


Ngoài ra:( IFS=:; set -- 1 2 3 4 5 6; echo "$*" )
Kusalananda

Tức là:join () { var=$1; shift; export "$var"="$( IFS=:; echo "$*" )"; }
Kusalananda

... Ngoại trừ việc "tham gia" là một cái tên không may mắn vì nó cũng là tên của một tiện ích tiêu chuẩn.
Kusalananda

Một cái hay, ngoại trừ việc bạn ghi đè lên biến thay vì nối thêm vào nó. Chỉ cần thêm ${!variable:+${!variable}:}vào đúng nơi làm việc cho tôi, tất cả các bài kiểm tra đã qua. Tìm một tên thích hợp là một kích thước lớn cho người đọc :)
Superlexx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.