แนะนำให้ใช้ zsh แทนที่จะเป็นสคริปต์ทุบตีหรือไม่? [ปิด]


25

ฉันสามารถสันนิษฐานได้ว่ามีคนจำนวนมากพอที่จะzshติดตั้งเพื่อรันสคริปต์ด้วย

#!/usr/bin/env zsh

ในฐานะ shebang?

หรือสิ่งนี้จะทำให้สคริปต์ของฉันไม่สามารถทำงานได้บนระบบมากเกินไปหรือไม่

ชี้แจง: ฉันสนใจโปรแกรม / สคริปต์ที่ผู้ใช้อาจต้องการเรียกใช้ (เช่นบน Ubuntu, Debian, SUSE, Arch & c.)


4
คำถามแปลก ๆ ใครคือเป้าหมายของคุณ ในบางแวดวง (นักพัฒนาเว็บ Ruby-on-Rails) zshอาจได้รับความนิยมในขณะที่คนอื่น ๆ (ภาคธนาคาร) มันแทบไม่เคยได้ยินมาก่อน ฉันคิดว่าคุณควรให้ข้อมูลมากขึ้นถ้าคุณต้องการคำแนะนำที่เหมาะสมกับสิ่งนี้
rahmu

โลกผู้ใช้ทั่วไปของ linux
Profpatsch

2
WRT "โลกผู้ใช้ทั่วไปของ linux", zsh ไม่ได้มาตรฐาน มันไม่ได้ติดตั้งโดยค่าเริ่มต้น (ในส่วนใหญ่หรือ distros ทั้งหมด) หรือต้องการโดยอะไรดังนั้นคนส่วนใหญ่จะไม่ได้
goldilocks

3
ฉันไม่ได้zshติดตั้งบนระบบใด ๆของฉันและฉันจะไม่ติดตั้งสำหรับสคริปต์เดียว คุณควรหลีกเลี่ยงการ bashisms แม้ว่าโดยปกติแล้ว bash จะพร้อมใช้งาน
frostschutz

คำตอบ:


29

เพื่อความสะดวกในการพกพา ในขณะที่zshสามารถคอมไพล์บน Unix หรือ Unix-like และแม้แต่ Windows อย่างน้อยผ่าน Cygwin และถูกจัดทำแพ็กเกจสำหรับไลค์โอเพนซอร์สแบบ Unix และเชิงพาณิชย์ส่วนใหญ่โดยทั่วไปจะไม่รวมอยู่ในการติดตั้งเริ่มต้น

bashอีกด้านหนึ่งถูกติดตั้งบนระบบ GNU (เช่นเดียวbashกับเชลล์ของโครงการ GNU) เช่นระบบ Linux ส่วนใหญ่ที่ไม่ได้ฝังตัวและบางครั้งใช้กับระบบที่ไม่ใช่ GNU เช่น Apple OS / X ในด้าน Unix เชิงพาณิชย์ Korn shell (ตัวแปร AT&T แม้ว่าจะมากกว่าksh88หนึ่ง) นั้นเป็นบรรทัดฐานและทั้งคู่bashและzshอยู่ในแพ็คเกจเสริม บน BSDs เชลล์แบบโต้ตอบที่ต้องการมักจะอยู่tcshในขณะshนั้นขึ้นอยู่กับ Almquist shell หรือpdkshและbashหรือzshจะต้องติดตั้งเป็นแพ็คเกจเสริมเช่นกัน

zshติดตั้งตามค่าเริ่มต้นบน Apple OS / X มันเคยเป็นที่/bin/shนั่น มันสามารถพบได้ตามค่าเริ่มต้นในการแจกแจงลินุกซ์ไม่กี่อย่างเช่น SysRescCD, Grml, Gobolinux และอื่น ๆ แต่ฉันไม่คิดว่าสำคัญมาก

ชอบbashมีคำถามของรุ่นที่ติดตั้งและเป็นผลให้คุณสมบัติที่มีอยู่ ยกตัวอย่างเช่นมันไม่ใช่เรื่องแปลกที่จะหาระบบที่มีหรือbash3 zsh3นอกจากนี้ยังไม่มีการรับประกันว่าสคริปต์ที่คุณเขียนในขณะนี้zsh5จะทำงานได้zsh6เหมือนกันกับที่สคริปต์bashพยายามรักษาความเข้ากันได้ย้อนหลัง

สำหรับสคริปต์มุมมองของฉันคือ: ใช้ไวยากรณ์ POSIX เชลล์เนื่องจาก Unices ทั้งหมดมีอย่างน้อยหนึ่งเชลล์ที่เรียกว่าsh(ไม่จำเป็นต้องอยู่ใน/bin) ที่สามารถตีความไวยากรณ์นั้นได้ จากนั้นคุณไม่ต้องกังวลกับการพกพามากนัก และถ้าไวยากรณ์นั้นไม่เพียงพอสำหรับความต้องการของคุณคุณอาจต้องการเปลือกมากกว่า

จากนั้นตัวเลือกของคุณคือ:

  • Perl ซึ่งแพร่หลายทุกอย่าง (แม้ว่าคุณอาจต้อง จำกัด ตัวเองกับชุดคุณลักษณะของเวอร์ชั่นเก่าและไม่สามารถตั้งสมมติฐานบนโมดูล Perl ที่ติดตั้งเป็นค่าเริ่มต้น)
  • ระบุล่ามและรุ่นของมัน (python 2.6 หรือสูงกว่า, zsh 4 หรือสูงกว่า, bash 4.2 หรือสูงกว่า ... ), เป็นการอ้างอิงสำหรับสคริปต์ของคุณ, โดยการสร้างแพ็คเกจสำหรับทุกระบบเป้าหมายที่ระบุการพึ่งพาหรือโดยการกำหนดมัน ในไฟล์ README ที่ส่งมาพร้อมกับสคริปต์ของคุณหรือฝังไว้เป็นความคิดเห็นที่ด้านบนสุดของสคริปต์ของคุณหรือโดยการเพิ่มสองสามบรรทัดในไวยากรณ์ Bourne ที่จุดเริ่มต้นของสคริปต์ของคุณที่ตรวจสอบความพร้อมของล่ามที่ร้องขอ เมื่อมันไม่ได้เช่นสคริปต์นี้ความต้องการ zsh 4.0 หรือสูงกว่า
  • จัดส่งล่ามมาพร้อมกับสคริปต์ของคุณ (ระวังเรื่องลิขสิทธิ์) ซึ่งหมายความว่าคุณต้องมีหนึ่งแพ็คเกจสำหรับทุกระบบปฏิบัติการ ล่ามบางตัวทำให้เป็นเรื่องง่ายขึ้นโดยจัดเตรียมวิธีในการแพ็คสคริปต์และล่ามในชุดคำสั่งเดียว
  • เขียนเป็นภาษาที่รวบรวม อีกครั้งหนึ่งแพ็คเกจต่อระบบเป้าหมาย

"zsh-man" พูดว่า "ไม่" ฉันภูมิใจในตัวคุณ! ^^ พกพาได้ ftw! (ด้วยคำเตือนทั้งหมด ... ) +1
Olivier Dulac

9

ไม่คุณไม่สามารถ. สิ่งที่รับประกันได้คือ/bin/shเปลือก Bourne ดั้งเดิม เกือบทั้งหมด (โปรดสังเกตว่า "เกือบ"!) การติดตั้ง Linux จะมีการทุบตี แต่ในระบบ * BSD มันเป็นเรื่องยาก ฉันไม่รู้ว่าเชลล์มาตรฐานคืออะไรบน Mac แต่อีกครั้งมีข้อสงสัยเกี่ยวกับ GPL เช่นเดียวกันสำหรับ Solaris

zsh เป็นเชลล์เฉพาะไม่ได้อยู่ในการติดตั้งเริ่มต้นของ Fedora (และฉันไม่เชื่อว่ามันจะเป็นค่าเริ่มต้นสำหรับการแจกจ่ายหลัก ๆ )


6
ไม่ใช่ Bourne Shell ดั้งเดิม แต่เป็น Posix shell ในระบบที่เข้ากันได้กับ Posix ซึ่งในหลาย ๆ ระบบคือ / bin / sh แต่ไม่จำเป็นต้องทำเช่นนั้น (ใน Solaris <= เวอร์ชัน 10 นี่คือ / usr / xpg4 / bin / sh)
Scrutinizer

การติดตั้ง“ เริ่มต้น” นั้นไม่สำคัญ สิ่งที่สำคัญคือถ้าติดตั้งเลย
Profpatsch

@Profpatsch จากนั้นการติดตั้งเริ่มต้นจะมีความเกี่ยวข้องมาก (สันนิษฐานว่าการแจกจ่ายจะพิจารณาว่าผู้คนใช้อะไรจริงๆ)
vonbrand

2
@StephaneChazelas "ช่อง" ใน "ผู้ใช้ไม่กี่คนใช้มัน" / "ติดตั้งน้อยมี" มันอาจจะเป็นเปลือกที่ดีที่สุดตั้งแต่ขนมปังหั่นบาง ๆ แต่ถ้ามีเพียงเศษเสี้ยวเล็ก ๆ ที่ใช้มันคุณไม่สามารถนับได้ว่ามันจะถูกติดตั้งทุกที่
vonbrand

1
โปรดทราบว่าถ้าคุณพิจารณาว่าส่วนที่ดีของลินุกซ์ปรับใช้จะถูกฝังอยู่ในปัจจุบัน (คิดว่าหุ่นยนต์, เครื่องพิมพ์, เราเตอร์, ทีวี, หลอดไฟ ... ), ส่วนใหญ่ของระบบ Linux ตามไม่ได้มีbash( แต่ระบบเหล่านั้นอาจจะไม่ได้เป็นหลัก กำหนดเป้าหมาย OP ไว้ในใจสำหรับคำถามของเขา)
Stéphane Chazelas

2

ฉันคิดว่ามันขึ้นอยู่กับคุณสมบัติพิเศษของzsh ที่คุณใช้และสถานที่ หากคุณกำลังวางแผนที่จะแจกจ่ายสคริปต์ของคุณทั่วทั้งผู้ใช้ที่แตกต่างกันและระบบที่ผมจะแนะนำให้ใช้ทุบตีหรือแม้กระทั่งการดวลจุดโทษ

ในเวลาเดียวกันถ้าสคริปต์ของคุณออกแบบมาให้ทำงานทั่วทั้งองค์กรของคุณและคุณมีระเบียบให้zshบนเครื่องของคุณ (เช่น AMI พื้นฐานเดียวกัน) และงานของคุณมีประโยชน์ชัดเจนจากส่วนขยายเช่นตัวเลือกไฟล์ขั้นสูงหรือสิ่งอื่น ๆ จากhttp: / /www.rayninfo.co.uk/tips/zshtips.htmlฉันจะบอกว่าไปข้างหน้า!


1

ตามที่ระบุไว้bashโดยทั่วไปจะมีอยู่ในการติดตั้งเริ่มต้นสำหรับหลาย distros zshสคริปต์ของคุณจะไม่สามารถเข้าถึงฐานผู้ใช้ที่ยิ่งใหญ่ที่สุดโดยอาศัย

คำถามสำคัญที่ต้องตอบก่อนออกแบบสคริปต์ของคุณคือ " ทำไมจึงมีความสำคัญว่าเชลล์สคริปต์ใดที่เรียกใช้สคริปต์? "

เชลล์ที่แตกต่างกันใช้ไวยากรณ์ที่แตกต่างกันหรือเสนอฟังก์ชั่นของเชลล์เพิ่มเติมที่เชลล์อื่นอาจไม่รองรับ ในการเขียนสคริปต์สำหรับ "โลกผู้ใช้ทั่วไปของ linux" ให้พิจารณาว่าสคริปต์ของคุณใช้ไวยากรณ์หรือฟังก์ชั่นเชลล์ใด ๆ ที่อาศัยสภาพแวดล้อมเชลล์เฉพาะหรือไม่

ตัวอย่างเช่นbashเชลล์สนับสนุนการขยายบางอย่างที่ไม่ได้รับการสนับสนุนโดยdashเชลล์เป้าหมายหรือ/bin/shจุดใดก็ตามที่อยู่บนระบบของผู้ใช้

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

ลองดำเนินการecho {1..10}ด้วย/bin/shเมื่อเทียบกับ/bin/bashและคุณจะได้รับผลที่แตกต่างกันมาก

เดียวกันจะไปสำหรับzshซึ่งในขณะที่การสนับสนุนมากที่สุดbashไวยากรณ์ข้อเสนอการขยายตัวเพิ่มขึ้นและไวยากรณ์ที่ไม่ได้รับการสนับสนุนจากbashเปลือก ดูตารางนี้เปรียบเทียบเชลล์สำหรับตัวอย่างเฉพาะ

คุณสามารถขยายฐานผู้ใช้ของคุณที่มีศักยภาพเกินโดยยึดมั่นในสคริปต์ที่ทำงานเมื่อเรียกว่ามีbash #!/bin/sh -uอย่างไรก็ตามสิ่งนี้ก่อให้เกิดคำถามสำคัญอีกข้อหนึ่งที่ถามว่า: " อะไรคือสิ่งที่เสียสละเพื่อแลกกับการพกพาที่มากขึ้น? "

พิจารณาว่าความแตกต่างที่เกี่ยวข้องกับความปลอดภัยฟังก์ชั่นประสิทธิภาพหรือสิ่งอื่นใดที่คุณรู้สึกว่ามีความสำคัญสำหรับสคริปต์ของคุณจะคุ้มค่าเสียสละ คุณอาจไม่ต้องการใช้สคริปต์ที่มีจุดอ่อนด้านความปลอดภัยที่รู้จักกันแพร่หลายเพราะมันทำงานได้ในสภาพแวดล้อมที่มากขึ้น

สคริปต์จำนวนมากดังนั้นจะเขียนสำหรับbashการสนับสนุนสำหรับสคริปต์เหล่านี้ถูกนำมาใช้เป็นเกณฑ์เมื่อเปรียบเทียบหอยคำสั่ง ผู้คนจำนวนมากจะสามารถเรียกใช้สคริปต์ของคุณได้มากกว่าที่จะต้องอาศัยzshหรือไวยากรณ์อื่นใดที่ไม่รวมอยู่ในสภาพแวดล้อมของเชลล์

นอกจากนี้โปรดจำไว้ว่าในที่สุดคุณจะไม่สามารถควบคุมวิธีที่ผู้ใช้เรียกใช้งานสคริปต์ (เช่นมีประโยชน์สำหรับการดีบักสคริปต์ในเชลล์ที่แตกต่างกัน ):

จำไว้ว่าถ้าคุณใช้เชลล์เพื่ออ่านเชลล์สคริปต์ (“ sh scriptname”) แทนที่จะเรียกใช้งานโดยตรง (“ ./scriptname”) เชลล์จะถือว่าข้อคิดเห็นทั้งหมดที่จุดเริ่มต้นของเชลล์สคริปต์เป็นความคิดเห็น โดยเฉพาะอย่างยิ่งความคิดเห็นที่ระบุล่ามที่จะใช้เมื่อเรียกใช้งานสคริปต์ (“ #! / bin / sh -u”) จะถูกละเว้นเช่นเดียวกับตัวเลือกทั้งหมดที่แสดงข้างล่ามนั้น

ดังนั้นสิ่งที่ดีที่สุดที่คุณสามารถทำได้คือทำให้สคริปต์ของคุณเป็นแบบพกพาตราบใดที่ไม่มีการเสียสละอันยิ่งใหญ่ในการทำงานของมัน

นอกจากนี้คุณยังอาจเห็นทุบตีประชุมการเข้ารหัส - กองมากเกิน


1
"สิ่งที่กำลังเสียสละ" ... ดูที่ autoconf พวกเขากำหนดเป้าหมาย / bin / sh เช่นเดียวกับใน "Original Bourne Shell" เพราะเชลล์ทั้งหมดสนับสนุนชุดคุณลักษณะ (ขนาดเล็ก) ที่ และพวกเขาทนทุกข์กับมันอย่างมาก
Jürgen A. Erhard

1

/bin/shสิ่งเดียวที่คุณเกือบจะสามารถรับประกันว่าจะมี นั่นอาจเป็นเชลล์ที่ลิงก์แบบสแตติกจริงหรืออาจเป็นลิงก์ไปยังเชลล์อื่น เชลล์อื่น ๆ มักตรวจพบว่ามันถูกเรียกว่า sh และจะทำงานในโหมดความเข้ากันได้

สังเกตุเกือบในประโยคแรก

ระบบยูนิกซ์ทุกอย่างที่ฉันเคยทำ หลายคนติดตั้ง bash ไว้แล้ว (แต่ไม่ใช่ทั้งหมดเช่น bash นั้นไม่ได้ติดตั้งไว้ใน BSD บางเครื่องการกระจาย Linux บางตัวที่มีDASH , Debian Almquist shell แทน

สิ่งที่คุณสามารถรับประกันได้คือคำแนะนำในการติดตั้ง คุณสามารถเพิ่มบรรทัดลงในไฟล์ README ที่ระบุว่าต้องการ zsh หากคุณสร้างแพ็คเกจจากนั้นคุณสามารถทำเครื่องหมาย zsh เป็นการพึ่งพา คุณสามารถตรวจสอบได้ด้วยเครื่องมือ autoconf / automake คุณสามารถตรวจสอบว่าพบ zsh ในสคริปต์การติดตั้ง (เริ่มต้นด้วย / bin / sh แล้วลองค้นหา zsh หากพบต่อไปหากไม่แสดงข้อผิดพลาดเช่น "คำเตือน: ไม่ได้ติดตั้ง ZSH โปรดอ่านไฟล์คำแนะนำการติดตั้ง! ".)

ฉันแน่ใจว่าฉันลืมตัวเลือกเพิ่มเติมไม่กี่ตัว แต่ประเด็นสำคัญคือ:

  • คุณสามารถรับประกันอะไรจนกว่าคุณจะตรวจสอบมัน
  • คุณเกือบจะรับประกันว่า / bin / sh มีอยู่และคุณสามารถตรวจสอบได้

POSIX ต้องการ / bin / sh, AFAIU เช่นเดียวกับที่ต้องใช้สาธารณูปโภคที่สมเหตุสมผลอื่น ๆ ตรวจสอบสิ่งที่จำเป็นต้องมีสำหรับ GNU autoconfiscation
vonbrand

@vonbrand POSIX /bin/shไม่จำเป็นต้องมี มันต้องการสิ่งshที่อยู่ในสภาพแวดล้อมที่ถูกต้อง (ซึ่งไม่จำเป็นต้องเป็นสภาพแวดล้อมเริ่มต้น) ตามที่ระบุ /bin/shอาจไม่ใช่ POSIX เชลล์ ยกตัวอย่างเช่น Solaris 10 และก่อนหน้านี้ก็ยังคงเป็นบอร์นเชลล์และมาตรฐานอยู่ในsh /usr/xpg4/bin
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.