envsubst: không tìm thấy lệnh trên Mac OS X 10.8


92

Khi tôi cố gắng chạy tập lệnh có chứa lệnh envsubst, tôi gặp lỗi này. Nhìn trên mạng, đây có vẻ là một lệnh bash tiêu chuẩn, vì vậy tôi không chắc phải cài đặt những gì để nó hoạt động.


2
envsubstđược bao gồm trong gettextgói. bạn có thể biên dịch của riêng bạn. xem stackoverflow.com/questions/14940383/…
ymonad

Bạn muốn thêm câu trả lời đó làm câu trả lời để tôi có thể chấp nhận nó?
Andrew

Tôi đã đăng nó như một câu trả lời.
ymonad

Câu trả lời:


131

Chỉnh sửa: Anwer của @cobberboy thì đúng hơn. ủng hộ anh ấy.

brew install gettext
brew link --force gettext 

Sau đây là câu trả lời cũ của tôi:

envsubstđược bao gồm trong gettextgói.

Do đó, bạn có thể tự biên dịch nó bằng cách sử dụng các công cụ xây dựng tiêu chuẩn như makehoặc sử dụng homebrew.

Tuy nhiên, nó dường như gặp ít vấn đề khi cài đặt gettexttrong MacOS. Xem url sau để biết chi tiết: Cách cài đặt gettext trên MacOS X


8
Mặc dù envsubstlà một phần của gettext (được cài đặt bởi homebrew), nó không được liên kết theo mặc định. Tôi mong đợi điều này là vì gettext là một công thức chỉ keg. Bạn có thể nói với homebrew để liên kết thùng, nhưng điều này có thể có tác dụng phụ ngoài ý muốn. Một cách tiếp cận ít xâm phạm hơn là thiết lập bí danh bằng cách thêm alias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'vào .profile(hoặc tương đương) của bạn. Tất nhiên, bạn có thể đã cài đặt một phiên bản gettext khác. Bạn có thể tìm hiểu về nó bằng cách chạy brew info gettext.
trkoch

2
@trkoch Bạn có thể muốn bí danh /usr/local/opt/gettext/bin/envsubstmà sống sót nâng cấp
Christoph Hösler

1
Mặc dù đây là câu trả lời được chấp nhận, vui lòng cuộn xuống câu trả lời của @ cobberboy, vì nó cũng có thể là phổ biến mà bạn cần buộc liên kết.
Big Money

Tôi tự hỏi tại sao tôi đột nhiên nhận được nhiều ủng hộ hơn. Cảm ơn vì sự hào phóng của bạn @ymonad
cobberboy

1
Liên kết /usr/local/Cellar/gettext/0.19.8.1 ... 194 liên kết tượng trưng được tạo ... wtf 194 liên kết tượng trưng?
Alexander Mills

235
brew install gettext
brew link --force gettext 

Điều này sẽ kích hoạt envsubst trên OS X và buộc nó phải liên kết đúng cách. Nó yêu cầu phải cài đặt homebrew.


1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... wtf 194 liên kết tượng trưng?
Alexander Mills

@AlexanderMills vâng gettextbao gồm rất nhiều thứ; Nó có vẻ như quá mức cần thiết chỉ để envsubstcài đặt nhưng đó là cách nhanh nhất và đơn giản nhất.
cobberboy

có vẻ như họ đang mã hóa mọi tệp thay vì chỉ liên kết mã hóa một thư mục
Alexander Mills

17

Để giải tỏa sự nhầm lẫn tiềm ẩn:

  • envsubstlà một tệp thực thi bên ngoài và do đó không phải là một phần của Bash ; các tệp thực thi bên ngoài phụ thuộc vào nền tảng , cả về mặt nào khả dụng cũng như hành vi cụ thể của chúng và các tùy chọn cụ thể mà chúng hỗ trợ (tuy nhiên, hy vọng có một tập hợp con chung dựa trên các thông số kỹ thuật của POSIX)
  • Các lệnh được tích hợp trực tiếp bashđược gọi là nội trang và chỉ chúng có thể được dựa vào để có mặt trên tất cả các nền tảng .

Để kiểm tra xem một lệnh đã cho có phải là nội trang hay không , hãy sử dụng

type <cmdName>

Trong trường hợp hiện tại, chạy type envsubsttrên macOS 10.13 trả về -bash: type: envsubst: not found, từ đó bạn có thể suy ra:

  • envsubst KHÔNG phải là nội trang
  • envsubstkhông có trong hệ thống của bạn $PATH(và do đó có khả năng không xuất hiện trên hệ thống của bạn)

(Ngược lại, chạy lệnh tương tự trên, ví dụ, hệ thống Ubuntu 12.04 trả về envsubst is hashed (/usr/bin/envsubst), điều này cho bạn biết rằng tiện ích đang có mặt và vị trí của nó.)


Một giải pháp thay thế tạm thời envsubstlà sử dụng eval, mặc dù áp dụng cảnh báo thông thường: evalchỉ sử dụng trên các chuỗi có nội dung bạn kiểm soát hoặc tin cậy:

Giả sử một sample.txttệp chứa văn bản với các tham chiếu biến không được mở rộng; ví dụ:

cat > sample.txt <<'EOF'
Honey, I'm $USER
and I'm $HOME.
EOF

Tương đương với:

envsubst < sample.txt

Là:

eval "echo \"$(sed 's/"/\\"/g' sample.txt)\""

Tuy nhiên, có một sự khác biệt quan trọng :

  • envsubstchỉ mở rộng các tham chiếu biến môi trường
  • trong khi đó evalsẽ mở rộng vỏ tài liệu tham khảo biến quá - cũng như nhúng thay thế lệnh , đó là những gì làm cho sử dụng của evalmột mối quan tâm an ninh.

Tôi thích ý tưởng eval echovì tôi tin tưởng vào nguồn nhưng nó không giống nhau .. envsubst < .env.examplekhông thể chỉ làeval echo < .env.example
IRAS

1

Bây giờ tôi đang sử dụng điều này trong tập lệnh bash của mình yêu cầu envsubst:

if ! which envsubst > /dev/null 2>&1; then
    envsubst() {
        while read line; do
            line=$( echo $line | sed 's/"/\\"/g' )
            eval echo $line
        done
    }
fi

bạn có thể sử dụng nó dưới dạng lệnh envsubst - tất nhiên nó không hoàn chỉnh về tính năng hoặc một cái gì đó khác:

envsubst <<<'Honey, I am $HOME.'
envsubst < input > output 2> corrupt

Điều này dường như lột tất cả hàng đầu và dấu khoảng trắng
sudo

như đã nói đây là một giải pháp thay thế không hoàn chỉnh về tính năng. bạn có thể thử thêm "khoảng $ line nhưng tôi chưa thử cái này
iRaS

1

Nếu bạn không muốn cài đặt homebrew và gettext, một tệp thực thi perl một dòng sẽ thực hiện:

#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
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.