ความแตกต่างระหว่าง bash และ sh คืออะไร?


28

ฉันเห็นโค้ดที่ใช้สองประเภท:

#!/usr/bin/sh

และ:

#!/user/bin/bash

ฉันค้นหาออนไลน์นี้และความคิดเห็นต่างกันมาก คำอธิบายที่ฉันเห็นในเว็บไซต์ส่วนใหญ่บอกว่าshเก่ากว่าbashและไม่มีความแตกต่างที่แท้จริง

มีคนรู้ถึงความแตกต่างระหว่างสิ่งเหล่านี้หรือไม่? คุณสามารถให้ตัวอย่างที่ใช้ได้จริงกับฉันเมื่อใช้อีกอันหนึ่งได้หรือไม่?


สำหรับภาพรวมทั่วไปของกระสุนที่แตกต่างกัน (ไม่ใช่แค่shและbash): http://en.wikipedia.org/wiki/Comparison_of_command_shells
akira

1
อีกหนึ่งประวัติศาสตร์ที่ยอดเยี่ยมที่นี่: faqs.org/faqs/unix-faq/shell/shell-differences
John Wright

คำตอบ:


34

bashเป็น superset ของshie ทุกสิ่งที่คุณสามารถทำได้ในคุณสามารถทำได้ในshbash

Bash มีคุณสมบัติมากขึ้น (การแยกย่อย, บิวด์อิน, อาร์เรย์) ทำให้สคริปต์เขียนง่ายขึ้น บางคนในภายหลัง * ระวังมี/bin/shการเชื่อมโยงไปยัง/bin/bash

สำหรับคำอธิบายแบบเต็มของสิ่งที่นี่คือการสอน


5
@Saif Bechan: เหตุผลหนึ่งที่ทำให้ Bourne shell ( sh) ไม่ได้ขยายออกไปคือ Bash` เขียนโดยคนอื่น นอกจากนี้ฉันเดิมพันว่ามีปัญหาเรื่องใบอนุญาต อ่านบทความเกี่ยวกับ Bourne Shell en.wikipedia.org/wiki/Bourne_shell
Felix

7
การลบshจะทำให้สคริปต์จำนวนมากซึ่งคาดว่าจะอยู่ที่นั่นและพึ่งพาวิธีแยกวิเคราะห์สิ่งต่างๆ ผู้ใช้ Linux อาจไม่สนใจ แต่คนที่ใช้จ่าย $ พันกับ Solaris, AIX หรือ HP-UX อาจรำคาญมาก
njd

3
... และเพื่อความสนุกสนานยิ่งขึ้น Ubuntu symlinks / bin / sh to dash ขีดกลางไม่ได้สมบูรณ์ตามมาตรฐาน sh หรือ bash แต่ควรเริ่มต้นได้เร็วขึ้น เมื่อระบบบู๊ตสคริปต์ init.d ทั้งหมดจะทำงานและฉันคิดว่าเวลาที่บันทึกโดยรวมนั้นคุ้มค่า
kbyrd

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

8
@Saif: มีอีกเหตุผลหนึ่งที่ทำไมshไม่ขยายออกไปอีก: ซอร์สโค้ดของมันคือนรกที่บริสุทธิ์ ลองดูสิ. มันควรจะเป็น C ...
grawity

6

ตามเนื้อผ้า / bin / sh จะเป็นเชลล์เป้าหมายเดิมซึ่งไม่มีประวัติหรือการแก้ไขบรรทัดคำสั่งและไม่มีการควบคุมงาน

เป็นเวลาประมาณ 15 ปีที่ผ่านมา Unixes ส่วนใหญ่มีการติดตั้งเชลล์ POSIX หรืออย่างน้อย ksh หรือ bash (ซึ่งเกือบจะเหมือน POSIX มาก) แต่ยังคงมีเชลล์ที่ จำกัด มากใน / bin / sh

เหตุผลที่ทำให้เชลล์สคริปต์เก่าซึ่งคาดว่าshคำสั่งเก่าจะยังคงทำงานได้
ตั้งแต่ตัวละครที่ชอบ{, }และ!มีความหมายพิเศษเพื่อทุบตีก็เป็นไปได้ว่าเชลล์สคริปต์เก่าโดยใช้ตัวอักษรเหล่านั้น (โดยไม่ต้องหลบหนีพวกเขา) อาจล้มเหลว
(เชลล์เป้าหมายจะใช้!!{1,2}ตัวอักษรในขณะที่ทุบตีจะตีความว่าเป็นการทำซ้ำของคำสั่งก่อนหน้า (!! ) ตามด้วยการขยายรั้ง)

บนลีนุกซ์, shคำสั่งนั้นเกือบจะเป็นแค่ลิงค์ไปbash, พร้อมกับฟีเจอร์เดียวกันทั้งหมด.


2
ควรใช้ Bash (แต่ไม่เสมอไป) ในโหมดความเข้ากันได้ของ sh หากเรียกใช้เป็น / bin / sh สิ่งต่างๆมากมายเกิดขึ้นเมื่อ Ubuntu เปลี่ยน / bin / sh จากการเชื่อมโยงไปยัง / bin / bash เป็นการเชื่อมโยงไปยัง / bin / dash สิ่งที่แตกหักสันนิษฐานว่าพวกเขาควรจะใช้ bashisms มาตรฐาน sh
Broam

4

sh สามารถหมายถึงเชลล์เป้าหมายหรือ / bin / sh ซึ่งเป็นเชลล์ (สอดคล้องกับ POSIX) อื่น ๆ บนแพลตฟอร์มที่ทันสมัยที่สุด "POSIX shell" เป็นเชลล์นามธรรมที่กำหนดโดย POSIXซึ่งนำมาใช้โดยการทุบตีในโหมด POSIX หรือ ksh หรือเส้นประโดยค่าเริ่มต้น / bin / sh บางครั้งเรียกว่า POSIX เชลล์เนื่องจากเป็นเชลล์ที่สอดคล้องกับ POSIX บนแพลตฟอร์มส่วนใหญ่ เชลล์เป้าหมายเดิมไม่ใช่ POSIX เชลล์

bashref มีรายชื่อของความแตกต่างระหว่างการทุบตีและเปลือกหอยบอร์น man bashมีรายชื่อของการเปลี่ยนแปลงเมื่อทุบตีถูกเรียกในโหมด POSIX

/ bin / sh ไม่ใช่ symlink หรือฮาร์ดลิงก์ใน OS X แต่มันมีขนาดใกล้เคียงกับ / bin / bash:

$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x  1 root  wheel  1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x  1 root  wheel  1334000 Jul 26 01:52 /bin/sh

ทุบตีคน :

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

การลอกเลียนแบบของบอร์นเชลล์นั้นค่อนข้าง จำกัด bash +B(Bourne) จริง ๆ แล้วจะปิดการใช้งานคุณสมบัติเช่นการขยายรั้ง

$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}

แต่แม้ว่าคุณจะปิดใช้งานโหมด POSIX แต่เสียงก้องนั้นจะมีลักษณะecho -eดังนี้:

$ sh
$ shopt -uo posix
$ echo '1\b2'
2

/ bin / sh เป็นเส้นประบนUbuntuดังนั้นbashismsบางอย่างทำงานกับ / bin / sh บน OS X แต่ไม่ใช่ Ubuntu

หากคุณต้องการเขียนสคริปต์สำหรับบอร์นเชลล์ต้นฉบับ (เหมือน) คุณสามารถใช้#!/usr/bin/env bash +Bแทนได้

ฉันคิดว่าการเขียนสคริปต์สำหรับ bash ง่ายกว่าการหลีกเลี่ยงฟีเจอร์ที่ไม่ได้เป็นส่วนหนึ่งของข้อกำหนด POSIX หรือ Bourne shell หรือทดสอบทุกอย่างด้วย shell อื่น


2

ที่จริงแล้วแม้ว่า / bin / sh อาจเป็นลิงค์ไปยัง / bin / bash หากเริ่มต้นขึ้นเนื่องจาก sh มันจะทำงานแตกต่างกัน จาก manpage ทุบตี:

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

ดังนั้นจึงshพยายามเลียนแบบพฤติกรรมเชิงประวัติศาสตร์ เนื่องจากbashมันพยายามที่จะมีประโยชน์มากที่สุดเท่าที่เป็นไปได้เป็นเชลล์ล็อกอินแบบโต้ตอบ


2

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


2
นอกจากนี้ยังอาจมีประโยชน์ในกรณีฉุกเฉินหากคุณทำสิ่งที่ไม่ดีldconfigหรือ/libไดเรกทอรีของคุณถูกลบออกด้วยเหตุผลบางอย่าง
LawrenceC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.