อ่าน 42 นาที
แบช (เชลล์ยูนิกซ์)
Bash (ชื่อย่อของ " Bourne Again SHell ") เป็น ตัวแปลคำสั่ง แบบโต้ตอบ และ ภาษาคำสั่ง ที่พัฒนาขึ้นสำหรับ ระบบปฏิบัติการ ที่คล้าย Unix สร้างขึ้นในปี 1989 โดย Brian Fox สำหรับ โครงการ...
แบช (เชลล์ยูนิกซ์)
| ทุบตี | |
|---|---|
| ผู้เขียนต้นฉบับ | ไบรอัน ฟ็อกซ์ |
| นักพัฒนา | เชต ราเมย์ |
| ปล่อย | 8 มิถุนายน 2532 |
| เวอร์ชันเสถียร | 5.3 [ 1 ] |
| เขียนเป็น | ซี |
| ระบบปฏิบัติการ | |
| แพลตฟอร์ม | จีเอ็นยู |
| มีจำหน่ายใน | รองรับหลายภาษา ( gettext ) |
| พิมพ์ | เชลล์ (คอมพิวเตอร์) , เชลล์ยูนิก , ภาษาคำสั่ง |
| ใบอนุญาต |
|
| เว็บไซต์ | www.gnu.org/software/bash/ |
| ที่เก็บข้อมูล |
|
Bash (ชื่อย่อของ " Bourne Again SHell ") เป็นตัวแปลคำสั่ง แบบโต้ตอบ และภาษาคำสั่งที่พัฒนาขึ้นสำหรับระบบปฏิบัติการที่คล้ายUnixสร้างขึ้นในปี 1989 โดย Brian Fox สำหรับโครงการ GNU [ 7 ]โดยได้รับการออกแบบให้เป็นซอฟต์แวร์ทางเลือกฟรี อย่างสมบูรณ์ สำหรับBourne shellและUnix shellที่เป็นกรรมสิทธิ์อื่นๆ[ 8 ]ซึ่งได้รับการสนับสนุนโดยFree Software Foundation [ 7 ] เนื่องจากได้รับการยอมรับอย่างกว้างขวาง Bash จึงมักใช้เป็น เชลล์ ล็อกอิน เริ่มต้นสำหรับ Linuxหลายเวอร์ชัน[ 9 ]นอกจากนี้ยังรองรับการเรียกใช้คำสั่งจากไฟล์ที่เรียกว่าสคริปต์เชลล์ ซึ่ง ช่วยอำนวย ความสะดวกในการ ทำงาน อัตโนมัติsh
ไวยากรณ์คำสั่งของ Bash เป็นส่วนขยายของ ไวยากรณ์ของ Bourne shellซึ่งคุณสมบัติพื้นฐานทั้งหมดของไวยากรณ์ Bash ถูกคัดลอกมาจาก Bourne shell ดังนั้น Bash จึงสามารถเรียกใช้สคริปต์ของ Bourne shell ส่วนใหญ่ได้โดยไม่ต้องแก้ไข นอกจากนี้ยังมีการนำแนวคิดบางอย่างมาจากC shell , tcshซึ่งเป็นรุ่นต่อจาก C shell และKorn Shell Bash สามารถใช้งานได้บนระบบปฏิบัติการสมัยใหม่เกือบทั้งหมด ทำให้เป็นเครื่องมืออเนกประสงค์ในสภาพแวดล้อมการประมวลผลต่างๆ
คำจำกัดความ
ASCII, สตริง และตัวเลข
ภาษาที่ป้อนเข้าสู่เชลล์จะต้องได้รับการตรวจสอบในระดับอักขระก่อน
— "POSIX 1003.1-2024, 2.10.1 ข้อกำหนดทางศัพท์ของไวยากรณ์เชลล์"ข้อกำหนด พื้นฐาน ของThe Open Group ฉบับที่ 8, IEEE Std 1003.1-2024 The Open Group สืบค้นเมื่อ25 สิงหาคม 2025
$ printf '<ขึ้นบรรทัดใหม่>: <%b>\n' $'\n' <ขึ้นบรรทัดใหม่>: < > $ printf '<แท็บ>: <%b>\n' $'\t' <แท็บ>: < > $ printf '<เว้นวรรค>: <%s>\n' " " <เว้นวรรค>: < > $ printf '<อักขระว่าง>: <%b>\n' $'\0' < อักขระว่าง>: <>ชุดของอักขระใดๆ เรียกว่า "สตริง" หรือบางครั้งเรียกว่า " สตริงลิเทอรัล " ในระบบปฏิบัติการแบบ Unix อักขระทั้งหมด ทั้งที่พิมพ์ได้และพิมพ์ไม่ได้ ยกเว้นอักขระบางตัว เช่นอักขระว่างและเครื่องหมายทับ/สามารถใช้ในชื่อไฟล์ได้ นอกจากนี้ สตริงทั้งหมดจะคำนึงถึงตัวพิมพ์ใหญ่และตัวพิมพ์ เล็ก [ 10 ]
Bash เช่นเดียวกับภาษาโปรแกรมอื่นๆ อีกหลายภาษา ใช้ระบบการนับเลขแบบเริ่มต้นที่ศูนย์
การกดปุ่ม Ctrl ร่วมกับปุ่มอื่นๆ
ฟังก์ชันการกดปุ่ม Control+key นั้นมีให้ใช้งานในGNU Readlineและใช้งานได้เฉพาะในโหมดโต้ตอบเท่านั้น การกดปุ่มบางชุดจะช่วยให้ผู้ใช้สามารถใช้งาน Bash เพื่อใช้การเติมคำสั่งอัตโนมัติด้วยปุ่ม Tab และค้นหาประวัติคำสั่งได้
- Tab ↹– เปิดใช้งานการเติมแท็บอัตโนมัติ
- ↑– เลื่อนขึ้น (เช่น เลื่อนไปข้างหลัง) ในประวัติคำสั่ง
- ↓– เลื่อนลง (เช่น เลื่อนไปข้างหน้า) ในประวัติคำสั่ง
- Ctrl+ r– ค้นหาประวัติคำสั่ง
การรวมปุ่มกดบางชุดยังช่วยให้ผู้ใช้สามารถใช้งานโปรแกรมจำลองเทอร์มินัลเพื่อย้ายเคอร์เซอร์ภายในหน้าต่างเทอร์มินัลและควบคุมโปรแกรมจำลองได้ โดยค่าเริ่มต้น การรวมปุ่มกดเหล่านี้ใน Bash จะเหมือนกับของEmacs [ 11 ]
ปุ่มลัดเริ่มต้นสำหรับรหัสควบคุมมีดังนี้:
- Ctrl+ f– เลื่อนเคอร์เซอร์ไปทางขวาหนึ่งตัวอักษร
- Ctrl+ b– เลื่อนเคอร์เซอร์ไปทางซ้ายหนึ่งตัวอักษร
- Alt+ f– เลื่อนเคอร์เซอร์ไปทางขวาหนึ่งคำ
- Alt+ b– เลื่อนเคอร์เซอร์ไปทางซ้ายหนึ่งคำ
- Ctrl+ a– ย้ายเคอร์เซอร์ไปที่จุดเริ่มต้นของบรรทัดคำสั่งปัจจุบัน
- Ctrl+ c– ยกเลิกคำสั่งปัจจุบันและแสดงข้อความแจ้งเตือนใหม่
- Ctrl+ d– ปิดอินสแตนซ์ Bash ปัจจุบัน ซึ่งอาจปิดโปรแกรมจำลองเทอร์มินัลด้วย
- Ctrl+ e– เลื่อนเคอร์เซอร์ไปที่ท้ายบรรทัดคำสั่งปัจจุบัน
- Ctrl+ q– ปลุกเครื่องเทอร์มินัล จากนั้นจึงประมวลผลการกดปุ่มที่บันทึกไว้
- Ctrl+ s– ตั้งค่าเทอร์มินัลให้เข้าสู่โหมดพักเครื่อง
- Ctrl+ w– ลบคำหนึ่งคำทางด้านซ้ายของเคอร์เซอร์
- Ctrl+ z– หยุดกระบวนการที่ทำงานอยู่เบื้องหน้า
การกำหนดคีย์ลัด ของ Viก็มีให้ใช้งานเช่นกัน และสามารถเปิดใช้งานได้โดยการเรียกใช้[ 12 ] [ 13 ]set-ovi
ไวยากรณ์
เมื่อ Bash อ่านบรรทัดคำสั่งทั้งหมดสตริงทั้งหมดจะถูกแบ่งออกเป็นโทเค็น "โทเค็น" จะถูกระบุโดยใช้ และคั่นออกจากกันโดยใช้เมตาแคแรคเตอร์
ใน Bash เวอร์ชัน 5.3 อักขระพิเศษ 10 ตัว ได้แก่ ช่องว่าง แท็บ และขึ้นบรรทัดใหม่ รวมถึงอักขระต่อไปนี้:|&;()<>
"ช่องว่าง"ประกอบด้วยอักขระพิเศษที่ไม่มีเครื่องหมายคำพูดทั้งหมด"ตัวดำเนินการ"แต่ละตัวมีอักขระพิเศษที่ไม่มีเครื่องหมายคำพูดอย่างน้อยหนึ่งตัว และ"คำ"จะต้องไม่มีอักขระพิเศษที่ไม่มีเครื่องหมายคำพูดเลย
ในทางปฏิบัติ Bash จะแยกสตริงคำสั่งทั้งหมด ออก เป็นโทเค็นหรือกลุ่มของโทเค็นที่มีอักขระพิเศษ และโทเค็นหรือกลุ่มของโทเค็นที่ไม่มีอักขระพิเศษใดๆ ซึ่งเรียกว่า"คำ"จากนั้นก็จะแยกคำเหล่านั้นออกเป็นส่วนย่อยๆ ที่มีความหมายมากขึ้น เช่น ชื่อคำสั่ง คำสั่งกำหนดค่าตัวแปร เป็นต้น
ช่องว่างสองช่องนั้นคือช่องว่างธรรมดาและแท็บ
ผู้ปฏิบัติงาน
ตัวดำเนินการควบคุมทำหน้าที่ควบคุมโดยอาจเป็นอักขระขึ้นบรรทัดใหม่ หรืออักขระต่อไปนี้: ||, &&, &, ;, ;;, ;&, ;;&, |, |&, (, หรือ).
ตัวดำเนินการเปลี่ยนเส้นทางจะเปลี่ยนเส้นทางสตรีมอินพุตหรือเอาต์พุต ซึ่งได้แก่<, >, &>, <<, และ<<<.
คำ
คำ คือลำดับของอักขระ ( ที่ไม่ใช่เมตา) ที่เชลล์ถือว่าเป็นหน่วยเดียวคำสงวน คือ คำประเภทหนึ่งที่มีความหมายพิเศษสำหรับเชลล์[ 14 ] ชื่อคือคำประเภทหนึ่งที่แยกจากคำสงวนชื่อ( A) ประกอบด้วยตัว อักษรเครื่องหมายขีดล่าง และตัวเลขเท่านั้น (B) ขึ้นต้นด้วยตัวอักษรหรือเครื่องหมายขีดล่าง และ (C) ห้ามขึ้นต้นด้วยตัวเลข ชื่อเรียกอีกอย่างว่าตัว ระบุ สามารถใช้ตั้งชื่อตัวแปรและฟังก์ชันได้
คำสงวนจำนวน 16 คำจากทั้งหมด 22 คำซึ่งอาจเป็นอักขระหรือคำ มีดังต่อไปนี้:
'!' '[[' '{' ']]' '}' case in esac for do done if then elif else fi ... ชื่ออาจประกอบด้วยอักขระABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_. เท่านั้น
ในตัวอย่างสตริงคำสั่งแบบเต็มต่อไปนี้อักขระพิเศษ,จะมีเครื่องหมายจุลภาคอยู่ด้านบนคำสงวนจะมีเครื่องหมายแคเร็ตอยู่ด้านล่าง^และโทเค็น อื่นๆ จะมีเครื่องหมายแบ็กติ๊กอยู่ด้านล่างเช่น`กัน
$ #, , , ,, , ,, , $ if echo foo ; then bar = abc ; fi $ # ^^ ```` ``` ^^^^ ``````` ^^ซับเชลล์
"ซับเชลล์" คืออินสแตนซ์เพิ่มเติมของเชลล์ที่ถูกเริ่มต้นโดยอินสแตนซ์ปัจจุบันของเชลล์ เมื่อเชลล์ "แม่" สร้างซับเชลล์หรือเชลล์ "ลูก" ข้อมูลสภาพแวดล้อมของเชลล์แม่จะถูกสร้างขึ้นใหม่และกลายเป็นสภาพแวดล้อมของซับเชลล์
ใน Bash ในบริบทที่ไม่เกี่ยวข้องกับการคำนวณทางคณิตศาสตร์ เราสามารถบังคับให้ใช้ซับเชลล์ได้โดยการใส่คำสั่งทั้งหมดไว้ในวงเล็บ เดี่ยว
$ echo foo ; ( echo foo ) foo foo $ในกรณีง่ายๆ นี้ คำสั่งสองคำสั่งข้างต้นนั้นเทียบเท่ากัน อย่างไรก็ตาม การใช้ซับเชลล์อาจมีผลข้างเคียงที่ไม่คาดคิดได้ มีไวยากรณ์หลายรูปแบบที่สามารถทำให้เกิดการเริ่มต้นใช้งานซับเชลล์ได้ รายการตัวดำเนินการที่ไม่ครบถ้วนสมบูรณ์ที่ทำให้เกิดการเริ่มต้นใช้งานซับเชลล์มีดังต่อไปนี้:
- ไวยากรณ์ของซับเชลล์
()เช่น จะใช้ในการเริ่มต้นซับเชลล์:$ ( program arga argb )
- ไวยากรณ์การส่งข้อมูลผ่านท่อ (piping syntax)
A | Bจะเริ่มต้นใช้งานซับเชลล์หลายตัว โดยแต่ละตัวจะทำหน้าที่แทนคำสั่งแต่ละคำสั่งในไปป์ไลน์:$ program1 abc def | program2 -abc
การขยายตัว
โครงสร้างข้อมูล
Bash มีตัวแปรและอาร์เรย์เป็นโครงสร้างข้อมูล และถึงแม้จะมี ตัวแปรและอาร์เรย์หลายประเภทให้เลือกใช้ แต่โครงสร้างข้อมูลเหล่านี้ก็ค่อนข้างเรียบง่ายเมื่อเทียบกับภาษาอื่นๆ เช่นCหรือJava [ 15 ] ข้อมูลทั้งหมดจะถูกเก็บไว้ในหน่วยความจำในรูปแบบสตริง
การขึ้นต้นคำด้วยเครื่องหมายดอลลาร์ ($) หมายความว่าคำนั้นเป็นชื่อของตัวแปรหรืออาร์เรย์ แนะนำให้ใส่เครื่องหมายอัญประกาศคู่คร่อมชื่อตัวแปรหรือเครื่องหมายดอลลาร์เสมอ เพื่อป้องกันค่าของพารามิเตอร์จากผลกระทบที่ไม่พึงประสงค์
แนะนำ ให้ใส่เครื่องหมายวงเล็บปีกกาครอบชื่อตัวแปร{}เพื่อความอ่านง่ายและความสม่ำเสมอระหว่างตัวแปรและอาร์เรย์ เมื่อเขียนตัวแปร วงเล็บปีกกาเป็นตัวเลือก และวงเล็บเหลี่ยมจะเป็นข้อผิดพลาดทางไวยากรณ์ ชื่อพารามิเตอร์จะอยู่ทางด้านซ้ายของเครื่องหมายเท่ากับเสมอ และค่าจะอยู่ทางด้านขวาเสมอ
ตัวแปร
กำหนดค่าให้กับตัวแปรโดยใช้ไวยากรณ์name=value.
ในการใช้ตัวแปร$nameจะใช้ไวยากรณ์ หรือ${name}ซึ่งจะขยายเป็นค่าที่กำหนดให้กับตัวแปรนั้น
ต้องใช้ไวยากรณ์แบบหลังสำหรับชื่อบางชื่อเพื่อป้องกันผลข้างเคียงที่ไม่พึงประสงค์ ตัวอย่างเช่น$10จะถูกแยกวิเคราะห์เป็น${1}0ดังนั้นการใช้${10}จะทำให้ถูกแยกวิเคราะห์ตามที่ต้องการ
พารามิเตอร์ตามตำแหน่ง ซึ่งโดยปกติจะส่งผ่านไปยังสคริปต์ bash จะถูกระบุด้วยตัวแปรที่มีหมายเลขเริ่มต้นจาก $0 พารามิเตอร์พิเศษจะถูกระบุด้วยอักขระเครื่องหมายวรรคตอน[ 15 ]ตัวอย่างเช่น$@จะขยายเป็นรายการของพารามิเตอร์ตามตำแหน่งตัวแรกถึงตัวสุดท้าย "ที่อ้างอิงใหม่ทีละตัว คั่นด้วยช่องว่าง"
ตัวแปรสภาพแวดล้อมจะแสดงด้วยตัวอักษรพิมพ์ใหญ่ทั้งหมด ตัวแปรสภาพแวดล้อมประกอบด้วยตัวแปร UNIX เช่นLESS_SIGUSR1และตัวแปร Bourne shell เช่น[ 15HOME ] ตัวแปรสคริปต์จะแสดงด้วยตัวอักษรพิมพ์เล็กทั้งหมดหรือ CamelCase นี่เป็นเพียงธรรมเนียมปฏิบัติเท่านั้น ตัวแปรใดๆ ก็สามารถส่งผ่านไปยังคำสั่งเพื่อสร้างเป็นตัวแปรสภาพแวดล้อม ได้export
อาร์เรย์
อาร์เรย์เป็นโครงสร้างข้อมูลที่เก็บค่าได้หลายค่า[ 16 ] อาร์เรย์มีวงเล็บเหลี่ยมชุดหนึ่งวางไว้ที่ท้ายชื่อตัวแปรและอยู่ภายในวงเล็บปีกกา เมื่อเขียนอาร์เรย์ จำเป็นต้องใช้วงเล็บปีกกาและวงเล็บเหลี่ยม
อาร์เรย์จะถูกกำหนดค่าโดยใช้ไวยากรณ์ และname=( one or more elements )จะถูกขยายโดยใช้หรือหรือขึ้นอยู่กับกรณีการใช้งาน ${quux[@]}${quux[*]}${quux[1]}
พารามิเตอร์แต่ละประเภทจะถูกจำแนกด้วยข้อกำหนดการตั้งชื่อเฉพาะ [ 15 ]
ตั้งแต่ Bash 4.0 [ 17 ] Bash ยังรองรับอาร์เรย์แบบเชื่อมโยง อีก ด้วย
ในบทความนี้ ตัวอย่างของตัวแปรจากส่วนนี้ ได้แก่${foo}, PID, PWD, EUID, $$ , ${quux}และ${zork }
การประหารชีวิต
"การเรียกใช้งาน" โปรแกรมเกิดขึ้นเมื่อผู้ใช้ (หรือโปรแกรมอื่น) ร้องขอให้ระบบปฏิบัติการดำเนินการตามคำสั่งที่อยู่ในโปรแกรมนั้น
โดยค่าเริ่มต้น Bash จะอ่านโค้ดของผู้ใช้ทีละบรรทัด ตีความอักขระขึ้นบรรทัดใหม่หรือเครื่องหมายเซมิโคลอน;ว่าเป็นจุดสิ้นสุดของคำสั่งปัจจุบัน และดำเนินการคำสั่งตามลำดับ หากคำสั่งแบบโต้ตอบยาวเกินความกว้างของโปรแกรมจำลองเทอร์มินัล โดยปกติแล้วจะสามารถพิมพ์ต่อไปได้ และคำสั่งจะขึ้นบรรทัดใหม่โดยอัตโนมัติ หากต้องการขยายคำสั่งเกินบรรทัดใหม่ไปยังบรรทัดถัดไป จำเป็นต้องให้ตัวอักขระสุดท้ายของบรรทัดแรกเป็นเครื่องหมายแบ็กสแลช (\) ที่ไม่ถูกหลีกเลี่ยง\ซึ่งเป็นสัญญาณ "การต่อบรรทัด" Bash จะทำการวิเคราะห์และดำเนินการคำสั่งบรรทัดหนึ่งให้เสร็จสิ้นก่อนที่จะไปยังบรรทัดถัดไปและเริ่มการวิเคราะห์คำสั่งบรรทัดถัดไปเสมอ
$ foo = aa บาร์= bb quux =ซีซีzork = dd ; ตั้ง -o xtrace $ : " ${ foo } " ; : " ${ บาร์} " + : aa + : bb $ : " ${ quux } " \ > : " ${ zork } " + : cc : dd $คำแรกของบรรทัดคำสั่งเรียกว่า "ตำแหน่งคำสั่ง" ตามธรรมเนียมของ UNIX คำแรกของบรรทัดคำสั่งมักจะเป็นคำสั่งเสมอ และคำที่เหลือในสตริงบรรทัดคำสั่งจะเป็นตัวเลือกสำหรับคำสั่ง อาร์กิวเมนต์สำหรับตัวเลือก หรืออินพุตบางประเภทที่คำสั่งจะดำเนินการ "ตัวเลือก" ยังเรียกว่า "แฟล็ก" "สวิตช์" หรือเรียกอย่างเป็นทางการว่า "ตัวดำเนินการ" เมื่อ Bash พยายามค้นหาคำสั่งเพื่อดำเนินการ ไดเร็กทอรีที่มันค้นหาคือไดเร็กทอรีที่ระบุไว้ใน$PATHตัวแปรและไดเร็กทอรีการทำงานปัจจุบัน[ 18 ]
$ # [ตำแหน่งคำสั่ง] [ตัวเลือก] [อาร์กิวเมนต์] $ # ,--^ ,------------^ ,----^ $ declare -p USER BASH_VERSION declare -x USER="liveuser" declare -- BASH_VERSION="5.2.37(1)-release" $ผู้ใช้และ PS1
สามารถสร้างบัญชีผู้ใช้ได้ทั้งสำหรับผู้ใช้ที่เป็นมนุษย์หรือผู้ใช้ที่เป็นโปรแกรม ในระบบปฏิบัติการแบบ Unix จะมีผู้ใช้สองประเภท ได้แก่ ผู้ใช้ "ระดับสูง" และผู้ใช้ "ทั่วไป" ผู้ใช้ระดับสูง เช่น root หรือเคอร์เนลของระบบปฏิบัติการ สามารถทำอะไรก็ได้บนเครื่องนั้น ส่วนผู้ใช้ทั่วไปจะมีข้อจำกัดหลายอย่าง
เมื่อเซสชันเชลล์แบบโต้ตอบรอรับข้อมูลจากผู้ใช้ โดยค่าเริ่มต้นจะแสดงสตริงอักขระเฉพาะบนหน้าจอ ใน Bash ค่าของสตริงที่รอรับข้อมูลนี้จะถูกเก็บไว้ในตัวแปรเชลล์สำหรับผู้$PS1ใช้ทั่วไป ค่าเริ่มต้นที่ใช้กันทั่วไป คือ เครื่องหมาย$PS1ดอลลาร์$สำหรับผู้ใช้ระดับสูงสุดค่าเริ่มต้นที่ใช้กันทั่วไปคือเครื่องหมายแฮช ( # )
$ sudo --login --user root [sudo] รหัสผ่านสำหรับ liveuser: # vim /home/liveuser/names.txt # ออก$ grep -e bob ./names.txt grep: ./names.txt: การเข้าถึงถูกปฏิเสธโหมดต่างๆ
รูปแบบการเขียนโปรแกรม
แม้ว่าผู้ใช้ส่วนใหญ่จะคิดว่าเชลล์เป็นตัวแปลคำสั่งแบบโต้ตอบ แต่จริงๆ แล้วมันเป็นภาษาโปรแกรมที่แต่ละคำสั่งทำหน้าที่รันคำสั่ง เนื่องจากมันต้องตอบสนองทั้งด้านการโต้ตอบและด้านการเขียนโปรแกรมของการรันคำสั่ง จึงทำให้มันเป็นภาษาที่แปลกประหลาด ซึ่งได้รับอิทธิพลจากทั้งประวัติศาสตร์และการออกแบบ
— Brian W. Kernighan & Rob Pike , Kernighan, Brian W. ; Pike, Rob (1984). สภาพแวดล้อมการเขียนโปรแกรม UNIX . Englewood Cliffs: Prentice-Hall . ISBN 0-13-937699-2.
Bash เขียนด้วยภาษา C รูปแบบโมดูลาร์สามารถประมาณได้ด้วยรูปแบบที่ดีและการออกแบบอย่างระมัดระวัง[ 19 ] มักใช้ในรูปแบบ คำสั่งหรือขั้นตอน
โหมดโต้ตอบและโหมดไม่โต้ตอบ
ในฐานะโปรแกรมประมวลผลคำสั่ง Bash สามารถทำงานได้สองโหมด คือ โหมดโต้ตอบและโหมดไม่โต้ตอบ ในโหมดโต้ตอบ คำสั่งมักจะถูกอ่านจาก โปรแกรมจำลองเทอร์มินัลในโหมดไม่โต้ตอบ ซึ่งช่วยให้การทำงานอัตโนมัติง่ายขึ้นคำสั่งมักจะถูกอ่านจากไฟล์ที่มีชื่อ ซึ่งปัจจุบันเรียกว่าสคริปต์เชลล์เมื่อเรียกใช้เป็นคำสั่งเดี่ยวๆ ที่อินเทอร์เฟซบรรทัดคำสั่ง (CLI) โดยค่าเริ่มต้น Bash จะเปิดเชลล์ใหม่ในโหมดโต้ตอบ
สคริปต์
สคริปต์เชลล์เป็นไฟล์ข้อความที่ประกอบด้วยโค้ด ซึ่ง มักจะเป็นคำสั่ง ที่มีจุดประสงค์เพื่อให้ ตัวแปลภาษาเฉพาะอ่านและประมวลผลในกระบวนการแบบกลุ่มในโหมดที่ไม่ต้องมีการโต้ตอบจากผู้ใช้ และโดยไม่ต้องมีการแทรกแซงใดๆ เพิ่มเติม สคริปต์ที่ถูกแปลภาษาคือโปรแกรมที่ไม่จำเป็นต้องคอมไพล์ซอร์สโค้ด : ซอร์สโค้ดที่เกี่ยวข้องทั้งหมดอยู่ในสคริปต์แล้ว มีโปรแกรมมากมายที่สามารถทำหน้าที่เป็นตัวแปลภาษาสคริปต์ได้ เช่นPerl , AWKเป็นต้น สคริปต์ที่ถูกแปลภาษาส่วนใหญ่มักเขียนขึ้นสำหรับเชลล์ Unix
อักขระสองตัวแรกของบรรทัดแรกของสคริปต์เชลล์ (ที่สามารถเรียกใช้งานได้) ใดๆ จะเริ่มต้นด้วยสิ่งที่เรียกว่าชีแบง (shebang ) ซึ่งก็คืออักขระแฮช ( # ) และแบง ( ! ) เรียงติดกัน
$ cat ./example.sh # ! /bin/env bash echo foo exit$หากสคริปต์นั้นมีจุดประสงค์เพื่อให้ผู้ใช้เรียกใช้เป็นโปรแกรมแบบสแตนด์อะโลนบนบรรทัดคำสั่ง สคริปต์นั้นจะเรียกว่า"ไฟล์ปฏิบัติการ" (executable)ตามธรรมเนียมแล้ว ชื่อไฟล์ของ สคริปต์เชลล์ยูนิซ ที่เรียกใช้งานได้จะระบุด้วยคำต่อท้าย บิต.sh"เรียกใช้งานได้" สามารถเปิดใช้งานได้ในสคริปต์เชลล์โดยใช้ยูทิลิตี้chmod:
$ ls -l ./example.sh -rw-r--r--.1 liveuser liveuser 32 Aug 3 22:33 example.sh $ ./example.sh bash: ./example.sh: Permission denied $ chmod 0744 ./example.sh $ ls -l ./example.sh -rwxr--r--.1 liveuser liveuser 32 Aug 3 22:33 example.sh $ ./example.sh foo $ในsourceตัว
ด้วย คำสั่ง sourceหรือ.คำสั่งที่มีความหมายเหมือนกัน Bash จะอ่านและเรียกใช้คำสั่งเชลล์จากไฟล์ข้อความใดๆ ตามชื่อ[ 20 ]
เชลล์แบบล็อกอินและแบบไม่ล็อกอิน
Bash สามารถทำงานเป็นเชลล์ล็อกอินหรือ " ผู้นำเซสชัน " ได้ทั้งในโหมดโต้ตอบและไม่โต้ตอบผ่าน--loginตัวเลือก การ "ล็อกอิน" จำเป็นต้องมีการตรวจสอบสิทธิ์ ผู้ใช้ ด้วยเหตุนี้จึงมีเชลล์ล็อกอินเพียงหนึ่งเดียวต่อเซสชันของผู้ใช้ ใน GNU/Linux เชลล์ล็อกอินของผู้ใช้จะถูกระบุไว้ในไฟล์ /etc/passwd
$ awk -F ':' '$1 ~ /root/' /etc/passwd root:x:0:0:Super User:/root:/bin/bashเมื่อผู้ใช้เริ่มเซสชันการเข้าสู่ระบบ ขั้นตอนนี้มักเกิดขึ้นในอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI) เมื่อผู้ใช้เปิดโปรแกรมจำลองเทอร์มินัลโปรแกรมจำลองจะเรียกใช้เชลล์การเข้าสู่ระบบของผู้ใช้ในโหมด ที่ไม่ใช่การเข้า สู่ระบบจริง
การออกจากเซสชันเชลล์ภายในโปรแกรมจำลองเทอร์มินัลสามารถทำได้โดยใช้ คำสั่ง exitหรือโดยค่าเริ่มต้นใน Bash โดยการกดปุ่ม+ . Ctrld
sourceไฟล์เริ่มต้น
เมื่อ Bash เริ่มทำงาน มันจะใช้ คำสั่งใน ไฟล์ dotfilessourceต่างๆ(ดูรายการด้านล่าง) [ 21 ] ไฟล์ dotfiles เหล่านี้ ต่างจากสคริปต์เชลล์ โดยทั่วไปแล้วจะไม่มีสิทธิ์ในการเรียกใช้งานหรือhash-bangโดยค่าเริ่มต้น Bash จะเรียกใช้ชุดไฟล์ที่แตกต่างกันเล็กน้อย และในลำดับที่แตกต่างกัน ขึ้นอยู่กับ: [ 22 ]
- วิธีการเรียกใช้ Bash: แบบโต้ตอบ, แบบไม่โต้ตอบ, เรียกใช้โดยระบุชื่อ
sh - มีการใช้ตัวเลือกใดบ้าง:
--login,--rcfile,--norc,--posix - ตัวแปรสภาพแวดล้อมใดบ้างที่ถูกกำหนดไว้:
BASH_ENV,ENV, และ - ไฟล์ใดบ้างที่มีอยู่:
/etc/profile~/.bash_profile~/.bash_login~/.profile~/.bash_logout, และ~/.bashrcและอื่นๆ อีกมากมาย
แน่นอนว่าไฟล์เริ่มต้นการทำงานใดๆ ก็สามารถเรียกใช้คำสั่งจากไฟล์อื่นๆ ได้เช่นกัน ไฟล์เริ่มต้นการทำงานสามารถส่งผลต่อพฤติกรรมของเชลล์ โปรแกรมจำลองเทอร์มินัลระบบหน้าต่าง Xและ ตัว จัดการ หน้าต่าง ได้
โหมด POSIX
มาตรฐานPOSIX IEEE 1003.1 กำหนดชุดคำจำกัดความทั่วไปที่แอปพลิเคชันระบบ เชลล์ใดๆ (bash, dash , zsh ฯลฯ ) สามารถปฏิบัติตามได้สคริปต์ผู้ใช้./myscript.sh เชลล์ใดๆ ที่เขียนขึ้นตามแนวทางของ POSIX ควรจะสามารถเรียกใช้งานได้โดยแอปพลิเคชันระบบ เชลล์ใดๆ ที่ได้นำข้อกำหนดของ POSIX มาใช้ ดังนั้นจึงสามารถคาดหวังได้อย่างสมเหตุสมผลว่าสคริปต์ที่สอดคล้องกับ POSIX จะสามารถเรียกใช้งานได้สำเร็จบนระบบปฏิบัติการ Unix หรือระบบปฏิบัติการที่คล้าย Unix ใดๆ ที่ใช้มาตรฐาน POSIX ( Linux , OpenBSD , Oracle Linux , HP-UXฯลฯ) สคริปต์เหล่านี้ถือว่า " พกพาได้ " โดยไม่ต้องแก้ไขเพิ่มเติมใดๆ ส่วนของ POSIX ที่ใช้กับเชลล์และยูทิลิตี้บรรทัดคำสั่งเป็นส่วนย่อยของกลุ่มมาตรฐาน POSIX ที่ใหญ่กว่า ซึ่งระบุเพิ่มเติมว่าเทอร์มินัลและโปรแกรมจำลองเทอร์มินัลควรทำงานอย่างไรเพื่อให้ถือว่าพกพาได้เช่นกัน
เมื่อ Bash ทำงานในโหมด POSIX ฟีเจอร์ต่างๆ จะมีให้ใช้งานน้อยลง แต่โค้ดที่ได้จะสามารถทำงานได้บนระบบปฏิบัติการที่หลากหลายมากขึ้น
ในการเปิด ใช้งานโหมด POSIX เมื่อเริ่มต้นเชลล์แบบโต้ตอบ Bash สามารถเรียกใช้ได้โดยใช้หรือsh[ 23 ]ในการทำให้สคริปต์เริ่มต้นในโหมด POSIX จะต้องใช้ hashbang หรือ ที่พกพาได้น้อยกว่าเมื่ออินสแตนซ์ของ Bash ทำงานในโหมด POSIX ตัวแปรสภาพแวดล้อมจะถูกกำหนด และค่าของตัวแปรสภาพแวดล้อมจะ รวมสตริงposixbash --posixbash -o posix#!/usr/bin/env sh#!/bin/sh$POSIXLY_CORRECTSHELLOPTS
$ declare -p POSIXLY_CORRECT bash: declare: POSIXLY_CORRECT: ไม่พบ$ sh $ declare -p POSIXLY_CORRECT declare -- POSIXLY_CORRECT="y" $รายการคุณสมบัติทั้งหมดที่มีอยู่ใน Bash ซึ่งไม่ได้ระบุไว้ใน POSIX นั้นมีจำนวนมาก[ 24 ]นี่คือรายการบางส่วน:
- อาร์เรย์ใดๆ นอกเหนือจากอาร์เรย์ของพารามิเตอร์ตำแหน่ง
$@ไม่เป็นไปตามมาตรฐาน POSIX - โครงสร้างการทดสอบแบบขยายวงเล็บคู่
[[...]]ไม่ใช่มาตรฐาน POSIX[...]และtestเป็นไปตามมาตรฐาน POSIX
- หนึ่งในไวยากรณ์การประเมินค่าทางคณิตศาสตร์ด้วยวงเล็บคู่
((...))ไม่ใช่มาตรฐาน POSIX$((...))คือ POSIX
- การขยายวงเล็บ
kernel{,-headers}ไม่เป็นไปตามมาตรฐาน POSIX - การกำหนดขอบเขตพารามิเตอร์แบบไดนามิกและ
localฟังก์ชันในตัวไม่เป็นไปตามมาตรฐาน POSIX - การแทนที่กระบวนการ
<(...)ไม่เป็นไปตามมาตรฐาน POSIX - การดำเนินการจัดการสตริงบางอย่างในการขยายพารามิเตอร์ไม่เป็นไปตามมาตรฐาน POSIX
- คำสั่งพื้นฐานส่วนใหญ่ของ Bash ไม่เป็นไปตามมาตรฐาน POSIX
- คำสั่งนี้จะแสดงรายการฟังก์ชันในตัวพิเศษของ Bourne ซึ่งเป็นมาตรฐาน POSIX
enable-s$ enable -s | wc --lines 16 $ enable | wc --lines 61
- ตัวระบบภายในเอง นั้น
enableไม่รองรับมาตรฐาน POSIX - ใน Bash ในโหมดที่ไม่ใช่ POSIX คำสั่ง `and`
.และ `sourcebuiltins` มีความหมายเหมือนกัน.ฟังก์ชันในตัว (เช่น 'จุด') นั้นใช้มาตรฐาน POSIX อย่างไรก็ตาม- ฟังก์ชัน
sourceในตัวไม่รองรับมาตรฐาน POSIX
- คำสั่งนี้จะแสดงรายการฟังก์ชันในตัวพิเศษของ Bourne ซึ่งเป็นมาตรฐาน POSIX
- ตัวแปรเชลล์
$EPOCHSECONDSและ ตัวแปรอื่นๆ ไม่เป็นไปตามมาตรฐาน POSIX$EPOCHREALTIME
คำสั่งระบบที่มีอยู่ในระบบปฏิบัติการแบบ Unix สมัยใหม่ และที่กำหนดไว้ในมาตรฐาน POSIX อาจมีตัวเลือกหรือตัวแปรสภาพแวดล้อมที่เกี่ยวข้องน้อยกว่าภายใต้มาตรฐาน POSIX ส่วนใหญ่ (เช่นls) เป็นโปรแกรมแบบสแตนด์อโลนใน ไดเร็กทอรี /bin, /usr/bin, /sbinหรือ/usr/sbin(ใน Linux มักจัดหาโดยGNU coreutilsหรือBusyBox ) มากกว่าจะเป็นคำสั่งในตัวของ Bash
เนื่องจากความแตกต่างเหล่านี้และอื่นๆ สคริปต์เชลล์ Bash สมัยใหม่ (เวอร์ชัน 5) จึงไม่ค่อยสามารถรันได้ "ตามที่เป็นอยู่" ภายใต้ตัวแปลเชลล์ Bourne หรือ Korn รุ่นเก่า การเขียนสคริปต์โดยคำนึงถึงความสามารถในการพกพาเริ่มลดน้อยลงเมื่อ GNU/Linux แพร่หลายมากขึ้น[ 23 ] [ 25 ]
โค้ดที่มีไวยากรณ์ถูกต้องใน Bash แต่ไม่ได้ระบุไว้ใน POSIX เรียกว่า "bashism" โปรแกรมนี้checkbashismsสามารถใช้เพื่อให้แน่ใจว่าสคริปต์สามารถทำงานบนDebian Linux ได้ โดยไม่มีข้อผิดพลาดด้านความเข้ากันได้[ 26 ] Vidar Holen shellcheckเป็นlinter แบบคงที่อีกตัวหนึ่ง ที่เขียนด้วยHaskellซึ่งสามารถวิเคราะห์ไวยากรณ์ของสคริปต์เพื่อความเข้ากันได้กับ bash, dash, ksh และ Bourne sh ทั้งหมดหรือบางส่วน[ 27 ]
ข้อกำหนดด้านไวยากรณ์สำหรับแต่ละเชลล์นั้นแตกต่างกันเล็กน้อย ตัวอย่างเช่น นโยบายของ Debian อนุญาตให้ใช้ส่วนขยายบางอย่างในสคริปต์ (เช่นเดียวกับใน เชลล์ dash ) [ 25 ]ในขณะที่สคริปต์ที่ตั้งใจจะรองรับเชลล์ Bourne ก่อน POSIX เช่นconfigureของautoconfนั้นมีข้อจำกัดมากขึ้นในคุณสมบัติที่สามารถใช้งานได้[ 28 ]
โหมดอื่นๆ
โหมดจำกัด
เชลล์แบบจำกัดสิทธิ์ (Restricted shell) ใช้สำหรับตั้งค่าสภาพแวดล้อมที่มีการควบคุมมากกว่าเชลล์มาตรฐาน เชลล์แบบจำกัดสิทธิ์ทำงานเหมือนกับ bash ทุกประการ ยกเว้นว่าการกระทำหลายอย่างไม่ได้รับอนุญาตหรือไม่ดำเนินการ รวมถึง:
- การเปลี่ยนไดเร็กทอรีด้วย
cdฟังก์ชันในตัว - การกำหนดค่าหรือยกเลิกการกำหนดค่าของตัวแปร
SHELL,PATH,HISTFILE,ENV, หรือBASH_ENV - การระบุชื่อคำสั่งที่มีเครื่องหมายทับ (/) บนบรรทัดคำสั่ง (CLI)
- การใช้พาธแบบสัมบูรณ์เป็นอาร์กิวเมนต์สำหรับคำสั่ง
.,history, หรือhash-p - ระบุการค้นหาเส้นทางด้วย
. -pหรือ.command-p - นำเข้าคำจำกัดความของฟังก์ชันและแยกวิเคราะห์ค่า
SHELLOPTSจากสภาพแวดล้อมเชลล์เมื่อเริ่มต้นระบบ - การเปลี่ยนเส้นทางการส่งออกโดยใช้ตัวดำเนินการเปลี่ยนเส้นทาง
>,>,<>,>&,&>, และ>> - ใช้คำ
execสั่งในตัวเพื่อแทนที่เชลล์ด้วยคำสั่งอื่น - การแก้ไขค่าในตัวของเชลล์
เมื่อเปิดใช้งานโหมดจำกัดแล้ว จะไม่สามารถปิดใช้งานได้ ข้อจำกัดเหล่านี้จะถูกบังคับใช้หลังจากอ่านไฟล์เริ่มต้นระบบแล้ว และจะไม่มีผลกับสคริปต์เชลล์ โหมดจำกัดนี้ไม่ค่อยได้ใช้
โหมดพิเศษ
ใน Bash "โหมดสิทธิ์พิเศษ" เป็นตัวเลือกที่ใช้ไม่บ่อยนักซึ่งสืบทอดมาจากเชลล์ SVR4.2 UNIX System V (ประมาณปี 1992) [ 29 ]สามารถเปิดใช้งานได้ด้วยและปิดใช้งานได้ด้วย[ 30 ] เมื่อเปิดใช้งานโหมดสิทธิ์พิเศษตัวแปรเชลล์จะรวมสตริง "privileged" ไว้ด้วย set-pset+pSHELLOPTS
โหมดดีบักแบบขยาย
เปิดใช้งานผ่านbash --debuggerการเรียกใช้หรือผ่านระหว่างโหมดโต้ตอบหรือไม่โต้ตอบ โดยใช้โปรแกรมแยกต่างหากที่เรียกว่าbashdb [ 31 ] extdebugไม่สามารถใช้งานได้ในโหมด POSIX ดูเอกสารประกอบสำหรับข้อมูลเพิ่มเติม ดูเพิ่มเติมที่§ การดีบัก shopt-sextdebug
โหมดความเข้ากันได้
Bash-4.0 ได้นำเสนอแนวคิดของระดับความเข้ากันได้ของเชลล์ ซึ่งระบุเป็นชุดตัวเลือกสำหรับคำสั่ง shopt ในตัว (compat31, compat32, compat40, compat41 และอื่นๆ) ปัจจุบันมีระดับความเข้ากันได้เพียงระดับเดียวเท่านั้น โดยแต่ละตัวเลือกจะไม่สามารถใช้ร่วมกันได้ ระดับความเข้ากันได้นี้มีจุดประสงค์เพื่อให้ผู้ใช้สามารถเลือกพฤติกรรมจากเวอร์ชันก่อนหน้าที่ไม่เข้ากันกับเวอร์ชันใหม่กว่าในขณะที่พวกเขากำลังย้ายสคริปต์เพื่อใช้คุณสมบัติและพฤติกรรมปัจจุบัน โดยมีจุดประสงค์เพื่อเป็นวิธีแก้ปัญหาชั่วคราว[ 32 ]
— คู่มืออ้างอิง Bash, โหมดความเข้ากันได้ของเชลล์ 6.12
ความสามารถในการสังเกตการณ์
ตัวเลือกxtrace
เมื่อ เปิดใช้งาน xtraceเนื้อหาการดีบักแบบง่ายจะถูกพิมพ์ไปยังเทอร์มินัล สามารถเปิดใช้งานได้ด้วยหรือและปิดใช้งานได้ด้วยหรือตัวเลือกเหล่านี้ยังสามารถใช้ได้ที่บรรทัดคำสั่งและที่ hash-bangs ด้วยเช่น , เป็นต้น set -o xtraceset -xset +o xtraceset +xset -#!/bin/bash -x
$ bash -x $ echo $(( 2 + 2 )) + echo 4 4 $ set -- 1 2 3 $ printf '<%s>\n' " $@ " + printf '<%s>\n' 1 2 3 <1> <2> <3> $การ ตั้งค่าเชลล์ xtraceถูกกำหนดโดยมาตรฐาน POSIX ดูเพิ่มเติมที่หัวข้อ§ การดีบัก
ตัวเลือกแบบละเอียด
ตัวเลือก verbose จะพิมพ์สตริงไปยังเทอร์มินัลขณะที่อ่าน และก่อนที่จะทำการขยายใดๆ ไม่ค่อยได้ใช้[ 33 ]
ความคิดเห็น
การใส่คำอธิบายประกอบเป็นวิธีที่มีประโยชน์ในการชี้แจงข้อมูลหรืออธิบายสคริปต์หรือไฟล์ต้นฉบับให้แก่ผู้อื่นที่อาจไม่คุ้นเคยกับเจตนาหรือบริบทของผู้เขียนสคริปต์
ข้อความแสดงความคิดเห็นมาตรฐานใน Bash จะใช้เครื่องหมายแฮช ( # ) แทน ข้อความใดๆ ที่อยู่ทางขวาของเครื่องหมายแฮชไปจนถึงท้ายบรรทัดจะถูกละเว้น อนุญาตให้ใช้ข้อความแสดงความคิดเห็นแบบแทรกในบรรทัดได้ แต่ข้อความแสดงความคิดเห็นแบบแฮชจะไม่แสดงผลระหว่างการดีบัก ดูเพิ่มเติมที่: § xtrace
ความคิดเห็นที่ระบุด้วยเครื่องหมายโคลอน:มาจากเชลล์ Thompsonอาร์กิวเมนต์ใดๆ ทางด้านขวาของเครื่องหมายโคลอน:จะถูกละเว้น ความคิดเห็นแบบอินไลน์ไม่สามารถทำได้ แต่ความคิดเห็นแบบโคลอนจะถูกพิมพ์ระหว่างการดีบัก และพารามิเตอร์ใดๆ จะถูกขยาย[ 34 ]
$ # กำหนดค่า foo $ foo = bar # คอมเมนต์แบบแฮชแทรกในบรรทัดเดียวกับคำสั่ง$ set -x $ # คอมเมนต์ปกติ (ไม่มีเอาต์พุต) $ : " ${ foo } " + : bar $
รหัสทางออก
เมื่อ bash ประมวลผลคำสั่ง จะมีการสร้างรหัส สถานะการออกหรือที่เรียกว่า "รหัสส่งคืน" ซึ่งสามารถให้ข้อมูลเชิงลึกเกี่ยวกับวิธีที่โปรแกรมหยุดทำงานได้ ค่าของรหัสการออกที่บันทึกไว้ล่าสุดจะถูกเก็บไว้ในพารามิเตอร์ของเชลล์ 'เครื่องหมายคำถาม:' $?ในบริบทที่ไม่เกี่ยวข้องกับการคำนวณทางคณิตศาสตร์ (เช่น ในกรณีส่วนใหญ่) ค่าตัวเลขหรือ " บูลีน " ของ "จริง" คือศูนย์ (0) และค่าของ "เท็จ" คือหนึ่ง (1)
เมื่อคำสั่งระบบทำงานเสร็จสิ้น ความหมายที่แท้จริงของสถานะการออกจากระบบมักจะพบได้ในหน้าคู่มือ (man page) โดยปกติแล้วเลขศูนย์หมายถึงความสำเร็จ และสถานะการออกจากระบบที่ไม่ใช่ศูนย์หมายถึงความล้มเหลวหรือความสำเร็จบางส่วน pingเป็นคำสั่งที่รู้จักกันดีซึ่งมีรหัสการออกจากระบบที่มีความหมายสามแบบ ได้แก่ 0, 1 และ 2
ใน Bash ภายในบริบททางคณิตศาสตร์ ค่าความจริงของตัวเลขจะกลับกัน: "จริง" คือหนึ่ง และ "เท็จ" คือศูนย์ บริบททางคณิตศาสตร์มักจะระบุได้จากไวยากรณ์ `true` ((...))หรือ ` $((...))false` หากคำสั่งทางคณิตศาสตร์ประเมินค่าได้เป็นจำนวนเต็มศูนย์ คำสั่งนั้นจะถือว่าเป็น "จริง" และรหัสการออกจะเป็นหนึ่ง หากคำสั่งนั้นประเมินค่าได้เป็นตัวเลขอื่นที่ไม่ใช่ศูนย์ คำสั่งทางคณิตศาสตร์นั้นจะถือว่าเป็น "เท็จ" และรหัสการออกจะเป็นศูนย์
คำสั่งในระบบ Linux/UNIX บางคำสั่งไม่ได้ให้รหัสการออกที่มีความหมายนอกเหนือจากศูนย์และหนึ่ง และไม่มีระบบมาตรฐานสำหรับการกำหนดรหัสการออกในระบบ Linux
$ true ; echo " $? " # รหัสออกหมายถึง "true" 0 $ false ; echo " $? " ; echo # รหัสออกหมายถึง "false" 1 $ $ bash -c 'exit 99' ; printf 'exit-code: %d\n\n' " $? " exit-code: 99 $ $ (( 1 - 1 )) ; printf '%d\n' " $? " # รหัสออกนี้หมายถึง "true" 1 $ (( 1 + 1 )) ; printf '%d\n' " $? " # ...และรหัสออกนี้หมายถึง "false" 0
การควบคุมงาน
เชลล์ Bash มีโหมดการเรียกใช้คำสั่งสองโหมด ได้แก่ แบบกลุ่ม (แบบอะซิงโครนัส) และแบบพร้อมกัน (แบบซิงโครนัส) ในการเรียกใช้คำสั่งในโหมดกลุ่ม (เช่น ตามลำดับ) คำสั่งเหล่านั้นจะต้องคั่นด้วยเครื่องหมาย;หรือเขียนไว้ในบรรทัดที่แยกกัน:
$ command1 ; command2 $ command3 $
ในตัวอย่างนี้ เมื่อคำสั่ง command1เสร็จสิ้นคำสั่ง command2 จะถูกดำเนิน การ และเมื่อคำสั่ง command2เสร็จสิ้น คำ สั่ง command3จะ ถูกดำเนินการ การเรียกใช้ คำสั่ง command1 ในพื้นหลังสามารถทำได้โดยใช้สัญลักษณ์&ที่ท้ายคำสั่งการเรียกใช้ และกระบวนการจะถูกดำเนินการในพื้นหลังพร้อมกับส่งการควบคุมกลับไปยังเชลล์ทันทีและอนุญาตให้ดำเนินการคำสั่งต่อไปได้
$ command1 & $
หรือหากต้องการเรียกใช้คำสั่งcommand1และcommand2 พร้อมกัน จะต้องเรียกใช้คำสั่งเหล่านั้นใน Bash shell ด้วยวิธีดังต่อไปนี้:
$ command1 & command2 $
ในกรณีนี้command1จะถูกดำเนินการในพื้นหลังและสัญลักษณ์ & จะส่งคืนการควบคุมทันทีไปยังเชลล์ที่ดำเนินการcommand2ในพื้นหน้า กระบวนการสามารถหยุดได้และส่งคืนการควบคุมไปยัง bash โดยการพิมพ์+ ในขณะที่กระบวนการกำลังทำงานในพื้นหน้า[ 35 ] รายชื่อของกระบวนการทั้งหมด ทั้งในพื้นหลังและที่หยุดแล้ว สามารถทำได้โดยการเรียกใช้งาน : Ctrlz
$ งาน[1]- เรียกใช้คำสั่ง 1 และ$
ในผลลัพธ์ ตัวเลขในวงเล็บหมายถึงรหัสงาน เครื่องหมายบวกหมายถึงกระบวนการเริ่มต้นสำหรับbgและfgข้อความ "กำลังทำงาน" และ "หยุดแล้ว" หมายถึงสถานะของกระบวนการและสตริงสุดท้ายคือคำสั่งที่เริ่มต้นกระบวนการ
สามารถเปลี่ยนสถานะของกระบวนการได้โดยใช้คำสั่งต่างๆ คำสั่ง fgจะนำกระบวนการมาทำงานในพื้นหน้า ในขณะที่bgจะตั้งค่ากระบวนการที่หยุดทำงานให้ทำงานในพื้นหลัง คำสั่ง bgและfgสามารถรับรหัสงานเป็นอาร์กิวเมนต์แรกเพื่อระบุกระบวนการที่จะดำเนินการ หากไม่มีรหัสงาน คำสั่งเหล่านี้จะใช้กระบวนการเริ่มต้น ซึ่งระบุด้วยเครื่องหมายบวกในผลลัพธ์ของคำสั่ง jobsคำ สั่ง killสามารถใช้เพื่อยุติกระบวนการก่อนกำหนดโดยการส่งสัญญาณ ไปยังกระบวนการ นั้น ต้องระบุรหัสงานหลังเครื่องหมายเปอร์เซ็นต์
$ sleep 100 & [1] 4904 $ kill %1 $ jobs [1]+ Terminated sleep 100 $
การควบคุมงาน หรือที่เรียกว่า "โหมดตรวจสอบ" จะเปิดใช้งานโดยค่าเริ่มต้นในเชลล์แบบโต้ตอบ และสามารถปิดใช้งานได้ด้วยคำสั่ง ` .` set+m
สัญญาณ
การส่งสัญญาณเป็นวิธีการสื่อสารระหว่างกระบวนการ (IPC) บางครั้งกระบวนการบรรทัดคำสั่งอาจดูเหมือนหยุดทำงานกลางคัน ในกรณีเช่นนี้ อาจจำเป็นต้องระบุว่ากระบวนการใดถูกบล็อกและยุติกระบวนการที่ก่อปัญหาด้วยตนเอง
ในเทอร์มินัลแบบโต้ตอบ โดยปกติแล้ว การกดปุ่มเพื่อยุติกระบวนการที่ทำงานอยู่เบื้องหน้าและส่งการควบคุมกลับไปยังพร้อมท์ผู้ใช้ หรือการกดปุ่มเพื่อระงับกระบวนการ ก็เพียงพอแล้ว ในบางครั้ง การพยายามระงับกระบวนการอาจสำเร็จเมื่อการพยายามยกเลิกกระบวนการดูเหมือนจะไม่ตอบสนอง ในกรณีอื่นๆ อาจจำเป็นต้องใช้ โปรแกรม killเพื่อส่งสัญญาณ IPC ในตัวอย่างนี้ เราใช้ คำสั่ง killจากหน้าจอเทอร์มินัลที่สองเพื่อยุติกระบวนการที่มี PID 4331 Ctrl-c Ctrl-z
$ tty # เทอร์มินัลหนึ่ง/dev/pts/0 $ whoami liveuser $ sleep 1000 # คำสั่งค้าง
$ tty # เทอร์มินัลสอง/dev/pts/1 $ whoami liveuser $ ps aux | grep -e sleep -e PID USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND liveuser 4331 0.0 0.0 230336 2312 pts/1 S+ 11:19 0:00 sleep 1000 liveuser 4333 0.0 0.0 231248 2516 pts/0 S+ 11:19 0:00 grep --color=auto -e sleep -e PID $ kill 4331 $ ps aux | grep -e sleep -e PID # กระบวนการ sleep สิ้นสุดลงแล้วUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND liveuser 4333 0.0 0.0 231248 2516 pts/0 S+ 11:19 0:00 grep --color=auto -e sleep -e PID $
$ tty # เทอร์มินัลอีกครั้ง/dev/pts/0 $ whoami liveuser $ sleep 1000 Terminated $
ในระบบปฏิบัติการที่คล้าย Unix ผู้ใช้สามารถสั่งการเคอร์เนลให้ส่งสัญญาณไปยังกระบวนการที่เป็นของผู้ใช้นั้นได้ ผู้ใช้ทั่วไปไม่สามารถส่งสัญญาณไปยังกระบวนการที่มีสิทธิ์พิเศษได้ สามารถส่งสัญญาณไปยังกระบวนการได้โดยใช้ คำสั่ง killหรือใช้ไบนารีของระบบที่มีชื่อเดียวกัน
$ whoami liveuser $ ps aux | awk '$2 ~ /\<1\>/' # มาดูข้อมูลบางอย่างเกี่ยวกับกระบวนการเคอร์เนล กระบวนการ 1 root 1 0.0 0.2 37140 20440 ? Ss 04:44 0:18 /usr/lib/systemd/systemd --switched-root --system --deserialize=53 rhgb $ kill -s SIGKILL 1 bash: kill: (1) - การดำเนินการไม่ได้รับอนุญาต$ type -a kill kill เป็นคำสั่งภายในของเชลล์kill คือ /usr/bin/kill $ /usr/bin/kill -s SIGKILL 1 kill: การส่งสัญญาณไปยัง 1 ล้มเหลว: การดำเนินการไม่ได้รับอนุญาต$
สัญญาณที่ใช้บ่อยที่สุดสามารถดูได้ด้วยkill -L | head -n 4แต่ละสัญญาณ IPC จะเชื่อมโยงกับหมายเลขสัญญาณ แต่รหัสออกและรหัสสัญญาณนั้นแตกต่างกัน แม้ว่าการส่งสัญญาณ IPC หมายเลข 9 (สัญญาณ "ฆ่า") ไปยังกระบวนการหนึ่งจะทำให้กระบวนการนั้นยุติลงทันที แต่ก็มีโอกาสสูงที่กระบวนการนั้นจะไม่ส่งรหัสออก 9 กลับมา
โดยค่าเริ่มต้นใน Bash คำสั่ง kill ในตัวจะส่งสัญญาณ TERM ("terminate") เป็นเรื่องปกติที่ยูทิลิตี้บรรทัดคำสั่งจะตอบสนองต่อ SIGTERM โดยการปิดระบบและออกจากโปรแกรมอย่างสะอาด (TERM และ SIGTERM เหมือนกัน คำนำหน้า SIG- ในชื่อสัญญาณทั้งหมดสามารถละเว้นได้) ลำดับการกดปุ่ม Ctrl-c ใน Bash จะส่งสัญญาณ SIGINT ซึ่งเป็นสัญญาณขัดจังหวะไปยังกระบวนการเบื้องหน้า ลำดับการกดปุ่ม Ctrl-z จะส่งสัญญาณ SIGSTOP ซึ่งเป็นสัญญาณหยุด[ 36 ] เมื่อกระบวนการได้รับ SIGKILL กระบวนการจะยุติลงทันทีและไม่เป็นระเบียบ ขอแนะนำให้ใช้ SIGKILL เป็นทางเลือกสุดท้ายเท่านั้น[ 37 ] สัญญาณ SIGKILL ไม่สามารถถูกบล็อกหรือจัดการได้
กระบวนการต่างๆ สามารถ "ดักจับ" และ "จัดการ" สัญญาณ IPC ที่ได้รับ ผู้ใช้สามารถใช้คำสั่ง kill ในตัวเพื่อ "ส่ง" สัญญาณ IPC ไปยังกระบวนการอื่น กระบวนการเป้าหมายนั้นสามารถตั้งค่ากลไกหรือวางแผนล่วงหน้าไว้ว่าจะตอบสนองอย่างไรเมื่อได้รับหรือ "ดักจับ" สัญญาณใดๆ ก็ตาม วิธีที่โปรแกรมเป้าหมายตอบสนองนั้นเรียกว่าวิธีที่โปรแกรม "จัดการ" การรับสัญญาณ ในหน้าคู่มือจะเห็นได้ว่าคำสั่งระบบบางคำสั่งจะพิมพ์ข้อมูลบางอย่างไปยังเทอร์มินัลเมื่อได้รับ SIGHUP ตัวอย่างเช่นddคำสั่ง[ 38 ]
เมื่อ bash เป็นแบบโต้ตอบ ในกรณีที่ไม่มีกับดักใดๆ bash จะไม่สนใจSIGTERM (เพื่อไม่ให้เชลล์แบบโต้ตอบหยุดทำงาน) และจะดักจับและจัดการSIGINT (เพื่อให้ ฟังก์ชัน waitในตัวสามารถถูกขัดจังหวะได้) เมื่อ bash ได้รับSIGINTมันจะออกจากลูปการทำงานใดๆ ในทุกกรณี bash จะไม่สนใจSIGQUITหากมีการควบคุมงาน bash จะไม่สนใจ SIGTTIN , SIGTTOUและSIGTSTP [ 39 ]
kill0
— บัช(1)
โดยค่าเริ่มต้น สคริปต์เชลล์ Bash จะรับและตอบสนองต่อสัญญาณ IPC ทั้งหมดที่ส่งไปยังสคริปต์เหล่านั้น อย่างไรก็ตาม สคริปต์ Bash สามารถใช้ฟังก์ชันtrapในตัวเพื่อดักจับและจัดการสัญญาณได้[ 40 ]
$ cat ./trap-example.sh # ! /usr/bin/env bash trap umask EXIT echo bar exit 0 $ chmod 0700 trap-example.sh $ ./trap-example.sh bar 0077 $
มีสัญญาณบางอย่างที่ใช้งานได้เฉพาะภายใน Bash เท่านั้น ซึ่งเป็นส่วนขยายของ GNU ได้แก่ERR , EXIT , RETURNและDEBUGสัญญาณเหล่านี้มีประโยชน์ในการดีบัก และสามารถส่งและจัดการได้โดยฟังก์ชันภายในของเชลล์เท่านั้น ดูเพิ่มเติมที่§ การดีบัก
ค่าของพารามิเตอร์
มีการใช้งานecho ที่แตกต่างกันมากมาย บางแบบมีตัวเลือก และบางแบบไม่มี[ 41 ] รายการตัวเลือกไม่สม่ำเสมอในแต่ละการใช้งาน แม้ว่าechoและprintf จะถูกกำหนดโดย POSIX ก็ตาม หากผู้ เขียน สคริปต์ต้องการทราบค่าที่แน่นอนของสตริงที่อยู่ในตัวแปร วิธีที่สอดคล้องกันมากที่สุดคือการใช้printf-e
สำหรับสตริงใดๆ ที่มีอักขระใดๆ (ยกเว้นค่าว่าง?) รวมถึงตัวเลข ตัวระบุรูปแบบคือ% s
$ foo = abc bar = 123 $ printf '<%s>\n' " ${ foo } " " ${ bar } " <abc> <123> $
สำหรับตัวเลขเท่านั้น ตัวระบุรูปแบบคือ% d
$ printf '<%d>\n' " ${ foo } " " ${ bar } " bash: printf: abc: ตัวเลขไม่ถูกต้อง<0> <123> $
เมื่อใช้คำสั่ง printfจะไม่มีการขึ้นบรรทัดใหม่ในผลลัพธ์ เว้นแต่ผู้เขียนสคริปต์จะใส่การขึ้นบรรทัดใหม่ในสตริงรูปแบบ ในตัวอย่างด้านล่างนี้ ซึ่งไม่ได้ใส่การขึ้นบรรทัดใหม่ในสตริงรูปแบบ ค่าของ PS1 จะถูกพิมพ์ในบรรทัดเดียวกันกับผลลัพธ์ของคำสั่งก่อนหน้า
$ printf '<%s>' " ${ foo } " " ${ bar } " <abc><123>$
อีกวิธีหนึ่งที่สม่ำเสมอมากคือการใช้ผลลัพธ์ของสามารถนำกลับมาใช้เป็นอินพุตได้ อย่างไรก็ตาม ไม่ใช่ทุกตัวแปรและพารามิเตอร์ที่จะสามารถพิมพ์ได้โดยใช้เช่น ค่าของพารามิเตอร์พิเศษ แฮชแท็กพารามิเตอร์พิเศษจะรายงานจำนวนพารามิเตอร์ตำแหน่งที่ถูกกำหนดไว้ในปัจจุบัน declare-pdeclare-pdeclare-p"$#"
$ declare -p foo bar declare -- foo="abc" declare -- bar="123" $ declare -p " $# " bash: declare: 0: not found $
สำหรับการป้อนข้อมูลแบบเต็มบรรทัดในเชลล์แบบโต้ตอบ...
$ declare -p #
...แฮชจะตีความแฮชแท็กนี้ว่าเป็นความคิดเห็นแบบแทรกในบรรทัด เมื่อลบความคิดเห็นและข้อความทั้งหมดทางด้านขวาออกแล้ว คำสั่งที่บาชจะดำเนินการคือ `npm run name` คำสั่งนี้ตามที่ระบุไว้ จะ"แสดงค่าและแอตทริบิวต์ของแต่ละ NAME" กล่าวคือ แต่ละตัวแปร และ "หากไม่มีการระบุ NAME จะแสดงค่าและแอตทริบิวต์และค่าของตัวแปรทั้งหมด" ซึ่งอาจมีผลลัพธ์มากกว่า 100 บรรทัด declare-phelp declare
ในทางกลับกันคำสั่ง printfไม่สามารถแสดงคุณสมบัติของตัวแปรได้ โปรดดูเพิ่มเติมที่§ การแก้ไขข้อผิดพลาด
$ readonly foo $ declare -p foo declare -r foo="abc" $ printf '<%s>' " ${ foo } " <abc> $
สิ่งแวดล้อม
สภาพแวดล้อมการดำเนินการที่กำหนดค่าได้: [ 42 ]
- ไฟล์เริ่มต้น เชลล์และเซสชันเช่น
~/.bashrcและ~/.profile(เช่นไฟล์ dotfiles ); - การตั้งค่า ( set built-in ) และตัวเลือกเชลล์ ( shopt built-in ) ที่เปลี่ยนแปลงพฤติกรรมของเชลล์
ไฟล์เริ่มต้นเชลล์และเซสชัน (หรือที่เรียกว่า "ไฟล์ดอท")
เมื่อ Bash เริ่มทำงาน มันจะเรียกใช้คำสั่งในไฟล์ dotต่างๆ[ 21 ] ต่างจากสคริปต์เชลล์ Bash ไฟล์ dot โดยทั่วไปจะไม่มีสิทธิ์ในการเรียกใช้หรือคำสั่งตัวแปลเช่น#!/bin/bash.
- ตัวอย่างการเริ่มต้นใช้งาน Bash ที่เข้ากันได้กับเวอร์ชันเก่า
ตัวอย่าง~/.bash_profileด้านล่างนี้ใช้งานได้กับ Bourne shell และให้ความหมายคล้ายกับ csh สำหรับ~/.bashrcและ~/.bash_loginเป็นการประเมินแบบลัดวงจรที่ทดสอบว่าไฟล์ชื่อมีอยู่และอ่านได้หรือไม่ โดยจะข้ามส่วนหลังหากไม่ใช่ [ -r filename ] && cmd&&
[ -r ~/.profile ] && ~/.profile # ตั้งค่าสภาพแวดล้อมเพียงครั้งเดียว ใช้ไวยากรณ์ Bourne-sh เท่านั้นถ้า[ -n " $PS1 " ] ; แล้ว# เรากำลังใช้งานแบบโต้ตอบอยู่หรือไม่? [ -r ~/.bashrc ] && ~/.bashrc # การตั้งค่า tty/prompt/ฟังก์ชันสำหรับเชลล์แบบโต้ตอบ[ -r ~/.bash_login ] && ~/.bash_login # งานใดๆ ที่เกี่ยวข้องกับการเข้าสู่ระบบสำหรับเชลล์ล็อกอินเท่านั้นfi # สิ้นสุดบล็อก "if"
- ปัญหาเกี่ยวกับระบบปฏิบัติการในการเริ่มต้น Bash
ระบบปฏิบัติการ UnixและLinuxบางเวอร์ชันมีสคริปต์ เริ่มต้น ระบบ/etc Bash ซึ่ง โดยทั่วไป จะอยู่ ในไดเร็กทอรี` / etc / bash ...~/.xsession~/.xprofile~/.profile
สตรีมมาตรฐาน
สตรีมมาตรฐาน - STDIN, STDOUT และ STDERR
คำสั่ง
คำสั่งระบบ
ชื่อเรียกอื่น
ชื่อแทน (Aliases) ช่วยให้สามารถแทนที่สตริงด้วยคำที่อยู่ในตำแหน่งที่สามารถเป็นคำแรกของคำสั่งง่ายๆ ในข้อมูลป้อนเข้าได้ ชื่อแทนจะมีชื่อและค่าที่สอดคล้องกัน ซึ่งสามารถตั้งค่าและยกเลิกได้โดยใช้คำสั่ง alias และ unalias ที่มีอยู่แล้วในระบบ
คำหลักและคำที่กลับด้าน
function- การประกาศฟังก์ชัน Bash ที่มีคีย์เวิร์ดเฉพาะนี้จะไม่สามารถใช้งานร่วมกับสคริปต์ Bourne/Korn/POSIX ได้ อย่างไรก็ตาม Bash ยอมรับไวยากรณ์การประกาศฟังก์ชันที่ใช้โดยเชลล์ Bourne, Korn และ POSIX
ฟังก์ชัน
ฟังก์ชันเชลล์เป็นวิธีการจัดกลุ่มคำสั่งเพื่อเรียกใช้ในภายหลัง โดยใช้ชื่อเดียวสำหรับกลุ่มคำสั่งนั้น ฟังก์ชันเหล่านี้จะถูกเรียกใช้เหมือนกับคำสั่งธรรมดาทั่วไป เมื่อใช้ชื่อของฟังก์ชันเชลล์เป็นชื่อคำสั่งธรรมดา เชลล์จะเรียกใช้รายการคำสั่งที่เกี่ยวข้องกับชื่อฟังก์ชันนั้น ฟังก์ชันเชลล์จะถูกเรียกใช้ในบริบทของเชลล์ปัจจุบัน ไม่มีการสร้างกระบวนการใหม่เพื่อตีความฟังก์ชันเหล่านั้น
คำสั่งในตัว
- คำสั่งในตัวต่างๆ:
- POSIX ฟังก์ชันในตัวพิเศษ: [ 54 ]
- ซีดี , รหัสผ่าน , เป็นต้น
- ชุด[ 55 ]
- Xtrace: [ | ]. เครื่องมือหลักในการดีบักของเชลล์ สามารถปิดทั้ง xtrace และ verbose พร้อมกันได้ด้วยคำสั่ง.
set-xset-oxtraceset- - Verbose: [ | ]. พิมพ์คำสั่งไปยังเทอร์มินัลตามที่ Bash อ่าน Bash อ่านโครงสร้างทั้งหมดพร้อมกัน เช่น คำสั่งประกอบที่รวมบล็อก if-fi และ case-esac หากมีการรวม a ไว้ในคำสั่งประกอบ "verbose" จะถูกเปิดใช้งานในครั้งถัดไปที่ Bash อ่านโค้ดเป็นอินพุต กล่าวคือ หลังจากสิ้นสุดโครงสร้างที่กำลังทำงานอยู่[ 56 ]
set-vset-overboseset-v - สามารถปิดทั้ง xtrace และ verbose พร้อมกันได้ด้วยคำสั่ง.
set-
- Xtrace: [ | ]. เครื่องมือหลักในการดีบักของเชลล์ สามารถปิดทั้ง xtrace และ verbose พร้อมกันได้ด้วยคำสั่ง.
- ร้านค้า[ 57 ]
- expand-aliases: เปิดใช้งานโดยค่าเริ่มต้นในเชลล์แบบโต้ตอบ นักพัฒนาบางรายไม่แนะนำให้ใช้ในสคริปต์
- POSIX ฟังก์ชันในตัวพิเศษ: [ 54 ]
คำสั่ง PATH และคำสั่งระบบ
เมื่อเชลล์ค้นหาคำสั่งภายนอก มันจะอาศัยตัวแปรเชลล์ Bourne $PATHซึ่ง$PATHประกอบด้วยรายการของไดเร็กทอรีที่คั่นด้วยเครื่องหมายโคลอน:โดยเริ่มจากไดเร็กทอรีซ้ายสุดและเลือกไดเร็กทอรีจากซ้ายไปขวา แต่ละไดเร็กทอรีจะถูกค้นหาจนกว่าจะพบคำสั่งที่ตรงกัน ในลินุกซ์ เพื่อให้ผู้ใช้สามารถค้นหาคำสั่งเพิ่มเติมได้ เป็นเรื่องปกติที่ผู้ดูแลระบบการแจกจ่ายและนักพัฒนาแพ็กเกจจะแก้ไขค่าของตัวแปรเชลล์ Bourne ของผู้ใช้ปลายทาง$PATHโดยการรวมไฟล์ต้นฉบับไว้ใน ไดเร็กทอรี `.bourne.js` /etc/profile.dและตำแหน่งอื่นๆ
เมื่อค้นหาคำสั่งchmodเช่น หลังจากพิจารณาคำสั่งภายในแล้วไม่พบอะไรเลย Bash จะค้นหาไดเร็กทอรีใน$PATHและจะเลือกเส้นทางสัมบูรณ์ของไฟล์ปฏิบัติการแรกที่พบซึ่งมีชื่อพื้นฐานที่ตรงกับสตริงการค้นหา[ 18 ]
หากมีคำสั่งมากกว่าหนึ่งคำสั่งechoในไดเร็กทอรีที่ระบุไว้$PATHในระหว่างกระบวนการวิเคราะห์และเรียกใช้คำสั่งบรรทัดคำสั่ง โดยค่าเริ่มต้นจะเลือกเฉพาะคำสั่งแรกที่พบเท่านั้น $PATHการค้นหาใช้เวลานาน เชลล์จะเร่งความเร็วในการดำเนินการคำสั่งบรรทัดคำสั่งโดยการจดจำตำแหน่งคำสั่งในตารางแฮช หากต้องการค้นหาแบบเต็ม$PATHโดยไม่มีการแทรกแซงจากตารางแฮช ให้ลบตารางปัจจุบันด้วยและค้นหาคำสั่งทุกประเภทด้วย hash-rtype-a
$ # บังคับค้นหาเส้นทางแบบเต็ม$ PATH = ${ PATH } : ${ HOME } $ printf 'echo script_file: "$@"\n' > ./echo $ chmod 0700 ./echo $ hash -r ; type -a echo echo เป็นคำสั่งภายในของเชลล์echo คือ /usr/bin/echo echo คือ /home/liveuser/echo $
ในการเรียกใช้คำสั่งจากบรรทัดคำสั่งที่ปรากฏอยู่ถัดไปใน$PATHสตริง คุณสามารถระบุพาธแบบสัมบูรณ์ หรือกำหนดให้การแก้ไขพาธสัมพันธ์กับไดเร็กทอรีการทำงานปัจจุบันได้
$ /home/liveuser/echo foo script_file: foo $ ./echo bar script_file: bar $
เพื่อความปลอดภัย ควรตรวจสอบให้แน่ใจว่าไดเร็กทอรีใน PATH ไม่สามารถเข้าถึงได้โดยทุกคน หรือสามารถเข้าถึงได้เฉพาะผู้ใช้ root และผู้ใช้ที่เชื่อถือได้เท่านั้น
การค้นหาคำสั่ง
- ตำแหน่งคำสั่ง: หลังจากการขยายความแล้ว จะเป็นคำแรกของข้อความคำสั่งทั้งหมด
- การค้นหาชื่อคำสั่งจะดำเนินการตามลำดับดังต่อไปนี้:
- คำสั่งภายในเชลล์ :
- ชื่อเรียกแทน ของเชลล์
- คำสงวนของเชลล์
- ฟังก์ชันเชลล์และ
- คำสั่งในตัวของเชลล์ ;
- คำสั่งภายนอกเชลล์ โดยใช้ตัวแปรเชลล์ PATH:
- คำสั่งภายในเชลล์ :
- สตริงที่ได้จะถูกนำไปประมวลผลเป็นคำสั่ง
โครงสร้างควบคุม
ซับเชลล์
ซับเชลล์ : (...);
ท่อส่ง
อย่างไรก็ตาม การใช้ไปป์ไลน์ช่วยให้สามารถประมวลผลหลายรอบพร้อมกันได้ ซึ่งเพิ่มความเร็วได้อย่างมาก ในหน่วยควบคุมแบบไปป์ไลน์ คำสั่งต่างๆ จะผ่านกระบวนการพร้อมกัน แต่ในจุดที่แตกต่างกัน ในขณะที่กำลังดึงคำสั่งหนึ่ง คำสั่งที่สองก็กำลังถูกถอดรหัส และอื่นๆไปป์ไลน์ แบบ Unix : |.
ตัวดำเนินการตรรกะ
- และ (
&&) - หรือ (
||) - ไม่ (
!)
Bash มีตัวคั่นคำสั่งแบบ "การทำงานแบบมีเงื่อนไข" ซึ่งทำให้การทำงานของคำสั่งขึ้นอยู่กับรหัสการออกที่กำหนดโดยคำสั่งก่อนหน้า ตัวอย่างเช่น:
$ cd " $SOMEWHERE " && ./do_something || echo "เกิดข้อผิดพลาด" > & 2คำสั่ง `where` ./do_somethingจะถูกเรียกใช้ก็ต่อเมื่อ คำสั่ง `cd` (เปลี่ยนไดเร็กทอรี) "สำเร็จ" (ส่งค่าสถานะการออกเป็นศูนย์) และ คำสั่ง `echo`จะถูกเรียกใช้ก็ต่อเมื่อคำสั่ง `cd`หรือคำสั่งอื่น ๆ ส่งค่า "ผิดพลาด" (ค่าสถานะการออกไม่ใช่ศูนย์) ./do_something
การวนซ้ำ
การวนซ้ำ: บางครั้งโปรแกรมจะถูกทำซ้ำไปเรื่อยๆ หรือจนกว่าจะถึงผลลัพธ์ที่เฉพาะเจาะจง การดำเนินการคำสั่งแต่ละครั้งถือเป็น "การวนซ้ำ" [ 58 ]
- ในขณะที่จนกระทั่งและเลือกคำสั่งผสมลูป
- การคำนวณทางคณิตศาสตร์แบบ C และการแจงนับรายการสำหรับคำสั่งประกอบลูป และ
- คำสั่งควบคุมการไหลของโปรแกรม ได้แก่continue , break , returnและexit ;
คำสั่งผสม
สารประกอบ: สิ่งที่เกิดจากการรวมกันขององค์ประกอบหรือส่วนต่างๆ[ 59 ]
— พจนานุกรม Merriam-Webster's Collegiate
Bash ยังรองรับและรูปแบบของการประเมินคำสั่งแบบมีเงื่อนไข อีกด้วย [ c ]if...ficase...esac
การทดสอบ
คำสั่งในตัวสำหรับการทดสอบคุณสมบัติของไฟล์ การเปรียบเทียบค่าสตริงและจำนวนเต็ม ฯลฯ:
- คำสั่งทดสอบแบบดั้งเดิม
- การทดสอบวงเล็บเดี่ยวแบบดั้งเดิม:
[, - การตรวจวินิจฉัยด้วยเครื่องมือจัดฟันแบบคู่สมัยใหม่:
[[...]]ซึ่งรวมถึงคุณสมบัติขั้นสูงต่างๆ ดังนี้:- การจับคู่ แบบนิพจน์ปกติขยายและการจับคู่แบบ extglob
- การเปรียบเทียบเชิงพจนานุกรมกับ
<และ>;
((...))การประเมินและการทดสอบเชิงตัวเลข ซึ่งรวมถึงตัวดำเนินการเกือบทั้งหมดของภาษา "C" สำหรับการคำนวณทางคณิตศาสตร์และการเปรียบเทียบตัวเลข
สำหรับคำสั่งทั้งหมด สถานะการออกจะถูกเก็บไว้ในตัวแปร$?พิเศษ
นิพจน์ปกติ
Bash 3.0 รองรับการจับคู่ แบบนิพจน์ปกติภายในกระบวนการโดยใช้ไวยากรณ์ที่คล้ายกับPerl [ 61 ] การจับคู่แบบนิพจน์ ปกติ จำกัดเฉพาะสตริงทางด้านขวาของ=~ตัวดำเนินการใน[[..]]โครงสร้างการทดสอบแบบขยาย[ 62 ]
[[$line=~[[:space:]]*(a)?b]]หมายความว่าค่าสำหรับบรรทัดเช่น 'aab', 'aaaaaab', 'xaby' และ 'ab' จะตรงกันทั้งหมด เช่นเดียวกับบรรทัดที่มีตัวอักษร 'b' อยู่ที่ใดก็ได้ในค่าของมัน
กระบวนการร่วม
โคโปรเซสคือคำสั่งเชลล์ที่นำหน้าด้วยคำสงวน coproc โคโปรเซสจะถูกดำเนินการแบบอะซิงโครนัสในซับเชลล์ ราวกับว่าคำสั่งนั้นถูกยุติด้วยตัวดำเนินการควบคุม '&' โดยมีการสร้างไปป์สองทางระหว่างเชลล์ที่กำลังดำเนินการและโคโปรเซส[ 63 ]
— คู่มืออ้างอิง Bash, 3.2.6 กระบวนการร่วม (Coprocesses)
การจัดการข้อมูล
การแบ่งคำ
แยกออกเป็นคำ (เช่นการแยกคำ )
การอ้างอิง
เมื่อไม่แน่ใจ ให้อ้างอิง! [ 64 ]
— การเรียนรู้การเขียนสคริปต์เชลล์บนลินุกซ์ โดย แอนดรูว์ มาลเลตต์
Bash มีกฎ การอ้างอิง บางอย่าง: การใช้งานของ
- เครื่องหมายอัญประกาศเดี่ยว
'...' - เครื่องหมายอัญประกาศคู่
"..." - เครื่องหมายแบ็กสแลช
\และ $'...'การอ้างอิงแบบ ANSI-C
ดูเพิ่มเติมที่§ สถานที่ตั้ง$"..."
ดูเพิ่มเติมที่เครื่องหมายแบ็กติ๊ก`...`: § ไวยากรณ์ที่เลิกใช้แล้ว
ยูนิโค้ด
รองรับ การ เขียนอักขระUnicodeและการอ้างอิงแบบ ANSI-C echo-e
การขยายอุปกรณ์พยุง
$ echo kernel { ,-headers } kernel kernel-headers
การขยายวงเล็บปีกกา หรือที่เรียกว่าการสลับ เป็นคุณสมบัติที่คัดลอกมาจากเชลล์ Cโดยจะสร้างชุดค่าผสมทางเลือก[ 65 ] ผลลัพธ์ที่สร้างขึ้นไม่จำเป็นต้องมีอยู่ในไฟล์ ผลลัพธ์ของสตริงที่ขยายแต่ละรายการจะไม่ถูกจัดเรียง และลำดับจากซ้ายไปขวาจะถูกรักษาไว้:
$ echo a { p,c,d,b } e ape ace ade abe $ echo { a,b,c }{ d,e,f } ad ae af bd be bf cd ce cf
ผู้ใช้ไม่ควรใช้การขยายวงเล็บปีกกาในสคริปต์เชลล์แบบพกพา เนื่องจากเชลล์ Bourneไม่ได้สร้างเอาต์พุตแบบเดียวกัน
$ # เชลล์ bash $ /bin/bash -c 'echo a{p,c,d,b}e' ape ace ade abe $ # เชลล์แบบดั้งเดิมจะไม่แสดงผลลัพธ์เดียวกัน$ /bin/sh -c 'echo a{p,c,d,b}e' a{p,c,d,b}e
เมื่อขยายวงเล็บปีกกาพร้อมกับใช้สัญลักษณ์ตัวแทน (wildcard) วงเล็บปีกกาจะถูกขยายก่อน จากนั้นสัญลักษณ์ตัวแทนที่ได้จะถูกแทนที่ตามปกติ ดังนั้น การแสดงรายการภาพ JPEG และ PNG ในไดเร็กทอรีปัจจุบันจึงสามารถทำได้โดยใช้:
ls *. { jpg,jpeg,png } # ขยายเป็น *.jpg *.jpeg *.png – หลังจากนั้น# จะประมวลผลสัญลักษณ์ตัวแทนecho *. { png,jp { e, } g } # echo แสดงเฉพาะผลลัพธ์การขยาย – # และสามารถใช้เครื่องหมายวงเล็บปีกกาซ้อนกันได้
นอกเหนือจากการสลับกันแล้ว การขยายวงเล็บปีกกายังสามารถใช้สำหรับช่วงลำดับระหว่างจำนวนเต็มหรืออักขระสองตัวที่คั่นด้วยจุดสองจุดได้อีกด้วย Bash เวอร์ชันใหม่กว่าอนุญาตให้ใช้จำนวนเต็มตัวที่สามเพื่อระบุค่าเพิ่มขึ้น
$ echo { 1 ..10 } 1 2 3 4 5 6 7 8 9 10 $ echo { 01 ..10 } 01 02 03 04 05 06 07 08 09 10 $ echo file { 1 ..4 } .txt file1.txt file2.txt file3.txt file4.txt $ echo { a..e } abcde $ echo { 1 ..10..3 } 1 4 7 10 $ echo { a..j..3 } adgj
เมื่อการขยายวงเล็บปีกกาถูกรวมเข้ากับการขยายตัวแปร (หรือที่เรียกว่าการขยายพารามิเตอร์และการแทนที่พารามิเตอร์ ) การขยายตัวแปรจะดำเนินการหลังจากขยายวงเล็บปีกกา ซึ่งในบางกรณีอาจจำเป็นต้องใช้ ฟังก์ชัน evalในตัว ดังนี้:
$ start = 1 ; end = 10 $ echo { $start .. $end } # ไม่สามารถขยายได้เนื่องจากลำดับการประเมิน{1..10} $ eval echo { $start .. $end } # การขยายตัวแปรเกิดขึ้น จากนั้นจึงประเมินสตริงที่ได้1 2 3 4 5 6 7 8 9 10
การขยายเครื่องหมายทิลเด
การขยายพารามิเตอร์และตัวแปร
- พิมพ์
- พารามิเตอร์ของเชลล์
- ตัวแปรสิ่งแวดล้อม
- ตัวแปรผู้ใช้
- ขอบเขต
- อาร์เรย์
- อาร์เรย์แบบมีดัชนี: ขนาดไม่จำกัด
- อาร์เรย์แบบเชื่อมโยง : ผ่าน[ e ]
declare-A
- การขยายพารามิเตอร์
- ไวยากรณ์การขยายที่สามารถทำงานบางอย่างได้เร็วกว่ายูทิลิตี้ภายนอก ซึ่งรวมถึงสิ่งต่อไปนี้:
- การแทนที่รูปแบบ
${foo//x/y}สำหรับ,sed 's/x/y/g'
- ลบรูปแบบคำนำหน้าหรือคำต่อท้ายที่ตรงกัน
${bar##[a-zA-Z0-9]*}สำหรับcut -c8-,
- ระบุคีย์ของอาร์เรย์
${!array[@]}, และ
- แสดงข้อผิดพลาดหากเป็นค่าว่างหรือไม่ได้ตั้งค่า
${var:?error message},
การขยายเส้นทาง
การขยายเส้นทางไฟล์ เช่น การจับคู่ รูปแบบ และการจับคู่รูปแบบสไตล์เชลล์โดยใช้*, ?, [...]. [ f ]
สถานที่
การแปลเฉพาะพื้นที่โดยใช้$"..."ไวยากรณ์การอ้างอิง[ 69 ]
การเปลี่ยนเส้นทางกระบวนการและการแยกวิเคราะห์
การแทนที่คำสั่ง
การแทนที่คำสั่ง : , $(...)
การทดแทนกระบวนการ
การทดแทนกระบวนการหรือเมื่อระบบรองรับ: <()>()
Bash รองรับการแทนที่กระบวนการโดยใช้ ไวยากรณ์ `and` ซึ่งจะแทนที่เอาต์พุตของ (หรืออินพุตของ) คำสั่งในตำแหน่งที่ปกติแล้วจะใช้ชื่อไฟล์ (โดยจะดำเนินการผ่านทาง ไปป์ที่ไม่มีชื่อ `/proc/fd/`บนระบบที่รองรับ หรือผ่านไปป์ที่มีชื่อ ชั่วคราว เมื่อจำเป็น) <(command)>(command)
การขยายเลขคณิต
การขยายเลขคณิต((...))หรือรวมถึง $((...))
- การคำนวณเลขจำนวนเต็มในฐาน ใดๆ ตั้งแต่สองถึงหกสิบสี่ แม้ว่า
- การคำนวณเลขทศนิยมไม่สามารถใช้งานได้ภายในเชลล์โดยตรง (หากต้องการใช้งานฟังก์ชันนี้ โปรดดูเวอร์ชันปัจจุบันของbcและawkเป็นต้น)
Bash สามารถทำการคำนวณจำนวนเต็ม ("การประเมินค่าทางคณิตศาสตร์") โดยไม่ต้องสร้างกระบวนการภายนอก โดยใช้ ไวยากรณ์ ((...))คำสั่งและตัวแปรเพื่อจุดประสงค์นี้ $((...))
การเปลี่ยนเส้นทาง
มีการดำเนิน การเปลี่ยนเส้นทาง ของ สตรีมข้อมูลอินพุตมาตรฐาน เอาต์พุตมาตรฐาน และข้อผิดพลาดมาตรฐานรวมถึง:
- การเขียนไฟล์
>, และการเพิ่มไฟล์>>, - เอกสารเหล่า
<<นี้... - ในที่นี้มีสตริง
<<<ซึ่งอนุญาตให้ใช้พารามิเตอร์เป็นอินพุตได้ และ - ตัวดำเนินการเปลี่ยนเส้นทาง
>|ซึ่งสามารถบังคับให้เขียนทับไฟล์ได้เมื่อเปิดใช้งานการตั้งค่าnoclobber ของเชลล์
ไวยากรณ์ของมันทำให้ การเปลี่ยน เส้นทางการรับส่งข้อมูล (I/O redirection ) ง่ายขึ้น ตัวอย่างเช่น มันสามารถเปลี่ยนเส้นทางการรับส่งข้อมูลมาตรฐาน (stdout) และข้อผิดพลาดมาตรฐาน (stderr) พร้อมกันได้โดยใช้&>ตัวดำเนินการ `@directory` ซึ่งพิมพ์ง่ายกว่าคำสั่ง `@directory` ใน Bourne shell Bash รองรับเอกสาร here documentตั้งแต่เวอร์ชัน 2.05b เป็นต้นไป Bash สามารถเปลี่ยนเส้นทางการรับข้อมูลมาตรฐาน (stdin) จาก "here string" โดยใช้ตัวดำเนินการ `@directory` ได้ command>file2>&1<<<
การแยกวิเคราะห์คำสั่ง
- (ข) คำสั่งจะถูกแยกวิเคราะห์ทีละบรรทัด:
- โครงสร้างการควบคุมได้รับการเคารพ และ
- การใช้ เครื่องหมายแบ็กสแล
\ชเพื่อหลีกหนีก็สามารถใช้ได้ที่ท้ายบรรทัดเช่นกัน
- (ค) แยกเป็นคำ (เช่นการแยกคำ ) ตามกฎ การอ้างอิง
- รวมถึงการอ้างอิงตามมาตรฐาน ANSI-C
$'...'ด้วย
- รวมถึงการอ้างอิงตามมาตรฐาน ANSI-C
- (D) จะมีการขยายสตริงผลลัพธ์ เจ็ด ประเภท ตามลำดับดังต่อไปนี้:
- (ประเภทที่ 1)
kernel{-headers}การขยายอุปกรณ์พยุง - (ประเภทที่ 2)การขยายเครื่องหมายทิล
~เด - เรียงจากซ้ายไปขวา:
- (ประเภทที่ 3) การขยายพารามิเตอร์และตัวแปร
$fooหรือรวมถึง${bar} - (ประเภท 4) การแทนที่คำสั่ง : ,
$(...) - (ประเภทที่ 5) การทดแทนกระบวนการหรือเมื่อระบบรองรับ:
<()>() - (ประเภทที่ 6)การขยายเลขคณิต
((...))หรือรวมถึง$((...))- การคำนวณเลขจำนวนเต็มในฐาน ใดๆ ตั้งแต่สองถึงหกสิบสี่ แม้ว่า
- การคำนวณเลขทศนิยมไม่สามารถทำได้จากภายในเชลล์เอง[ g ]
- (ประเภทที่ 3) การขยายพารามิเตอร์และตัวแปร
- การแยกคำ (อีกครั้ง)
- (ประเภท 7)การขยายพาธเนม เช่นการจับคู่ รูปแบบ และการจับคู่รูปแบบ สไตล์เชลล์ โดยใช้
*,?, , [ f ][...] - การลบ เครื่องหมายคำพูด ;
- (ประเภทที่ 1)
- (E) มีการดำเนิน การเปลี่ยนเส้นทาง ของ สตรีมข้อมูลอินพุตมาตรฐาน เอาต์พุตมาตรฐาน และข้อผิดพลาดมาตรฐาน ซึ่งรวมถึง
- การเขียนไฟล์
>, และการเพิ่มไฟล์>>, - เอกสารเหล่า
<<นี้... - ในที่นี้มีสตริง
<<<ซึ่งอนุญาตให้ใช้พารามิเตอร์เป็นอินพุตได้ และ - ตัวดำเนินการเปลี่ยนเส้นทาง
>|ซึ่งสามารถบังคับให้เขียนทับไฟล์ได้เมื่อnoclobberเปิดใช้งานการตั้งค่า ของเชลล์
- การเขียนไฟล์
- (F) การค้นหาชื่อคำสั่งจะดำเนินการตามลำดับต่อไปนี้:
- คำสั่งภายในเชลล์ :
- ชื่อเรียกแทน ของเชลล์
- คำสงวนของเชลล์
- ฟังก์ชันเชลล์และ
- คำสั่งในตัวของเชลล์ ;
- คำสั่งภายนอกเชลล์:
- คำสั่งภายในเชลล์ :
- (G) สตริงที่ได้จะถูกดำเนินการเป็นคำสั่ง
คุณสมบัติแบบโต้ตอบเท่านั้น
ประวัติคำสั่ง
ประวัติคำสั่งขนาดไม่จำกัด[ 72 ] คุณสมบัตินี้ใช้งานได้เฉพาะในโหมดโต้ตอบ เท่านั้น
สแต็กไดเร็กทอรี
คุณสมบัติ การจัดเรียงไดเร็กทอรี ( pushdและpopdคุณสมบัติในตัว) สามารถใช้งานได้เฉพาะในโหมดโต้ตอบเท่านั้น
การเสร็จสิ้นตามโปรแกรม
หรือที่รู้จักกันในชื่อ "การเติมข้อความอัตโนมัติด้วยแท็บ" หรือ " การเติม ข้อความอัตโนมัติในบรรทัดคำสั่ง " เมื่อผู้ใช้กดปุ่ม ในเชลล์คำสั่งแบบโต้ตอบ Bash จะใช้สคริปต์การเติมข้อความอัตโนมัติที่มีอยู่เพื่อแนะนำชื่อโปรแกรม ชื่อไฟล์ และชื่อตัวแปรที่พิมพ์บางส่วนโดยอัตโนมัติ [ 73 ] [ 4 ]ระบบการเติมข้อความอัตโนมัติในบรรทัดคำสั่งของ Bash มีความยืดหยุ่นและปรับแต่งได้มาก และมักจะบรรจุมาพร้อมกับฟังก์ชันที่เติมอาร์กิวเมนต์และชื่อไฟล์สำหรับโปรแกรมและงานเฉพาะ Tab ↹
Bash รองรับการเติมข้อความ อัตโนมัติแบบโปรแกรมได้ผ่าน คำสั่งในตัวcomplete, compopt, และ[ 74 ] คุณสมบัตินี้มีให้ใช้งานตั้งแต่เวอร์ชันเบต้า 2.04 ที่วางจำหน่ายในปี 2000 [ 75 ] คำสั่งเหล่านี้ช่วยให้สามารถระบุการเติมข้อความอัตโนมัติที่ซับซ้อนและชาญฉลาดสำหรับคำสั่ง (เช่น โปรแกรมที่ติดตั้ง) ฟังก์ชัน ตัวแปร และชื่อไฟล์ได้[ 76 ]compgen
คำ สั่ง completeและcompoptสองคำสั่งระบุวิธีการแสดงรายการอาร์กิวเมนต์ของคำสั่งหรือตัวเลือกที่มีอยู่บางรายการใน อินพุต readlineตั้งแต่เวอร์ชัน 5.1 การเติมคำสั่งหรือตัวเลือกมักจะเปิดใช้งานโดยการกดแป้นพิมพ์หลังจากพิมพ์ชื่อ[ 76 ] คุณสมบัตินี้มีให้ใช้งานในโหมดโต้ตอบเท่านั้น Tab
ข้อความแจ้งเตือน
สามารถกำหนดค่าข้อความแจ้งเตือน ได้ คุณสมบัตินี้ใช้งานได้เฉพาะในโหมดโต้ตอบเท่านั้น
เอกสารประกอบ
คู่มือผู้ใช้
คู่มือผู้ใช้สำหรับ Bash จัดทำโดยโครงการ GNU บางครั้งถือว่าเป็นเอกสารที่เป็นมิตรกับผู้ใช้มากกว่าหน้า man "คุณอาจค้นหาข้อมูลเกี่ยวกับ Bash ... โดยการดูที่/usr/share/doc/bash, /usr/local/share/doc/bash, หรือไดเร็กทอรีที่คล้ายกันในระบบของคุณ" [ 77 ] บนระบบ GNU/Linux หาก มีโปรแกรม info เวอร์ชันคู่มือ GNU ที่เกี่ยวข้องกับการติด ตั้งของคุณควรมีอยู่ที่[ 78 ] [ 79 ]info bash
หน้าคู่มือ
คู่มือทางเทคนิคฉบับล่าสุด หรือ'man page'มีจุดประสงค์เพื่อเป็นเอกสารทางเทคนิคที่อธิบายวิธีการทำงานของ bash อย่างมีอำนาจ บนระบบ GNU/Linux เวอร์ชันที่เกี่ยวข้องกับการติดตั้งของคุณมักจะสามารถเข้าถึงได้ผ่านโปรแกรม manที่[ 78 ] [ 39 ] [ 80 ]manbash
ความช่วยเหลือในตัว
ใน Bash เวอร์ชันล่าสุด ข้อมูลเกี่ยวกับคำสั่งในตัวของเชลล์สามารถค้นหาได้โดยการเรียกใช้คำสั่งhelpหรือที่พรอมต์เทอร์มินัลที่มีการติดตั้ง Bash ไว้ help[nameofbuiltin]man builtins
คำ สั่ง printfสามารถเรียกใช้ผ่านenvเพื่อให้แน่ใจว่าคุณเรียกใช้โปรแกรมที่พบผ่านเส้นทางการค้นหาของเชลล์ ไม่ใช่นามแฝงของเชลล์หรือฟังก์ชันในตัว: . [ 81 ]envprintf--help
ข้อกำหนด POSIX
เพื่อวัตถุประสงค์ในการอนุญาตให้โปรแกรมเชลล์ต่างๆ ที่ทำงานบนระบบปฏิบัติการที่แตกต่างกันสามารถทำงานร่วมกันได้ข้อกำหนด POSIXจึงมีอิทธิพลต่อวิธีการเขียนเชลล์แบบ UNIX สมัยใหม่ Bash "มีจุดประสงค์เพื่อเป็นการใช้งานที่สอดคล้องกับ ส่วน "เชลล์และยูทิลิตี้"ของข้อกำหนด IEEE POSIX (มาตรฐาน IEEE 1003.1)" [ 82 ] เอกสารเผยแพร่ล่าสุดของมาตรฐาน (2024) มีให้บริการทางออนไลน์[ 83 ]
มาตรฐาน POSIX หรือ IEEE Std 1003.1 [ 84 ] เป็นต้นไป ซึ่งเป็นมาตรฐานที่ bash ใช้เป็นพื้นฐานนั้น มีประโยชน์อย่างยิ่ง
แหล่งข้อมูลเพิ่มเติม
"ผู้ดูแลโครงการยังมีหน้า Bash ซึ่งรวมถึงคำถามที่พบบ่อย" [ 77 ] [ 85 ] [ 86 ] FAQ นี้เป็นปัจจุบัน ณ เวอร์ชัน bash 5.1 และไม่ได้รับการอัปเดตอีกต่อไป
สามารถขอรับการสนับสนุนอย่างไม่เป็นทางการได้ทาง IRC ที่ libera.chat ในช่อง #bash และรายชื่อผู้รับจดหมายที่Bash - GNU Project - Free Software Foundation
ความปลอดภัยและช่องโหว่
สคริปต์รูท
การเรียกใช้สคริปต์เชลล์ใดๆ ในฐานะผู้ใช้ root นั้นถูกวิพากษ์วิจารณ์อย่างกว้างขวางมานานหลายปีแล้วว่าเป็นแนวทางปฏิบัติที่ไม่ปลอดภัย เหตุผลหนึ่งที่มักถูกกล่าวถึงคือ เมื่อสคริปต์ถูกเรียกใช้ในฐานะ root ผลกระทบเชิงลบของข้อผิดพลาดใดๆ ในสคริปต์จะถูกขยายให้ใหญ่ขึ้นเนื่องจากสิทธิ์ระดับสูงของ root
ตัวอย่างที่พบได้ทั่วไป: สคริปต์มีคำสั่งแต่ตัวแปรไม่ได้ถูกกำหนดค่าไว้ ในลินุกซ์ หากสคริปต์ถูกเรียกใช้โดยผู้ใช้ทั่วไป เชลล์จะพยายามเรียกใช้คำสั่งในฐานะผู้ใช้ทั่วไป และคำสั่งนั้นจะล้มเหลว อย่างไรก็ตาม หากสคริปต์ถูกเรียกใช้โดยผู้ใช้ root คำสั่งนั้นก็มีแนวโน้มที่จะสำเร็จและระบบไฟล์จะถูกลบ rm-rf${dir}/$dirrm -rf /
ขอแนะนำให้ใช้sudoในแต่ละคำสั่งแทน
สคริปต์ CGI
สคริปต์ CGI เป็นแหล่งที่มาของช่องโหว่ที่สำคัญ[ 87 ] [ 88 ] [ 89 ]
การประเมินในตัว
"คำสั่ง eval มีประสิทธิภาพอย่างมากและง่ายต่อการนำไปใช้ในทางที่ผิดอย่างมาก" [ 90 ]
การตรวจสอบความถูกต้องของข้อมูลป้อนเข้า
" การตรวจสอบความถูกต้องของข้อมูลขาเข้าคือกระบวนการตรวจสอบให้แน่ใจว่าข้อมูลได้ผ่านการทำความสะอาดข้อมูลแล้ว เพื่อยืนยันว่าข้อมูลมีคุณภาพ กล่าวคือ ข้อมูลนั้นถูกต้องและมีประโยชน์"
การตรวจสอบความถูกต้องของข้อมูลขาเข้าจะดำเนินการเพื่อให้แน่ใจว่ามีเพียงข้อมูลที่มีรูปแบบถูกต้องเท่านั้นที่เข้าสู่เวิร์กโฟลว์ในระบบสารสนเทศ ป้องกันไม่ให้ข้อมูลที่มีรูปแบบไม่ถูกต้องคงอยู่ในฐานข้อมูลและทำให้ส่วนประกอบปลายทางต่างๆ ทำงานผิดปกติ การตรวจสอบความถูกต้องของข้อมูลขาเข้าควรเกิดขึ้นโดยเร็วที่สุดเท่าที่จะเป็นไปได้ในกระแสข้อมูล โดยควรทำทันทีที่ได้รับข้อมูลจากฝ่ายภายนอก[ 91 ]
— เอกสารสรุปวิธีตรวจสอบความถูกต้องของข้อมูลขาเข้าตามมาตรฐาน OWASP
ช็อกจากการรบ
ในเดือนกันยายน พ.ศ. 2557 มีการค้นพบ ช่องโหว่ ด้านความปลอดภัย[ 92 ] ในโปรแกรม ช่องโหว่นี้ถูกตั้งชื่อว่า " Shellshock " การเปิดเผยต่อสาธารณะอย่างรวดเร็วนำไปสู่ การโจมตีต่างๆทั่วอินเทอร์เน็ต [ 93 ] [ 94 ] [ 95 ]
การใช้ประโยชน์จากช่องโหว่นี้อาจทำให้สามารถเรียกใช้โค้ดตามอำเภอใจใน สคริปต์ CGIที่สามารถเรียกใช้งานได้โดย Bash บางเวอร์ชัน ข้อบกพร่องนี้เกี่ยวข้องกับวิธีที่ Bash ส่งผ่านคำจำกัดความของฟังก์ชันไปยังซับเชลล์ผ่านตัวแปรสภาพแวดล้อม [ 96 ] ข้อบกพร่องนี้มีอยู่ในซอร์สโค้ดตั้งแต่เดือนสิงหาคม พ.ศ. 2532 (เวอร์ชัน 1.03) [ 97 ]และได้รับการแก้ไขในเดือนกันยายน พ.ศ. 2557 (เวอร์ชัน 4.3)
มีการปล่อยแพทช์แก้ไขข้อผิดพลาดออกมาในไม่ช้าหลังจากที่พบข้อผิดพลาด ขอแนะนำอย่างยิ่งให้ทำการอัปเกรดเป็นเวอร์ชันล่าสุด
ช่องโหว่นี้ได้รับการกำหนด รหัส ช่องโหว่ทั่วไป ( CVE) ได้แก่ CVE -2014-6271 , CVE- 2014-6277และ CVE- 2014-7169เป็นต้น ภายใต้เกณฑ์ CVSS Metrics 2.x และ 3.x ช่องโหว่นี้ถูกจัดอยู่ในระดับ "สูง" และ "วิกฤต" ตามลำดับ
ไวยากรณ์ที่เลิกใช้แล้ว
- การแทนที่คำสั่งแบบ backtick : ถือว่าล้าสมัยแล้ว[ 98 ]ให้ใช้แทน
`...`$(...);
- การใช้
-aor-oในคำสั่งtest/[/[[- ตัวอย่างเช่นถูกยกเลิกการใช้งานแล้ว และควรใช้แทน
[-r./file-a!-l./file][-r./file]&&![-l./file];
- ตัวอย่างเช่นถูกยกเลิกการใช้งานแล้ว และควรใช้แทน
- การใช้ไวยากรณ์ทางคณิตศาสตร์นั้นไม่แนะนำให้ใช้แล้ว ให้ใช้รูปแบบอื่นแทน
$[...]$((...))หรือ((...))ตามความเหมาะสม;
- การใช้
^เป็นไปป์ไลน์นั้นไม่แนะนำให้ใช้แล้ว ให้ใช้แทน|แทน - การใช้exprหรือlet ใดๆ ก็ตาม
การดีบัก
ตารางคุณสมบัติ
| คุณสมบัติ | POSIX 2024 | คำอธิบาย | เวอร์ชั่น Bash | ||
|---|---|---|---|---|---|
| ประเภทไวยากรณ์ | ชื่อทางการ | ไวยากรณ์ | |||
| ยูทิลิตี้ในตัวพิเศษ | ตั้งค่า / xtrace | set-x | ใช่ | วิธีการหลักในการดีบักของ เชลล์ "มันจะเขียนข้อมูลการติดตามสำหรับแต่ละคำสั่งลงในช่องข้อผิดพลาดมาตรฐาน หลังจากที่มันขยายคำสั่งนั้นแล้ว และก่อนที่จะดำเนินการคำสั่งนั้น" | ? |
| พารามิเตอร์พิเศษ | สถานะการออก | "$?" | ใช่ | "ขยายให้เป็นรูปแบบที่สั้นที่สุดของการแสดงสถานะการออกในระบบเลขฐานสิบ" | ? |
| การขยายพารามิเตอร์ | ระบุค่าว่างหรือไม่ได้ตั้งค่า | "${parameter:?[word]}" | ใช่ | "กรณีที่การขยายตัวของ[word]ข้อมูล เช่น ข้อความแสดงข้อผิดพลาดหรือหมายเลขบรรทัด ถูกเขียนลงในช่องข้อผิดพลาดมาตรฐาน และเชลล์ปิดตัวลงด้วยรหัสออกที่ไม่ใช่ศูนย์" | ? |
| พารามิเตอร์พิเศษ | PID ของเชลล์ที่ถูกเรียกใช้ | "$$" | ใช่ | "ขยายเป็นรูปแบบที่สั้นที่สุดของรหัสกระบวนการแบบทศนิยมของเชลล์ที่เรียกใช้" | ? |
| ยูทิลิตี้ในตัวพิเศษ | ตั้งค่า / แสดงรายละเอียด | set-v | ใช่ | "เขียนข้อมูลที่ป้อนเข้าไปลงในช่องข้อผิดพลาดมาตรฐานขณะที่อ่านข้อมูล" | ? |
| ยูทิลิตี้ในตัวพิเศษ | ตั้งค่า / ท่อล้มเหลว | set-opipefail | ใช่ | "กำหนดสถานะการออกจากไปป์ไลน์โดยพิจารณาจากสถานะการออกจากไปป์ไลน์ของคำสั่งทั้งหมดในไปป์ไลน์ ไม่ใช่แค่คำสั่งสุดท้าย (ขวาสุด) เท่านั้น" | ? |
| ยูทิลิตี้ในตัวพิเศษ | ชุด / ชุดคำนาม | set-u | ใช่ | เมื่อเปิดใช้งาน จะทำให้เชลล์ปิดตัวลงพร้อมข้อความแสดงข้อผิดพลาดเมื่อพบการขยายตัวแปรที่ไม่ได้กำหนดค่าไว้ การใช้งานนั้นมีข้อเสียที่คาดไม่ถึงอยู่หลายประการ | ? |
| ยูทิลิตี้ในตัวพิเศษ | ตั้งค่า / errexit | set-e | ใช่ | Errexit เป็นการตั้งค่าที่เมื่อเปิดใช้งานแล้ว จะทำให้เชลล์ปิดตัวลงโดยไม่มีข้อความแสดงข้อผิดพลาดเมื่อใดก็ตามที่เชลล์ได้รับรหัสการออกที่ไม่ใช่ศูนย์ ภายใต้เงื่อนไขเฉพาะบางประการ การใช้งาน Errexit นั้นค่อนข้างเป็นที่ถกเถียงกัน ในระดับเดียวกับที่โปรแกรมคอมพิวเตอร์ที่ไม่ค่อยเป็นที่รู้จักใดๆ ก็สามารถก่อให้เกิดข้อถกเถียงได้ ผู้สนับสนุนอ้างว่า Errexit ช่วยให้มั่นใจได้ถึงความสามารถในการตรวจสอบความถูกต้องในสถานการณ์ที่สคริปต์เชลล์ "ต้องไม่ล้มเหลว" อย่างไรก็ตาม ผู้ต่อต้านอ้างว่าการใช้งานนั้นไม่น่าเชื่อถือ เรียบง่ายอย่างหลอกลวง ขัดกับสัญชาตญาณอย่างมาก เต็มไปด้วยกับดักและข้อผิดพลาด และโดยพื้นฐานแล้วเป็นเพียง "การแสดงความปลอดภัย" นักพัฒนา Bash จำนวนมากได้ออกมาคัดค้านการใช้การตั้งค่านี้อย่างแข็งขัน | ? |
| ยูทิลิตี้ในตัวพิเศษ | กับดัก / ทางออก | trap'[arg]'EXIT | ใช่ | "ถ้าตัวระบุสัญญาณเป็น0หรือEXITจะ[arg]ถูกดำเนินการเมื่อเชลล์ปิดตัวลง" ถ้า[arg]มีส่วนขยายอยู่ภายใน[arg]ควรใส่เครื่องหมายอัญประกาศเดี่ยวครอบไว้ | ? |
| คุณประโยชน์ | พิมพ์เอฟ | printf'<%s>\n'"${var}" | ใช่ | วิธีการพิมพ์ค่าของตัวแปรอย่างน่าเชื่อถือ | ? |
| ตัวแปร Bash | บาชปิด | "${BASHPID}" | เลขที่ | "ขยายไปยังรหัสกระบวนการของกระบวนการ bash ปัจจุบัน" [ 100 ] | ? |
| ตัวแปร Bash | BASH_ARGC | "${BASH_ARGC[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีค่าเป็นจำนวนพารามิเตอร์ในแต่ละเฟรมของสแต็กการเรียกใช้งาน bash ในปัจจุบัน" [ 101 ] | ? |
| ตัวแปร Bash | บาช_อาร์จีวี | "${BASH_ARGV[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีพารามิเตอร์ทั้งหมดในสแต็กการเรียกใช้งาน bash ปัจจุบัน" [ 102 ] | ? |
| ตัวแปร Bash | บาช_ไลน์โน | "${BASH_LINENO[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีสมาชิกเป็นหมายเลขบรรทัดในไฟล์ต้นฉบับที่สมาชิกที่เกี่ยวข้องแต่ละตัวถูกเรียกใช้" [ 103 ]"${FUNCNAME[@]}" | ? |
| ตัวแปร Bash | แบช_รีแมตช์ | "${BASH_REMATCH[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีสมาชิกซึ่งถูกกำหนดโดย=~ตัวดำเนินการไบนารีให้กับ[[คำสั่งเงื่อนไข" [ 104 ] | ? |
| ตัวแปร Bash | แหล่งที่มาของ BASH | "${BASH_SOURCE[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีสมาชิกเป็นชื่อไฟล์ต้นฉบับซึ่งมีการกำหนดชื่อฟังก์ชันเชลล์ที่สอดคล้องกันในตัวแปรอาร์เรย์" [ 105 ]"${FUNCNAME[@]}" | ? |
| ตัวแปร Bash | BASH_XTRACEFD | "${BASH_XTRACEFD}" | เลขที่ | "หากตั้งค่าเป็นจำนวนเต็มที่สอดคล้องกับตัวระบุไฟล์ที่ถูกต้อง Bash จะเขียนเอาต์พุตการติดตามที่สร้างขึ้นเมื่อเปิดใช้งานไปยังตัวระบุไฟล์นั้น" [ 106 ]set-x | ? |
| ตัวแปร Bash | อีโปชเรียลไทม์ | "${EPOCHREALTIME}" | เลขที่ | "ทุกครั้งที่มีการอ้างอิงพารามิเตอร์นี้ มันจะขยายเป็นจำนวนวินาทีตั้งแต่ยุค Unix (ดู) เป็นค่าจุดลอยตัวที่มีความละเอียดระดับไมโครวินาที" [ 107 ]time(3) | ? |
| ตัวแปร Bash | ชื่อฟังก์ชัน | "${FUNCNAME[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีชื่อของฟังก์ชันเชลล์ทั้งหมดที่อยู่ในสแต็กการเรียกการดำเนินการในปัจจุบัน" [ 108 ] | ? |
| ตัวแปร Bash | ไลน์โน | "${LINENO}" | เลขที่ | "ทุกครั้งที่มีการอ้างอิงพารามิเตอร์นี้ เชลล์จะแทนที่ด้วยตัวเลขทศนิยมที่แสดงถึงหมายเลขบรรทัดลำดับปัจจุบัน (เริ่มต้นด้วย 1) ภายในสคริปต์หรือฟังก์ชัน" [ 109 ] | ? |
| ตัวแปร Bash | ไพเพสตาตัส | "${PIPESTATUS[@]}" | เลขที่ | "ตัวแปรอาร์เรย์ที่มีรายการค่าสถานะการออกของกระบวนการในไปป์ไลน์พื้นหน้าที่เพิ่งดำเนินการล่าสุด (ซึ่งอาจมีคำสั่งเดียว)" [ 110 ] | ? |
| ตัวแปร Bash | พีพีไอดี | "${PPID}" | เลขที่ | "รหัสกระบวนการของแม่ของเชลล์" [ 111 ] | ? |
| ตัวแปร Bash | พีเอส4 | "${PS4}" | เลขที่ | "ค่าของพารามิเตอร์นี้จะถูกขยายเช่นเดียวกับ PS1 และค่าจะถูกพิมพ์ก่อนคำสั่งแต่ละคำสั่งที่ bash แสดงในระหว่างการติดตามการดำเนินการ" [ 112 ] | ? |
| เชลล์บิวท์อิน | ตั้งค่า / จำกัด | set-r | เลขที่ | โหมดจำกัดมีจุดประสงค์เพื่อเพิ่มความปลอดภัยของอินสแตนซ์เชลล์แต่ละตัวจากการโจมตีของบุคคลที่ไม่ประสงค์ดีซึ่งสามารถเข้าถึงเครื่องได้โดยตรง เนื่องจากแบบจำลองภัยคุกคามมีการเปลี่ยนแปลงไป การใช้งานจึงลดลงกว่าแต่ก่อน | ? |
| เชลล์บิวท์อิน | shopt / extdebug | shopt-sextdebug | เลขที่ | "พฤติกรรมที่ออกแบบมาเพื่อใช้โดยโปรแกรมดีบักเกอร์" | ? |
| เชลล์บิวท์อิน | กับดัก / ดีบัก | trap'[arg]'DEBUG | เลขที่ | "หาก sigspec เป็น DEBUG คำสั่ง arg จะถูกดำเนินการก่อนคำสั่งบางประเภท" | ? |
| เชลล์บิวท์อิน | กับดัก / ข้อผิดพลาด | trap'[arg]'ERR | เลขที่ | "หาก sigspec เป็น ERR คำสั่ง arg จะถูกดำเนินการเมื่อใดก็ตามที่..." คำสั่งบางประเภท "ส่งคืนสถานะการออกที่ไม่ใช่ศูนย์" ซึ่งอยู่ภายใต้ข้อจำกัดที่คล้ายคลึงกับ ErrExit | ? |
| เชลล์บิวท์อิน | กับดัก / กลับ | trap'[arg]'RETURN | เลขที่ | "หาก sigspec เป็น RETURN พารามิเตอร์คำสั่งจะถูกเรียกใช้ทุกครั้งที่ฟังก์ชันเชลล์หรือสคริปต์ที่เรียกใช้ด้วย คำสั่ง .ภายในsourceทำงานเสร็จสิ้น" | ? |
- คุณสมบัติของเชลล์ที่กำหนดโดยPOSIX :
- คุณสมบัติของ Bash ที่ไม่ได้ระบุไว้ในมาตรฐาน POSIX:
- เครื่องมือช่วยแก้ไขข้อผิดพลาดจากผู้พัฒนาภายนอก:
ตัวอย่าง
ด้วยการขยายพารามิเตอร์ ตัวแปรที่ไม่ได้กำหนดค่าหรือเป็นค่าว่างอาจทำให้สคริปต์หยุดทำงานได้ "${var:?}"
$ cat ex.sh # !/bin/bash bar="foo ไม่ได้ถูกกำหนด" echo "${foo:?$bar}" echo ข้อความนี้ไม่แสดงผล$ ./ex.sh ./ex.sh: บรรทัดที่ 3: foo: foo ไม่ได้ถูกนิยามไว้$
การพิมพ์เนื้อหาของอาร์เรย์ที่มีช่องว่างและขึ้นบรรทัดใหม่ได้อย่างน่าเชื่อถือ โดยพิมพ์ในรูปแบบไวยากรณ์ที่พกพาได้ก่อน แล้วจึงพิมพ์ในรูปแบบเดียวกันใน Bash โปรดทราบว่า POSIX ไม่มีอาร์เรย์แบบมีชื่อ มีเพียงรายการอาร์กิวเมนต์เท่านั้นซึ่งสามารถตั้งค่าใหม่ได้โดยใช้ คำสั่ง setในตัว "$@"
# ในเชลล์ POSIX: $ set -- "a" " b" " > c " $ printf ',%s,\n' " $@ " ,a, , b, , c,
โปรดทราบว่าใน Bash จำนวนช่องว่างก่อนขึ้นบรรทัดใหม่จะถูกระบุไว้อย่างชัดเจน
# ใน Bash: $ array =( "a" " b" " > c " ) $ declare -p array declare -a array=([0]="a" [1]=" b" [2]=$' \nc ')
แสดงข้อความแสดงข้อผิดพลาดเมื่อเกิดปัญหา
$ cat error.sh # !/bin/env bash if ! lsblk | grep sdb then echo Error, line "${LINENO}" fi $ ./error.sh Error, line 130
ใช้xtraceหากเปิดใช้งาน errexit ไว้ คำสั่งนี้จะไม่ถูกเรียกใช้งาน echoquux
$ cat test.sh # !/bin/env bash set -x foo=bar; echo "${foo}" false echo quux $ ./test.sh + foo=bar + echo bar bar + false + echo quux quux
หมายเหตุ: $BASHPIDแตกต่างกัน$$ในบางสถานการณ์ เช่น ซับเชลล์ที่ไม่จำเป็นต้องเริ่มต้น bash ใหม่
$ echo $( echo $BASHPID $$ ) $$ $BASHPID 25680 16920 16920 16920 # | | | | # | | | \- - $ BASHPID นอกซับเชลล์# | | \ - - $$ นอกซับเชลล์# | \ - - $$ ภายในซับเชลล์# \ - - $BASHPIDภายในซับเชลล์
การรายงานข้อผิดพลาด
คำสั่งภายนอกที่เรียกว่าbashbugจะรายงานข้อบกพร่องของเชลล์ Bash เมื่อเรียกใช้คำสั่งนี้ จะแสดงตัวแก้ไขเริ่มต้นของผู้ใช้พร้อมแบบฟอร์มให้กรอก แบบฟอร์มนี้จะถูกส่งทางอีเมลไปยังผู้ดูแล Bash (หรืออาจส่งไปยังที่อยู่อีเมลอื่นก็ได้) [ 126 ] [ 127 ]
ประวัติศาสตร์
ฟังก์ชันสคริปต์เชลล์มีต้นกำเนิดมาจากไฟล์ที่เรียกว่า " runcoms " โดยอ้างอิงถึง ตัวประมวลผล มาโคร ในปี 1963 ที่มีชื่อเดียวกัน คำต่อท้าย "rc" ย่อมาจาก "runcom" [ 128 ] คำว่า"shell"ถูกบัญญัติโดย Louis Pouzin ในปี 1964 หรือ 1965 และปรากฏในบทความของเขาในปี 1965 เรื่อง "The SHELL, A Global Tool for Calling and Chaining Procedures in the System" ซึ่งอธิบายคุณสมบัติหลายอย่างที่พบในเชลล์ UNIX หลายตัวในภายหลัง[ 129 ] [ 130 ] มาตรฐานASCIIสำหรับการเข้ารหัสอักขระถูกกำหนดในปี 1969 ในเอกสารที่เรียกว่าRequest for Comments (RFC) 20 [ 131 ]
ไทม์ไลน์
เหตุการณ์สำคัญในประวัติศาสตร์ของ Bash มีดังต่อไปนี้:
| วันที่ | เหตุการณ์ |
|---|---|
| 10 มกราคม 1988 | Brian Foxเริ่มเขียนโค้ด Bash หลังจากที่Richard Stallmanไม่พอใจกับความคืบหน้าที่ล่าช้าของนักพัฒนาคนก่อน[ 132 ] Stallman และFSFพิจารณาว่าเชลล์ฟรีที่สามารถเรียกใช้สคริปต์เชลล์ที่มีอยู่ได้นั้นมีความสำคัญต่อระบบฟรีอย่างสมบูรณ์ที่สร้างขึ้นจากโค้ด BSD และ GNU ดังนั้นนี่จึงเป็นหนึ่งในไม่กี่โครงการที่พวกเขาให้ทุนสนับสนุนเอง Fox ทำงานนี้ในฐานะพนักงานของ FSF [ 132 ] [ 133 ] |
| 8 มิถุนายน 1989 | Fox ปล่อย Bash ออกมาเป็นเบต้า เวอร์ชัน 0.99 [ 134 ] ใบอนุญาตคือ GPL-1.0 หรือเวอร์ชันที่ใหม่กว่า “นอกเหนือจากการสนับสนุนความเข้ากันได้แบบย้อนหลังสำหรับการเขียนสคริปต์แล้ว Bash ยังได้รวมคุณสมบัติจากเชลล์ Korn และ C ไว้ด้วย คุณจะพบประวัติคำสั่ง การแก้ไขบรรทัดคำสั่ง สแต็กไดเร็กทอรี (pushd และ popd) ตัวแปรสภาพแวดล้อมที่มีประโยชน์มากมาย การเติมคำสั่งอัตโนมัติ และอื่นๆ อีกมากมาย” [ 135 ] ในที่สุดก็รองรับ “นิพจน์ปกติ (คล้ายกับ Perl) และอาร์เรย์แบบเชื่อมโยง” |
| 1991 | Bash มีความสำคัญทางประวัติศาสตร์ในฐานะที่เป็นหนึ่งในโปรแกรมแรกๆ ที่Linus Torvalds พอร์ตไปยัง Linux พร้อมกับคอมไพเลอร์ GNU ( GCC ) [ 136 ] |
| พ.ศ. 2535 - 2537 | Brian Fox เกษียณจากการเป็นผู้ดูแลหลักในช่วงกลางปี 1992 [ 137 ] และกลางปี 1994 [ 138 ] [ 139 ] ความรับผิดชอบของเขาถูกส่งต่อให้กับ Chet Ramey ผู้มีส่วนร่วมในช่วงแรกอีกคนหนึ่ง[ 85 ] [ 140 ] [ 7 ] [ 9 ] นับตั้งแต่นั้นมา Bash ก็กลายเป็นเชลล์แบบโต้ตอบเริ่มต้นที่ได้รับความนิยมมากที่สุดในบรรดาระบบปฏิบัติการ GNU/Linux หลักๆ เช่นFedora , DebianและopenSUSEรวมถึงระบบปฏิบัติการที่พัฒนาต่อยอดและคู่แข่งอื่นๆ ด้วย[ 141 ] [ 142 ] |
| 26 มกราคม 1994 | Debian – การเปิดตัวครั้งแรก Bash เป็นเชลล์แบบโต้ตอบและไม่โต้ตอบเริ่มต้น[ 143 ] |
| 31 ธันวาคม 1996 | Chet Ramey ได้ปล่อย bash เวอร์ชัน 2.0 ออกมา โดยใช้ลิขสิทธิ์ GPL-2.0 หรือเวอร์ชันที่ใหม่กว่า |
| 5 มิถุนายน 1997 | Bash เวอร์ชัน 2.01 เปิดตัวแล้ว |
| 18 เมษายน 1998 | Bash เวอร์ชัน 2.02 เปิดตัวแล้ว |
| 19 กุมภาพันธ์ 1999 | Bash เวอร์ชัน 2.03 เปิดตัวแล้ว |
| 21 มีนาคม 2543 | Bash เวอร์ชัน 2.04 เปิดตัวแล้ว |
| 14 กันยายน 2543 | รายชื่อผู้รับจดหมาย Bug-bash มีอยู่[ 144 ] |
| 9 เมษายน 2544 | Bash 2.05 ออกวางจำหน่ายแล้ว[ 145 ] |
| 2003 | Bash กลายเป็นเชลล์เริ่มต้นบนระบบปฏิบัติการของ Apple (เช่น MacOS) โดยเริ่มตั้งแต่ OS X 10.3 Panther [ 146 ] [ 147 ] นอกจากนี้ยังมีให้ใช้งานบน OS X 10.2 Jaguar ซึ่งเชลล์เริ่มต้นคือ tcsh |
| 27 กรกฎาคม 2547 | Bash 3.0 เปิดตัวแล้ว[ 148 ] |
| 9 ธันวาคม 2548 | Bash 3.1 ออกวางจำหน่ายแล้ว[ 149 ] |
| 12 ตุลาคม 2549 | Bash 3.2 ออกวางจำหน่ายแล้ว[ 150 ] ใบอนุญาตคือ GPL-2.0 หรือเวอร์ชันที่ใหม่กว่า |
| 2006 | Ubuntuเปลี่ยนจาก bash เป็น dash เป็นเชลล์เริ่มต้น |
| 2009-02-20 | Bash 4.0 ออกวางจำหน่ายแล้ว[ 151 ] ใบอนุญาตคือ GPL-3.0 หรือเวอร์ชันที่ใหม่กว่า |
| 2 มกราคม 2553 | Bash 4.1 ออกวางจำหน่ายแล้ว[ 152 ] |
| 14 กุมภาพันธ์ 2554 | Bash 4.2 ออกวางจำหน่ายแล้ว[ 153 ] |
| 2012 | บนSolaris 11 "เชลล์ผู้ใช้เริ่มต้นคือเชลล์ Bourne-again (bash)" [ 154 ] |
| 27 กุมภาพันธ์ 2557 | Bash 4.3 ออกวางจำหน่ายแล้ว[ 155 ] |
| 8 กันยายน 2014 | Shellshock (ข้อผิดพลาดของซอฟต์แวร์) [ 156 ] [ 157 ] แพ ตช์สำหรับแก้ไขข้อผิดพลาดได้รับการเผยแพร่ในไม่ช้าหลังจากที่พบข้อผิดพลาด[ 158 ] |
| 2015 | Termuxและแอปพลิเคชันจำลองเทอร์มินัลอื่นๆ ช่วยให้สามารถใช้งาน Bash บนAndroidได้ |
| 15 กันยายน 2559 | Bash เวอร์ชัน 4.4 เปิดตัวแล้ว |
| 2009 ~ 2018 | Apple ปฏิเสธที่จะยอมรับการอนุญาตใช้งาน Bash เวอร์ชัน 4 ภายใต้สัญญาอนุญาตใช้ งาน GNU GPLเวอร์ชัน 3 และยุติการจัดหาการอัปเกรด Bash ที่เกินกว่าเวอร์ชัน 3.2 (ซึ่งมีให้ในMacOS Mojave ) |
| 5 มิถุนายน 2019 | Apple ประกาศให้zshเป็นเชลล์เริ่มต้น[ 159 ] และจัดหาเวอร์ชัน 5.7 ในMacOS Catalina [ 160 ] [ 161 ] [ 162 ] |
| 7 มกราคม 2019 | Bash 5.0 เปิดตัวแล้ว[ 163 ] |
| 2020-12-07 | Bash 5.1 ออกวางจำหน่ายแล้ว[ 164 ] |
| 26 กันยายน 2022 | Bash เวอร์ชัน 5.2 เปิดตัวแล้ว |
| 2025 | Bash เวอร์ชัน 5.3 เปิดตัวแล้ว |
ดูเพิ่มเติม
- การเปรียบเทียบเชลล์คำสั่ง
- Multics § คำสั่ง , exec_com: ตัวประมวลผลคำสั่งตัวแรก
- ดาวน์โหลด FTP จากโครงการ GNU ของ Bash เวอร์ชัน 1.14.0 ถึงเวอร์ชันปัจจุบัน[ 165 ]
เชลล์ยูนิกซ์
- เปลือกหอยอัลมควิสต์ (เถ้า)
- เชลล์ Debian-Almquist (แดช)
- บอร์นเชลล์ (sh)
- บัสซี่บ็อกซ์
- ซีเชลล์ (csh)
- ปลา (เปลือกหอยที่เป็นมิตรและโต้ตอบได้)
- nsh – เชลล์บรรทัดคำสั่งเหมือน fish แต่เข้ากันได้กับ POSIX [ 166 ]
- Google Shell (goosh) – ส่วนติดต่อผู้ใช้แบบคล้าย UNIX สำหรับการค้นหาของ Google
- KornShell (ksh) – มีหลายรูปแบบ
- osh (Oil Shell) – เชลล์บรรทัดคำสั่ง UNIX ที่ใช้งานร่วมกับ Bash ได้ มีให้ใช้งานบนArch Linux
- เปลือกแผงวงจรพิมพ์ (เปลือก Mashey หรือ Programmer's Workbench)
- Qshell – สำหรับ IBM i
- rc – จากPlan 9
- รันคอม
- rush (Restricted User Shell) – มีให้บริการบนDebian [ 143 ]
- บานหน้าต่าง (กรอบหน้าต่าง) แบบตั้งเดี่ยว
- scsh (The Scheme Shell)
- tcsh (TENEX C shell)
- เปลือกหอยทอมป์สัน (tsh)
- กล่องของเล่น
- yash (Yet Another Shell) – มีเป้าหมาย "ที่จะเป็นเชลล์ที่สอดคล้องกับมาตรฐาน POSIX มากที่สุดในโลก" สามารถใช้งานได้บนArch Linux
- Z shell (zsh)
ส่วนติดต่อผู้ใช้แบบกราฟิกสำหรับสคริปต์
มีโปรแกรมมากมายที่ช่วยให้คุณสร้างส่วนติดต่อผู้ใช้แบบกราฟิกสำหรับสคริปต์เชลล์ได้
- curses - curses เป็นไลบรารีควบคุมเทอร์มินัลสำหรับระบบปฏิบัติการที่คล้าย Unix ซึ่งช่วยให้สามารถสร้างแอปพลิเคชันส่วนติดต่อผู้ใช้แบบข้อความ (TUI) ได้
- dialog - เป็นยูทิลิตี้ที่ช่วยให้คุณสร้างกล่องโต้ตอบในคอนโซล โดยใช้ไลบรารีcursesและncurses
- gtkdialog - เป็นยูทิลิตี้ที่มีฟังก์ชันการทำงานมากที่สุดสำหรับการสร้างแอปพลิเคชันกราฟิกบนสคริปต์ bash [ 167 ]
- kdialog - เทียบเท่ากับ KDE ของ zenity [ 168 ]
- ncurses - ไลบรารีการเขียนโปรแกรมสำหรับสร้างส่วนติดต่อผู้ใช้แบบข้อความ (TUI) ที่ใช้งานได้กับเทอร์มินัลหลากหลายประเภท
- whiptail - เป็นอนาล็อกของยูทิลิตี้ dialog โดยใช้ไลบรารีnewt [ 169 ]
- xdialog - เป็นโปรแกรมทดแทนdialogที่ออกแบบมาเพื่อให้โปรแกรมที่เรียกใช้งานจากเทอร์มินัลมีอินเทอร์เฟซระบบ X Window System
- yad - เป็นการแยกสาขาของ zenity โดยมีคุณสมบัติเพิ่มเติม[ 170 ]
- Zenityเป็นแอปพลิเคชันที่ได้รับความนิยมมากที่สุดสำหรับการสร้างอินเทอร์เฟซกราฟิกสำหรับสคริปต์[ 168 ] [ 171 ]
อ่านเพิ่มเติม
- [A]
- "คู่มือเบื้องต้นเกี่ยวกับการเขียนสคริปต์เชลล์" . apple.com . Apple . สืบค้นเมื่อ8 สิงหาคม 2025 .
ลิขสิทธิ์ © 2003, 2014 Apple Inc สงวนลิขสิทธิ์ทุกประการ ... อัปเดต: 10 มีนาคม 2014
- "คู่มือเบื้องต้นเกี่ยวกับการเขียนสคริปต์เชลล์" . apple.com . Apple . สืบค้นเมื่อ8 สิงหาคม 2025 .
- [จี]
- "คู่มือการเขียนโค้ด Shell" . github.io . Google . สืบค้นเมื่อ 8 สิงหาคม 2025 .
- [ชม]
- Stephenson, Neal (2003). ในตอนเริ่มต้น... คือบรรทัดคำสั่ง . HarperCollins. ISBN 978-0-380-81593-7.
- [ฉัน]
- M. Jones (9 ธันวาคม 2011). "วิวัฒนาการของเชลล์ในลินุกซ์: จาก Bourne ถึง Bash และอื่นๆ" . ibm.com . IBM . สืบค้นเมื่อ8 สิงหาคม 2025 .
- [ม]
- Pouzin, Louis (2 เมษายน 1965). "SHELL: เครื่องมือระดับโลกสำหรับการเรียกและการเชื่อมโยงขั้นตอนในระบบ" (PDF) . mit.edu . สถาบันเทคโนโลยีแมสซาชูเซตส์. สืบค้นเมื่อ8 สิงหาคม 2025 .
- [โอ]
- นิวแฮม, คาเมรอน; โรเซนแบลตต์, บิล. "เรียนรู้ Bash Shell, 2e" . oreilly.com . O'Reilly Media, Inc . สืบค้นเมื่อ8 สิงหาคม 2025 .
ตัวอย่างเนื้อหา
- นิวแฮม, คาเมรอน; โรเซนแบลตต์, บิล. "เรียนรู้ Bash Shell, 2e" . oreilly.com . O'Reilly Media, Inc . สืบค้นเมื่อ8 สิงหาคม 2025 .
- [U]
- "เอกสารอ้างอิงการเขียนสคริปต์ :: การเขียนสคริปต์ด้วย Bourne-Again Shell (Bash)" . berkeley.edu . มหาวิทยาลัยแคลิฟอร์เนีย เบิร์กลีย์. สืบค้นเมื่อ19 พฤษภาคม 2024 .
- "IRIS :: ระบบสารสนเทศเพื่อการเรียนการสอนและการวิจัย :: คำถามที่พบบ่อย: Unix :: เกี่ยวกับ UNIX Shells" . berkeley.edu . มหาวิทยาลัยแคลิฟอร์เนีย เบิร์กลีย์. สืบค้นเมื่อ8 สิงหาคม 2025 .
หมายเหตุ
- ^อย่าสับสนกับตัวแปรเชลล์
$$ - ^ a bสคริปต์เชลล์ไม่จำเป็นต้องคอมไพล์ก่อนเรียกใช้งาน และเมื่อตรงตามข้อกำหนดบางประการ ก็สามารถเรียกใช้เป็นคำสั่งได้โดยใช้ชื่อไฟล์
- ^แนวคิดที่ดึงมาจาก ALGOL 68 ; [ 60 ]
- ^ Bash 4 ยังเปลี่ยนใบอนุญาตเป็น GPL-3.0 หรือเวอร์ชันที่ใหม่กว่าด้วย
- ^ในเดือนกุมภาพันธ์ พ.ศ. 2552 [ 66 ] Bash 4.0 [ d ] [ 67 ] ได้แนะนำการสนับสนุนสำหรับอาร์เรย์แบบเชื่อมโยง [ 4 ] ดัชนีอาร์เรย์แบบเชื่อมโยงเป็นสตริง ในลักษณะที่คล้ายกับ AWKหรือ Tcl [ 68 ]สามารถใช้เพื่อจำลองอาร์เรย์หลายมิติได้
- ^ a bแม้ว่าจะสามารถใช้ร่วมกันได้ แต่การใช้วงเล็บในการจับคู่รูปแบบและการใช้วงเล็บในคำสั่งทดสอบนั้นเป็นสิ่งแตกต่างกัน
[...][[[ ... ]] - ^สำหรับฟังก์ชันนี้ โปรดดูเวอร์ชันปัจจุบันของ
bcและawkรวมถึงเวอร์ชันอื่นๆ ด้วย