envsubst: ไม่พบคำสั่งบน Mac OS X 10.8


92

เมื่อฉันพยายามเรียกใช้สคริปต์ที่มีคำสั่ง envsubst ฉันได้รับข้อผิดพลาดนี้ เมื่อดูทางออนไลน์ดูเหมือนว่าจะเป็นคำสั่ง bash มาตรฐานดังนั้นฉันไม่แน่ใจว่าจะติดตั้งอะไรเพื่อให้มันใช้งานได้


2
envsubstรวมอยู่ในgettextแพ็คเกจ คุณอาจรวบรวมด้วยตัวคุณเอง ดูstackoverflow.com/questions/14940383/…
ymonad

ต้องการเพิ่มเป็นคำตอบเพื่อให้ฉันยอมรับได้หรือไม่
แอนดรูว์

ฉันโพสต์ไว้เป็นคำตอบ
ymonad

คำตอบ:


131

แก้ไข: anwer ของ @cobberboy ถูกต้องกว่า โหวตให้เขา

brew install gettext
brew link --force gettext 

ต่อไปนี้เป็นคำตอบเก่าของฉัน:

envsubstรวมอยู่ในgettextแพ็คเกจ

ดังนั้นคุณอาจรวบรวมมันด้วยตัวคุณเองโดยใช้เครื่องมือสร้างมาตรฐานเช่นหรือใช้makehomebrew

อย่างไรก็ตามดูเหมือนว่าจะมีปัญหาเล็กน้อยเมื่อติดตั้งgettextใน MacOS ดูรายละเอียด url ต่อไปนี้: วิธีติดตั้ง gettext บน MacOS X


8
แม้ว่าenvsubstจะเป็นส่วนหนึ่งของ gettext (ตามที่ติดตั้งโดย homebrew) จะไม่เชื่อมโยงโดยค่าเริ่มต้น ฉันคาดหวังว่านี่เป็นเพราะ gettext เป็นสูตรถังเท่านั้น คุณสามารถบอก homebrew ให้เชื่อมโยงถังได้ แต่อาจมีผลข้างเคียงที่ไม่ได้ตั้งใจ วิธีการล่วงล้ำน้อยในการติดตั้งนามแฝงโดยการเพิ่มalias envsubst='/usr/local/Cellar/gettext/0.19.6/bin/envsubst'ที่คุณ.profile(หรือเทียบเท่า) แน่นอนคุณอาจติดตั้ง gettext เวอร์ชันอื่นไว้ brew info gettextคุณสามารถเรียนรู้เกี่ยวกับเรื่องนี้โดยการเรียกใช้
trkoch

2
@trkoch คุณอาจต้องการที่จะนามแฝง/usr/local/opt/gettext/bin/envsubstซึ่งมีชีวิตอยู่การอัพเกรด
คริสโตHösler

1
แม้ว่านี่จะเป็นคำตอบที่ได้รับการยอมรับโปรดเลื่อนลงไปที่คำตอบของ @ cobberboy เนื่องจากอาจเป็นเรื่องปกติที่คุณต้องบังคับให้ลิงก์
Big Money

ฉันสงสัยว่าทำไมจู่ๆฉันถึงได้รับคะแนนโหวตเพิ่มขึ้น ขอบคุณสำหรับความเอื้ออาทรของคุณ @ymonad
cobberboy

1
การเชื่อมโยง /usr/local/Cellar/gettext/0.19.8.1 ... 194 symlinks สร้าง ... wtf 194 symlink?
Alexander Mills

235
brew install gettext
brew link --force gettext 

สิ่งนี้จะเปิดใช้งาน envsubst บน OS X และบังคับให้เชื่อมโยงอย่างถูกต้อง ต้องติดตั้ง homebrew


1
Linking /usr/local/Cellar/gettext/0.19.8.1... 194 symlinks created... wtf 194 symlinks?
Alexander Mills

@AlexanderMills ใช่gettextรวมถึงเรื่องมากมาย; ดูเหมือนว่าจะenvsubstติดตั้งมากเกินไป แต่เป็นวิธีที่เร็วและง่ายที่สุด
cobberboy

ดูเหมือนว่าพวกเขากำลังเชื่อมโยงทุกไฟล์แทนที่จะ
Alexander Mills

17

เพื่อขจัดความสับสนที่อาจเกิดขึ้น:

  • envsubstเป็นภายนอกปฏิบัติการและทำให้ส่วนหนึ่งไม่ได้ทุบตี ; ไฟล์ปฏิบัติการภายนอกขึ้นอยู่กับแพลตฟอร์มทั้งในแง่ของสิ่งที่พร้อมใช้งานตลอดจนพฤติกรรมเฉพาะและตัวเลือกเฉพาะที่รองรับ (แม้ว่าหวังว่าจะมีชุดย่อยทั่วไปตามข้อกำหนดของ POSIX)
  • คำสั่งที่สร้างขึ้นโดยตรงในbashที่เรียกว่าbuiltinsและมีเพียงพวกเขาสามารถพึ่งพาอาศัยเพื่อจะนำเสนอในทุกแพลตฟอร์ม

หากต้องการทดสอบว่าคำสั่งที่กำหนดเป็นแบบ builtin หรือไม่ให้ใช้

type <cmdName>

ในกรณีที่อยู่ในมือการทำงานtype envsubstบน macOS 10.13 จะกลับ-bash: type: envsubst: not foundมาซึ่งคุณสามารถอนุมานได้:

  • envsubst ไม่ใช่ในตัว
  • envsubstไม่ได้อยู่ในระบบของคุณ$PATH(และอาจไม่มีอยู่ในระบบของคุณ)

(ในทางตรงกันข้ามการรันคำสั่งเดียวกันบนคำสั่งเช่นระบบ Ubuntu 12.04 จะส่งคืนenvsubst is hashed (/usr/bin/envsubst)ซึ่งจะบอกคุณว่ามียูทิลิตี้อยู่และตำแหน่งที่อยู่)


ทางเลือกชั่วคราวenvsubstคือการใช้evalแม้ว่าจะมีข้อแม้ตามปกติ: ใช้evalเฉพาะกับสตริงที่มีเนื้อหาที่คุณควบคุมหรือเชื่อถือ:

สมมติว่าsample.txtไฟล์ที่มีข้อความที่มีการอ้างอิงตัวแปรที่ไม่ได้ขยาย เช่น:

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

เทียบเท่ากับ:

envsubst < sample.txt

คือ:

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

มีความแตกต่างที่สำคัญอย่างไรก็ตาม:

  • envsubstขยายเฉพาะการอ้างอิงตัวแปรสภาพแวดล้อม
  • ในขณะที่evalจะขยายเปลือกอ้างอิงตัวแปรเกินไป - เช่นเดียวกับที่ฝังแทนคำสั่งซึ่งเป็นสิ่งที่ทำให้การใช้ความกังวลด้านความปลอดภัยeval

ชอบไอเดียeval echoเพราะเชื่อแหล่งที่มา แต่ไม่เหมือนกัน .. envsubst < .env.exampleไม่ได้แค่eval echo < .env.example
iRaS

1

ตอนนี้ฉันใช้สิ่งนี้ในสคริปต์ทุบตีของฉันที่ต้องใช้ 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

คุณสามารถใช้เป็นคำสั่ง envsubst - แน่นอนว่าฟีเจอร์นี้ยังไม่สมบูรณ์หรืออย่างอื่น:

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

ดูเหมือนว่าจะตัดช่องว่างที่นำหน้าและต่อท้ายออกทั้งหมด
sudo

ตามที่กล่าวว่านี่เป็นวิธีแก้ปัญหาที่ยังไม่สมบูรณ์ คุณสามารถลองเพิ่ม"ประมาณ $ line แต่ฉันยังไม่ได้ลอง
iRaS

1

หากคุณไม่ต้องการรบกวนการติดตั้ง homebrew และ gettext ไฟล์ปฏิบัติการ perl หนึ่งบรรทัดจะทำ:

#!/usr/bin/perl -p
$_ =~ s/\Q${$1||$2}/$ENV{$1?$2:$4}/ while $_ =~ /(\$\{([^}]+)})|(\$(\w+))/g;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.