โปรแกรมสามารถเขียนด้วย Bash บริสุทธิ์ได้อย่างไร [ปิด]


17

หลังจากที่บางวิจัยอย่างรวดเร็วมากดูเหมือนทุบตีเป็นภาษาทัวริงสมบูรณ์

ฉันสงสัยว่าเพราะเหตุใด Bash จึงใช้สคริปต์เกือบทั้งหมดเพื่อเขียนสคริปต์ที่ค่อนข้างง่าย เนื่องจาก Bash shell มาพร้อมกับ Linux คุณสามารถเรียกใช้เชลล์สคริปต์ได้โดยไม่ต้องมีตัวแปลหรือคอมไพเลอร์ภายนอกตามที่จำเป็นสำหรับภาษาคอมพิวเตอร์ที่เป็นที่นิยมอื่น ๆ นี่เป็นข้อได้เปรียบที่ยิ่งใหญ่ที่สามารถชดเชยความธรรมดาของภาษาในบางกรณี

ดังนั้นจึงมีข้อ จำกัด ว่าโปรแกรมดังกล่าวจะซับซ้อนแค่ไหน? Pure Bash ใช้ในการเขียนโปรแกรมที่ซับซ้อนหรือไม่? เป็นไปได้ที่จะเขียน, พูด, ไฟล์คอมเพรสเซอร์ / decompressor ใน Bash บริสุทธิ์? คอมไพเลอร์? วิดีโอเกมง่ายๆ?

มันใช้อย่างเบาบางเพียงเพราะมีเครื่องมือดีบั๊กที่ จำกัด เท่านั้นใช่ไหม


2
shสคริปต์configureซึ่งจะใช้เป็นส่วนหนึ่งของการสร้างกระบวนการสำหรับการที่ดีมากยกเลิก * x แพคเกจไม่เป็น 'ค่อนข้างง่าย'
user4556274

@ user4556274 ไม่ใช่ แต่โดยทั่วไปมักจะไม่เขียนด้วยมือ แต่มาจากชุดm4แมโครจำนวนมาก
Kusalananda

2
มีแอสเซมเบลอร์ x86ใน Bash ดังนั้นใช่ Bash บางครั้งใช้เพื่อเขียนโปรแกรมที่ซับซ้อน ทำไมคนไม่ทำเช่นนั้นบ่อยขึ้น? อาจเป็นไปได้ว่าล่ามนั้นช้าช้าเส็งเคร็งและมีแนวโน้มที่จะเกิดข้อผิดพลาด "น่าสนใจ" (ดูที่Shellshock fi ) นอกจากนี้สคริปต์ทุบตีมักจะยากที่จะรักษาขนาด ดูที่แอสเซมเบลอร์ด้านบน คุณสามารถบอกได้จากแหล่งที่มาถ้ามันเป็นไปตาม AT&T หรือไวยากรณ์ของ Intel?
Satō Katsura

configureสคริปต์ก็ช้าทำงานกลุ่มไร้ประโยชน์ทั้งหมดและเป็นหัวข้อของการคุยโวที่น่าขบขัน แน่นอนเปลือกสามารถนำมาใช้สำหรับโปรแกรมที่มีขนาดใหญ่ แต่แล้วอีกครั้งคนยังได้ทำให้เครื่องคอมพิวเตอร์ออกจากเกมคอนเวย์ของชีวิตและ Minecraft และยังมีการเขียนโปรแกรมภาษาเช่น Brainf ** k และHexagony เห็นได้ชัดว่าบางคนชอบสร้างบางสิ่งจากอะตอมที่เล็กและสับสน คุณสามารถขายเกมที่มีความคิดเช่นนั้นได้ด้วย
ilkkachu

ดังนั้นคำถามนี้ตอบได้หรือไม่? พวกเขาพักไว้และบอกว่ามันตอบไม่ได้ แต่ถึงกระนั้นฉันก็ได้รับคำตอบที่ดี มันจะเป็นการดีที่จะเชื่อมโยงกันในขณะที่ฉันใหม่กับ SE นี้เพื่อที่จะนำฉันไปยังคำถามประเภทใดและไม่เป็นที่ต้องการใน SE นี้
Bregalad

คำตอบ:


30

ดูเหมือนว่า Bash เป็นภาษาทัวริงที่สมบูรณ์

แนวคิดของทัวริงสมบูรณ์แยกจากแนวคิดอื่น ๆ อีกมากมายที่มีประโยชน์ในภาษาสำหรับการเขียนโปรแกรมในขนาดใหญ่ : การใช้งานการแสดงออกความเข้าใจความเร็ว ฯลฯ

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

เหตุใด Bash จึงใช้สคริปต์ที่เรียบง่ายเป็นพิเศษในการเขียน

สคริปต์เชลล์ขนาดใหญ่และซับซ้อน - เช่นconfigureสคริปต์เอาต์พุตโดย GNU Autoconf - ผิดปกติด้วยเหตุผลหลายประการ:

  1. จนกระทั่งเร็ว ๆ นี้ค่อนข้างที่คุณไม่สามารถนับบนมีเปลือก POSIX ได้ทุกที่

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

    Pre-POSIX Bourne shells ไม่มีแม้แต่เลขคณิตในตัว คุณต้องโทรออกexprหรือbcทำสิ่งนั้นให้สำเร็จ

    ถึงแม้จะมีเปลือก POSIX คุณจะหายไปหมดในarrays สมาคมและคุณสมบัติอื่น ๆ ที่เราเคยคาดว่าจะพบในระบบปฏิบัติการยูนิกซ์ภาษาสคริปต์ตั้งแต่ Perl แรกที่กลายเป็นที่นิยมในช่วงปี 1990

    ความเป็นจริงในประวัติศาสตร์นั้นหมายความว่ามีประเพณีมายาวนานหลายทศวรรษในการเพิกเฉยคุณลักษณะที่ทรงพลังจำนวนมากในล่ามสคริปต์ตระกูล Bourne ตระกูลสมัยใหม่อย่างหมดจดเพราะคุณไม่สามารถไว้ใจได้ทุกที่

    นี้ยังคงดำเนินต่อไปในวันนี้ในความเป็นจริง: ทุบตีไม่ได้รับการเชื่อมโยงอาร์เรย์จนถึง 4 รุ่นแต่คุณอาจจะแปลกใจว่าหลายระบบยังคงอยู่ในการใช้งานจะขึ้นอยู่กับทุบตี 3. แอปเปิ้ลยังคงเรือ Bash 3 กับ MacOS ในปี 2017 - เห็นได้ชัดว่า เหตุผลการออกใบอนุญาต - และเซิร์ฟเวอร์ Unix / Linux มักจะทำงานทั้งหมด แต่ไม่ได้ถูกแตะต้องในการผลิตเป็นเวลานานดังนั้นคุณอาจมีระบบเก่าที่เสถียรซึ่งยังคงใช้งาน Bash 3 เช่นกล่อง CentOS 5 หากคุณมีระบบดังกล่าวในสภาพแวดล้อมของคุณคุณไม่สามารถใช้อาเรย์แบบเชื่อมโยงในเชลล์สคริปต์ที่ต้องทำงานกับมัน

    หากคำตอบของคุณสำหรับปัญหานั้นคือคุณเขียนเชลล์สคริปต์สำหรับระบบ "ทันสมัย" เท่านั้นคุณต้องรับมือกับข้อเท็จจริงที่ว่าจุดอ้างอิงทั่วไปสุดท้ายสำหรับเชลล์ Unix ส่วนใหญ่คือPOSIX เชลล์มาตรฐานซึ่งส่วนใหญ่ไม่เปลี่ยนแปลงเนื่องจากเป็น เปิดตัวในปี 1989 มีกระสุนจำนวนมากที่แตกต่างกันไปตามมาตรฐานนั้น แต่พวกมันต่างกันที่องศาที่แตกต่างจากมาตรฐานนั้น เพื่อที่จะใช้เชื่อมโยงอาร์เรย์อีกครั้งbash, zshและksh93ทุกคนมีคุณลักษณะที่ แต่มีการดำเนินการกันไม่ได้หลาย ๆ ทางเลือกของคุณแล้วคือการเพียงใช้ทุบตีหรือเพียงใช้ zsh หรือเพียงksh93ใช้

    หากคำตอบของคุณสำหรับปัญหานั้นคือ "ดังนั้นเพียงแค่ติดตั้ง Bash 4" ksh93หรืออะไรก็ตามทำไมไม่ "เพียงแค่" ติดตั้ง Perl หรือ Python หรือ Ruby แทน? ที่ยอมรับไม่ได้ในหลายกรณี ค่าเริ่มต้นเป็นเรื่อง

  2. ไม่มีของบอร์นเปลือกครอบครัวสนับสนุนภาษาสคริปต์โมดูล

    ที่ใกล้เคียงที่สุดที่คุณสามารถมากับระบบโมดูลในสคริปต์เปลือกเป็น.คำสั่ง - อาคาsourceในบอร์นที่ทันสมัยมากขึ้นเปลือกสายพันธุ์ - ซึ่งล้มเหลวในหลายระดับเมื่อเทียบกับระบบโมดูลที่เหมาะสมที่สุดพื้นฐานของซึ่งเป็นnamespacing

    ความเข้าใจของมนุษย์เริ่มตั้งค่าสถานะเมื่อไฟล์เดียวในโปรแกรมโดยรวมที่ใหญ่กว่าเกินสองสามบรรทัด เหตุผลที่เราจัดโครงสร้างโปรแกรมขนาดใหญ่เป็นไฟล์จำนวนมากคือเพื่อให้เราสามารถสรุปเนื้อหาของพวกเขาให้เป็นประโยคหนึ่งหรือสองประโยคได้มากที่สุด ไฟล์ A คือตัวแยกวิเคราะห์บรรทัดคำสั่งไฟล์ B คือปั๊ม I / O เครือข่ายไฟล์ C คือ shim ระหว่างไลบรารี่ Z และส่วนที่เหลือของโปรแกรม ฯลฯ เมื่อวิธีการเดียวของคุณสำหรับการประกอบไฟล์จำนวนมากเข้าในโปรแกรมเดียวคือการรวมข้อความ คุณ จำกัด จำนวนโปรแกรมของคุณที่จะเติบโตอย่างมีเหตุผล

    สำหรับการเปรียบเทียบมันจะเหมือนกับว่าภาษาการเขียนโปรแกรม Cไม่มีตัวเชื่อมโยง#includeคำสั่งเท่านั้น เช่นภาษา C-Lite จะไม่จำเป็นต้องคำหลักเช่นหรือextern staticคุณสมบัติเหล่านั้นมีอยู่เพื่อให้เป็นโมดูล

  3. POSIX ไม่ได้กำหนดวิธีในการกำหนดขอบเขตตัวแปรให้กับฟังก์ชั่นเชลล์สคริปต์เพียงไฟล์เดียว

    ได้อย่างมีประสิทธิภาพทำให้ตัวแปรทั้งหมดทั่วโลกอีกครั้งซึ่งเจ็บต้นแบบและ composability

    มีโซลูชั่นนี้ในเปลือกหอยโพสต์ POSIX - แน่นอนbash, ksh93และzshแต่ที่เพิ่งจะนำคุณกลับไปยังจุดที่ 1 ข้างต้น - อย่างน้อย

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

    แม้แต่ C ก็ยังดีกว่าในคะแนนนี้เป็นไมล์ ไม่เพียง แต่โปรแกรม C ส่วนใหญ่ที่เขียนด้วยตัวแปร function-local เป็นหลักเท่านั้น C ยังรองรับการกำหนดขอบเขตของบล็อกซึ่งอนุญาตให้บล็อกจำนวนมากภายในฟังก์ชันเดียวสามารถนำชื่อตัวแปรมาใช้ใหม่ได้โดยไม่ต้องมีการปนเปื้อนข้าม

  4. ภาษาการเขียนโปรแกรมเชลล์ไม่มีไลบรารีมาตรฐาน

    มีความเป็นไปได้ที่จะโต้แย้งว่าไลบรารีมาตรฐานของภาษาสคริปต์เชลล์คือเนื้อหาของPATHแต่ที่เพิ่งกล่าวว่าเพื่อให้ได้ผลลัพธ์ที่ตามมาเชลล์สคริปต์ต้องเรียกใช้โปรแกรมอื่นทั้งหมดอาจเป็นภาษาที่มีประสิทธิภาพมากกว่าเริ่มด้วย.

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

    แม้จะไม่สนใจความเป็นจริงที่ว่าส่วนใหญ่เชลล์สคริปต์พึ่งพาโปรแกรมภายนอกมักจะเขียนใน C จะได้รับอะไรที่เป็นประโยชน์ทำมีค่าใช้จ่ายของเหล่านั้นทั้งหมดpipe()→การfork()→การexec()โซ่โทร รูปแบบนั้นค่อนข้างมีประสิทธิภาพใน Unix เมื่อเทียบกับIPCและกระบวนการเปิดตัวในระบบปฏิบัติการอื่น ๆ แต่ที่นี่มันมีประสิทธิภาพแทนที่สิ่งที่คุณทำกับการเรียกรูทีนย่อยในภาษาสคริปต์อื่นซึ่งยังคงมีประสิทธิภาพมากกว่า สิ่งนี้ทำให้ขีด จำกัด สูงสุดของขีด จำกัด สูงสุดของความเร็วการประมวลผลสคริปต์เชลล์

  5. เชลล์สคริปต์มีความสามารถในตัวเล็กน้อยในการเพิ่มประสิทธิภาพผ่านการทำงานแบบขนาน

    เปลือกหอยบอร์นได้&, waitและท่อนี้ แต่ที่ส่วนใหญ่เท่านั้นที่มีประโยชน์สำหรับการเขียนโปรแกรมหลายโปรแกรมไม่ได้สำหรับการบรรลุ CPU หรือ I / O ขนาน คุณไม่น่าจะตรึงแกนหลักหรือทำให้อาร์เรย์ RAID อิ่มตัวด้วยการทำเชลล์สคริปต์ แต่เพียงอย่างเดียวและถ้าคุณทำเช่นนั้นคุณอาจจะได้รับประสิทธิภาพที่สูงขึ้นในภาษาอื่น ๆ

    ท่อโดยเฉพาะอย่างยิ่งเป็นวิธีที่อ่อนแอในการเพิ่มประสิทธิภาพผ่านการดำเนินการแบบขนาน มันอนุญาตให้โปรแกรมสองโปรแกรมทำงานแบบขนานและหนึ่งในสองโปรแกรมนั้นอาจถูกบล็อคบน I / O ไปยังหรือจากอีกโปรแกรมหนึ่งตามเวลาที่กำหนด

    มีวิธีหลังวันนี้เช่นxargs -PและGNUparallelแต่เพียง devolves ไปยังจุด 4 ข้างต้น

    ด้วยประสิทธิภาพที่ไม่สามารถใช้ประโยชน์จากระบบมัลติโปรเซสเซอร์ได้อย่างมีประสิทธิภาพเชลล์สคริปต์จะช้ากว่าโปรแกรมที่เขียนดีในภาษาที่สามารถใช้โปรเซสเซอร์ทั้งหมดในระบบได้เสมอ ในการรับconfigureตัวอย่างสคริปต์GNU Autoconf อีกครั้งการเพิ่มจำนวนแกนประมวลผลในระบบจะเพิ่มความเร็วในการทำงานเล็กน้อย

  6. เชลล์ภาษาสคริปต์ไม่ได้มีคำแนะนำหรือการอ้างอิง

    สิ่งนี้ทำให้คุณไม่สามารถทำสิ่งต่าง ๆ ได้อย่างง่ายดายในภาษาโปรแกรมอื่น

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

    หรือมันอาจจะเป็นกรณีที่คุณต้องการโครงสร้างข้อมูลที่ไม่ได้มีทางเลือกที่เพียงพอที่สร้างขึ้นในล่ามสคริปต์เปลือกของคุณเช่นการชี้นำวัฏจักรกราฟซึ่งคุณอาจต้องการเพื่อที่จะจำลองขึ้นกราฟ ฉันได้เขียนโปรแกรมมานานหลายทศวรรษและวิธีเดียวที่ฉันสามารถทำได้ในเชลล์สคริปต์คือการละเมิดระบบไฟล์โดยใช้ symlinks เป็นการอ้างอิงแบบ faux นั่นเป็นวิธีการแก้ปัญหาที่คุณได้รับเมื่อคุณพึ่งพาทัวริง - สมบูรณ์ซึ่งจะบอกอะไรคุณเกี่ยวกับว่าวิธีการแก้ปัญหาเป็นสง่ารวดเร็วหรือเข้าใจง่าย

    โครงสร้างข้อมูลขั้นสูงใช้เพียงหนึ่งเดียวสำหรับตัวชี้และการอ้างอิง มีแอปพลิเคชั่นอื่น ๆ อีกมากมายสำหรับพวกเขาซึ่งไม่สามารถทำได้อย่างง่ายดายในภาษาสคริปต์ตระกูล Bourne

ฉันสามารถไปต่อไปได้ แต่ฉันคิดว่าคุณได้รับจุดที่นี่ พูดง่าย ๆ ก็คือมีภาษาการเขียนโปรแกรมที่ทรงพลังกว่าสำหรับระบบ Unix

นี่เป็นข้อได้เปรียบที่ยิ่งใหญ่ที่สามารถชดเชยความธรรมดาของภาษาในบางกรณี

แน่นอนและนั่นคือเหตุผลที่ GNU Autoconf ใช้ชุดย่อยของตระกูลเชลล์สคริปต์ภาษาบอร์นสำหรับconfigureสคริปต์ออก: เพื่อให้configureสคริปต์ทำงานได้ทุกที่

คุณอาจจะไม่พบกลุ่มผู้เชื่อขนาดใหญ่ในยูทิลิตี้การเขียนในภาษา Bourne shell แบบพกพาสูงกว่านักพัฒนาของ GNU Autoconf แต่การสร้างของพวกเขาเองถูกเขียนขึ้นในภาษา Perl เป็นหลักรวมถึงบางส่วนm4เท่านั้น สคริปต์; เอาต์พุตของ Autoconf เท่านั้นคือเชลล์สคริปต์ Bourne แท้ หากนั่นไม่ได้ถามคำถามว่าแนวคิด "Bournewhere" มีประโยชน์เพียงใดฉันก็ไม่รู้ว่าจะทำอะไร

ดังนั้นจึงมีข้อ จำกัด ว่าโปรแกรมดังกล่าวจะซับซ้อนแค่ไหน?

เทคนิคการพูดไม่ใช่ตามที่การสังเกตของทัวริงครบถ้วน

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

เป็นไปได้ที่จะเขียน, พูด, ไฟล์คอมเพรสเซอร์ / decompressor ในทุบตีบริสุทธิ์?

ทุบตี "บริสุทธิ์" โดยไม่ต้องโทรออกไปหาสิ่งต่าง ๆ ในPATH? คอมเพรสเซอร์น่าจะเป็นไปได้โดยใช้echoและลำดับหลบหนี hex แต่มันจะค่อนข้างเจ็บปวดที่จะทำ ตัวขยายการบีบอัดอาจเป็นไปไม่ได้ที่จะเขียนด้วยวิธีนี้เนื่องจากไม่สามารถจัดการข้อมูลไบนารีในเชลล์ได้ คุณจะต้องโทรออกodและเช่นในการแปลข้อมูลไบนารีเป็นรูปแบบข้อความวิธีการจัดการข้อมูลของเชลล์

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

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

วิดีโอเกมง่ายๆ?

นี่คือTetris ในเปลือก เกมดังกล่าวมีให้บริการหากคุณไปดู

มีเครื่องมือการดีบักที่ จำกัด เท่านั้น

ฉันจะวางเครื่องมือสนับสนุนการดีบักลงประมาณ 20 ที่ในรายการคุณสมบัติที่จำเป็นในการสนับสนุนการเขียนโปรแกรมในขนาดใหญ่ โปรแกรมเมอร์จำนวนมากต้องพึ่งพาการprintf()ดีบักมากกว่า debuggers ที่เหมาะสมโดยไม่คำนึงถึงภาษา

ในเปลือกคุณมีechoและset -xซึ่งรวมกันเพียงพอที่จะแก้ปัญหาที่ดีมาก


2
"เชลล์สคริปต์มีความสามารถในตัวเล็กน้อยในการทำการประมวลผลแบบขนาน" ในความคิดของฉันเชลล์มีการรองรับการประมวลผลแบบขนานได้ดีกว่าภาษาอื่น ๆ ส่วนใหญ่ ด้วยอักขระตัวเดียว&คุณสามารถเรียกใช้กระบวนการแบบขนาน คุณสามารถwaitทำให้กระบวนการลูกสมบูรณ์ คุณสามารถตั้งค่าไพพ์ไลน์และเครือข่ายท่อที่ซับซ้อนมากขึ้นโดยใช้ไพพ์ที่มีชื่อ ที่สำคัญที่สุดคือมันง่ายที่จะทำการประมวลผลแบบขนานอย่างถูกวิธีโดยใช้รหัสสำเร็จรูปน้อยมากและหลีกเลี่ยงความเสี่ยงและความยากลำบากของการแชร์หน่วยความจำแบบมัลติเธรด
Sam Watkins

@ SamWatkins: ฉันได้อัปเดตจุดที่ 5 ด้านบนเพื่อตอบการตอบกลับของคุณ ในขณะที่ฉันเช่นกันฉันเป็นแฟนของการส่งข้อความระหว่างกระบวนการที่แยกกันเพื่อหลีกเลี่ยงปัญหามากมายที่เกิดขึ้นจากการใช้หน่วยความจำแบบขนาน - หน่วยความจำร่วมกันประเด็นที่ฉันทำที่นี่คือการเพิ่มประสิทธิภาพ มักจะต้องการความเท่าเทียมกันหน่วยความจำที่ใช้ร่วมกัน
Warren Young

เชลล์สคริปต์นั้นดีสำหรับการสร้างต้นแบบ แต่ในที่สุดโครงการควรย้ายไปใช้ภาษาการเขียนโปรแกรมที่เหมาะสมจากนั้นเป็นภาษาที่รวบรวม จากนั้นในกรณีที่รุนแรงประกอบเช่นคุณจะเห็นด้วยโครงการ FFmpeg Cmake เป็นตัวอย่างที่ดีของสิ่งที่ควรเกิดขึ้นกับ Autotools - มันเขียนด้วยภาษา C และไม่ต้องการ Perl หรือ Texinfo หรือ M4 มันช่างน่าอายจริงๆที่ Autotools ยังคงพึ่งพาเชลล์สคริปต์อย่างหนักหลังจาก 30 ปีwikipedia.org/wiki/GNU_Build_System#Criticism
Steven Penny

9

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

สำหรับสิ่งหนึ่งแม้ว่า bash นั้นจะเป็นทัวริง แต่ก็ไม่ดีในการจัดการกับข้อมูลอื่นที่ไม่ใช่จำนวนเต็ม (ไม่ใหญ่เกินไป), สตริง, อาร์เรย์ (หนึ่งมิติ) ของสตริงและแผนที่ จำกัด จากสตริงไปยังสตริง ข้อมูลชนิดอื่น ๆ ต้องการการเข้ารหัสที่น่ารำคาญซึ่งทำให้ยากในการเขียนโปรแกรมและมักจะกำหนดประสิทธิภาพที่ไม่ดีพอในทางปฏิบัติ ตัวอย่างเช่นการดำเนินการทศนิยมใน bash นั้นยากและช้า

นอกจากนี้การทุบตีมีวิธีการโต้ตอบกับสภาพแวดล้อมน้อยมาก มันสามารถเรียกใช้กระบวนการมันสามารถทำการเข้าถึงไฟล์อย่างง่าย (ผ่านการเปลี่ยนเส้นทาง) และที่เกี่ยวกับมัน Bash ยังมีไคลเอนต์เครือข่ายฝั่งไคลเอ็นต์ Bash สามารถปล่อย null null ได้ง่ายพอ ( printf \\0) แต่ไม่สามารถแจง null ได้ใน input ซึ่งทำให้ไม่เหมาะที่จะอ่านข้อมูลไบนารี Bash ไม่สามารถทำสิ่งอื่น ๆ ได้โดยตรง: ต้องเรียกโปรแกรมภายนอกสำหรับสิ่งนั้น และมันก็โอเค: เชลล์ออกแบบมาเพื่อวัตถุประสงค์หลักในการรันโปรแกรมภายนอก! เชลล์เป็นภาษากาวเพื่อรวมโปรแกรมเข้าด้วยกัน แต่ถ้าคุณกำลังเรียกใช้โปรแกรมภายนอกนั่นหมายความว่าโปรแกรมนั้นจะต้องพร้อมใช้งาน - และจากนั้นคุณจะลดความได้เปรียบในการพกพา: คุณต้องติดตั้งโปรแกรมบางตัวที่มีอยู่ทั่วไป (ส่วนใหญ่)

Bash ไม่มีคุณสมบัติใด ๆ ที่ทำให้การเขียนโปรแกรมที่มีประสิทธิภาพนอกเหนือจากset -eนั้นง่ายขึ้น ไม่มีประเภท (ประโยชน์) ประเภทเนมสเปซโมดูลหรือโครงสร้างข้อมูลที่ซ้อนกัน บั๊กเป็นปัญหาอันดับหนึ่งในการเขียนโปรแกรม ในขณะที่ความง่ายในการเขียนโปรแกรมที่ไม่มีบั๊กนั้นไม่ใช่ปัจจัยในการตัดสินใจในการเลือกภาษา ทุบตียังจัดอันดับประสิทธิภาพการทำงานที่ไม่ดีเมื่อทำสิ่งอื่นนอกเหนือจากการรวมโปรแกรมเข้าด้วยกัน

เป็นเวลานานทุบตีไม่ได้ทำงานบน Windows และแม้กระทั่งวันนี้มันไม่ได้อยู่ในการติดตั้ง Windows เริ่มต้นและมันไม่ได้ทำงานอย่างสมบูรณ์ (แม้กระทั่งใน WSL) ในแง่ที่ว่ามันไม่มีส่วนต่อประสานกับ คุณสมบัติดั้งเดิมของ Windows Bash ไม่ทำงานบน iOS และไม่ได้ติดตั้งบน Android ดังนั้นถ้าคุณไม่ได้เขียนแอปพลิเคชั่นสำหรับ Unix เท่านั้นการทุบตีจะไม่สามารถพกพาได้

การรวบรวมคอมไพเลอร์ไม่ใช่ปัญหาสำหรับการพกพา คอมไพเลอร์ทำงานบนเครื่องของนักพัฒนา การขอล่ามหรือห้องสมุดบุคคลที่สามอาจเป็นปัญหา แต่ภายใต้ Linux มันเป็นปัญหาที่แก้ไขได้ผ่านแพคเกจการกระจายและภายใต้ Windows, Android และ iOS ผู้คนมักจะรวมส่วนประกอบของบุคคลที่สามไว้ในแพ็คเกจแอปพลิเคชันของตน ดังนั้นความกังวลเรื่องความสะดวกในการพกพาที่คุณมีอยู่ในใจจึงไม่ใช่ข้อกังวลในทางปฏิบัติสำหรับแอปพลิเคชั่นที่หมดเวลาทำงาน

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


1
ฉันเชื่อว่าตำนานของการพกพาได้รับการพูดถึงค่อนข้างบ่อยไม่แน่ใจว่าฉันจะใช้รายการนั้นเป็นลบเพราะมันใช้กับภาษาอื่นส่วนใหญ่เช่นกันรวมถึง Java แม้แต่ PHP ที่ทำงานบนเซิร์ฟเวอร์ windows และเซิร์ฟเวอร์ * nix มีความแตกต่างเล็ก ๆ น้อย ๆ ซึ่งคุณต้องระวังอยู่เสมอหากคุณโง่พอที่จะทำงานอะไรบนเซิร์ฟเวอร์ windows นั่นก็คือ มีหลายสิ่งที่ไม่ทำงานบน android หรือ iOs ดังนั้นจึงไม่แน่ใจว่าจะเป็นความคิดเห็นที่ถูกต้องได้เช่นกัน
Lizardx

7

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

  • ฟังก์ชั่นส่วนใหญ่จะทำโดยการปิดคำสั่งภายนอกซึ่งช้า ในทางตรงกันข้ามภาษาการเขียนโปรแกรมเช่น Perl สามารถทำเทียบเท่าmkdirหรือgrepภายใน
  • ไม่มีวิธีง่ายๆในการเข้าถึงไลบรารี C หรือโทรออกจากระบบโดยตรงซึ่งหมายความว่าเช่นวิดีโอเกมจะสร้างยาก
  • ภาษาโปรแกรมที่เหมาะสมมีการสนับสนุนที่ดีกว่าสำหรับโครงสร้างข้อมูลที่ซับซ้อน แม้ว่า Bash จะมีอาร์เรย์และอาร์เรย์ที่เชื่อมโยงกัน แต่ฉันไม่ต้องการคิดรายการที่เชื่อมโยงหรือทรี
  • เชลล์ทำเพื่อประมวลผลคำสั่งที่สร้างขึ้นหากข้อความ ข้อมูลไบนารี (นั่นคือตัวแปรที่มี NUL ไบต์ (ไบต์ที่มีค่าเป็นศูนย์)) ยากที่จะจัดการไม่ได้ ขึ้นอยู่กับเปลือกหอยzshมีการสนับสนุน นี่เป็นเพราะอินเทอร์เฟซสำหรับโปรแกรมภายนอกส่วนใหญ่เป็นข้อความและ\0ใช้เป็นตัวคั่น
  • นอกจากนี้เนื่องจากคำสั่งภายนอกการแยกระหว่างรหัสและข้อมูลจึงยากเล็กน้อย เป็นสักขีพยานในทุกปัญหาที่เกิดขึ้นเมื่ออ้างถึงข้อมูลไปยังเชลล์อื่น (เช่นเมื่อทำงานbash -c ...หรือssh -c ...)

นี่เป็นชุดฟิล์มเนกาทีฟที่แม่นยำที่สุดสำหรับฉันในฐานะคนที่ทำสคริปต์ทุบตีจำนวนมากสิ่งเหล่านี้จะเป็นสิ่งที่ฉันจะระบุว่าเป็นรายการเชิงลบเช่นกัน อย่างไรก็ตามสิ่งหนึ่งที่ฉันพบคือ Bash นั้นไม่ได้ช้ากว่าภาษาที่คอมไพล์อื่น ๆ เมื่อเปรียบเทียบการทำงานที่คล้ายกัน ฉันสงสัยว่าจะพยายามเขียนสิ่งที่ซับซ้อนกว่าที่ฉันมีในการทุบตีงูหลามความแตกต่างของความเร็วจะไม่ทำให้งานอันยิ่งใหญ่ที่เกี่ยวข้องกับมันคุ้มค่า อย่างไรก็ตาม Bash เพียงอย่างเดียวที่ฉันพบมี จำกัด เกินไป แต่ Bash + gawk ทำงานได้ดี gawk เกือบจะเป็นจริง
Lizardx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.