**แบช** (อังกฤษ: bash: Bourne-again shell) เป็นเชลล์ยูนิกซ์ที่พัฒนาขึ้นสำหรับโครงการกนู ชื่อเต็มของโปรแกรมล้อเลียนเชลล์อีกตัวคือ บอร์นเชลล์ (Bourne shell) แบชเขียนมาใช้แทนบอร์นเชลล์ซึ่งเขียนขึ้นสำหรับยูนิกซ์เวอร์ชัน 7 โดย สตีเฟน บอร์น (Stephen Bourne) เมื่อประมาณ ค.ศ. 1978 ไบรอัน ฟอกซ์ (Brian Fox) เขียนแบชไว้เมื่อ ค.ศ. 1987 ตั้งแต่ ค.ศ. 1990 เป็นต้นมาผู้ดูแลพัฒนาหลักคือ เช็ต เรมี (Chet Ramey)
ในลีนุกซ์ส่วนใหญ่และในแมคโอเอสเท็นใช้แบชเป็นเชลล์มาตรฐาน แบชสามารถทำงานบนระบบปฏิบัติการยูนิกซ์และใกล้เคียง ยังปรับปรุงให้สามารถทำงานในไมโครซอฟท์วินโดวส์โดยโครงการ Cygwin และในดอสโดยโครงการ DJGPP ด้วย

รูปแบบคำสั่ง
------------

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

รูปแบบคำสั่งในแบชยังได้รับแนวความคิดจาก คอร์นเชลล์ (ksh) และ ซีเชลล์ (csh) เช่น การแก้ไขคำสั่ง จำคำสั่งเก่า ตัวแปร $RANDOM และ $PPID เป็นต้น เวลาใช้เป็นเชลล์ทางบรรทัดคำสั่ง แบชจะเติมชื่อโปรแกรม ชื่อไฟล์ ชื่อตัวแปร ให้ครบโดยอัตโนมัต เมื่อผู้ใช้กดปุ่ม TAB

ต่อไปนี้เป็นตัวอย่างรูปแบบคำสั่งที่เพิ่มเติมมาในแบชซึ่งบอร์นเชลล์ไม่มี

### การคำนวณเลขจำนวนเต็ม

แบชสามารถคำนวณตัวเลขจำนวนเต็มโดยไม่ต้องเรียกใช้โปรแกรมอื่น ในการคำนวณจะใช้คำสั่ง ((...)) หรือ $[...]

```
VAR=55            # กำหนดค่า 55 ให้กับตัวแปร VAR
((VAR = VAR + 1))   # บวกหนึ่งให้ตัวแปร VAR สังเกตว่าไม่ใช้อักษร '$'
((++VAR))              # อีกวิธีในการบวกหนึ่งให้กับ VAR
((VAR++))              # อีกวิธีในการบวกหนึ่งให้กับ VAR
echo $[VAR * 22]     # นำ VAR ไปคูณกับ 22 แล้วแทนที่ในคำสั่ง
echo $((VAR * 22))   # อีกวิธีในการนำ VAR ไปคูณกับ 22 แล้วแทนที่ในคำสั่ง
```

คำสั่ง ((...)) ยังใช้ในการตรวจสอบเงื่อนไข ว่าเป็นจริงหรือเท็จ เช่น

```
if ((VAR == Y * 3 + X * 2))
then
        echo Yes
fi

((Z > 23)) && echo Yes
```

สามารถใช้เงื่อนไข '==', '!=', '>', '<', '>=' และ '<=' ในคำสั่ง ((...))

แบชไม่สามารถคำนวณค่าเป็นจำนวนทศนิยมได้ มีเพียง คอร์นเชลล์ และ Z เชลล์ เท่านั้นที่ทำได้

### เปลี่ยนทิศทาง I/O

แบชมีรูปแบบคำสั่งหลายอย่างในการเปลี่ยนทิศทาง I/O ตัวอย่างเช่น ถ้าต้องการเปลี่ยน standard output (stdout) และ standard error (stderr) ไปเก็บในไฟล์ สามารถใช้รูปแบบ

```
command &> file
```

ซึ่งง่ายกว่าบอร์นเชลล์ที่ต้องพิมพ์ "command > file 2>&1"

ตั้งแต่รุ่น 2.05b เป็นต้นมา แบชสามารถดึงข้อความสตริงไปเข้า standard input (เรียกว่า "here documents" หรือ "heredocs") ได้ดังนี้

```
command << "สตริงที่ส่งไป standard input"
```

ถ้าในสตริงมีตัวอักษรช่องว่าง หรือตัวอักษรพิเศษอื่น ๆ ต้องใส่สตริงในเครื่องหมายคำพูด 

**ตัวอย่าง**:
Redirect standard output to a file, write data, close file, reset stdout

```
# สร้างไฟล์เดสคริปเทอร์ (Filedescriptor, FD) 6 ให้ชี้ไปยัง stdout (FD 1)
exec 6>&1
# เปลี่ยน stdout ให้เขียนลงไฟล์ "test.data" แทน
exec 1>test.data
# ใส่ข้อมูลในไฟล์
echo "data:data:data"
# ปิดไฟล์ "test.data"
exec 1>&-
# เปลี่ยน stdout ให้เหมือนกับ FD 6 (รีเซต stdout ให้กลับเหมือนเดิม)
exec 1>&6
# ปิด FD6
exec 6>&-
```

เปิดและปิดไฟล์

```
# เปิดไฟล์ test.data เพื่ออ่าน ใช้ FD 6
exec 6<test.data
# อ่านจนกว่าจะจบไฟล์
while read -u 6 dta
do
  echo "$dta" 
done
# ปิดไฟล์ test.data
exec 6<&-
```

เก็บผลลัพธ์ของคำสั่งภายนอก

```
 # รันโปรแกรม 'find' และเก็บผลลัพธ์ไว้ในตัวแปร VAR
 # ค้นหาไฟล์ที่ลงท้ายด้วยตัวอักษร "h"
 VAR=$(find. -name "*h")
```

### การตรวจสอบนพจน์ปรกติ

แบช 3.0 สนับสนุนการตรวจสอบนิพจน์ปรกติในตัวแบชเองโดยใช้รูปแบบคำสั่งที่คล้ายกับภาษาเพิร์ลดังนี้

```
[[string =~ regex]]
```

รูปแบบของนิพจน์ปรกติจะเหมือนกับที่กำหนดในหน้าแมนเพจ regex(7) ผลลัพธ์ที่ได้จะเป็น 0 ถ้าสายอักขระตรงกัน และเป็น 1 ถ้าไม่ตรงกัน ข้อความในวงเล็บภายในนิพจน์ปรกติสามารถอ่านได้จากตัวแปร BASH\_REMATCH ดังต่อไปนี้

```
if [[abcfoobarbletch =~ 'foo(bar)bl(.\*)']]
then
        echo ข้อความตรงกับที่ค้นหา\!
        echo $BASH_REMATCH      -- แสดง foobarbletch
        echo ${BASH_REMATCH[1]} -- แสดง bar
        echo ${BASH_REMATCH[2]} -- แสดง etch
fi
```

รูปแบบคำสั่งนี้ ทำงานมีประสิทธิภาพกว่าการรันโปรแกรม grep ต่างหาก ถ้าในนิพจน์ปรกติหรือสายอักขระมีตัวอักษรว่าง หรือตัวอักษรพิเศษ (เช่น '\*' หรือ '?') ต้องใส่ในเครื่องหมายคำพูด

### การแปลงแบ็คสแลช

ข้อความในรูป $'string' จะถูกจัดการเป็นพิเศษ ข้อความดังกล่าวจะถูกแปลงเป็นstring โดยที่ตัวอักษรที่ขึ้นต้นด้วยแบ็กสแลช (\) จะถูกแปลงตามที่กำหนดไว้ในภาษาซี ดังตารางต่อไปนี้

การแปลงข้อความ| ข้อความเดิม | แปลงเป็น |
| --- | --- |
| \a | ตัวอักษร alert หรือ bell |
| \b | ตัวอักษร backspace |
| \e | ตัวอักษร escape |
| \f | ตัวอักษร form feed |
| \n | ตัวอักษร new line |
| \r | ตัวอักษร carriage return |
| \t | ตัวอักษร horizontal tab |
| \v | ตัวอักษร vertical tab |
| \\ | ตัวอักษร \ |
| \' | ตัวอักษร ' |
| \nnn | ตัวอักษร 8 บิตที่มีเลขฐานแปดเป็น nnn (หนึ่งถึงสามหลัก) |
| \xHH | ตัวอักษร 8 บิตที่มีเลขฐานสิบหกเป็น HH (หนึ่งหรือสองหลัก) |
| \cx | ตัวอักษร control-X |

หลังจากแปลงแล้วข้อความจะอยู่ภายในเครื่องหมายคำพูด '...' เหมือนกับว่าไม่มีตัวอักษร $ อยู่

ข้อความตัวอักษรที่อยู่ภายใน $"..." จะถูกแปลตามโลเคล (locale) ปัจจุบัน ถ้าโลเคลปัจจุบันคือ C หรือ POSIX เครื่องหมายดอลลาร์จะไม่มีผล แต่ถ้าสตริงถูกแปลและแทนที่ ผลลัพธ์จะอยู่ในเครื่องหมายคำพูด "..."

สคริปเริ่มทำงาน
---------------

เมื่อแบชเริ่มทำงาน มันจะทำคำสั่งในสคริปเริ่มต้นต่าง ๆ กันแล้วแต่กรณี

ถ้าเรียกแบชเป็นเชลล์ล็อกอิน หรือเรียกโดยมีออปชัน --login มันจะไปค้นหา /etc/profile ตามด้วย ~/.bash\_profile, ~/bash\_login และ ~/.profile ตามลำดับ มันจะรันคำสั่งในไฟล์แรกที่มันพบและสามารถอ่านได้ สามารถสั่งให้แบชไม่รันคำสั่งโดยออปชัน --noprofile

ถ้าล็อกอินเชลล์จบการทำงาน แบชจะไปรันคำสั่งใน ~/.bash\_logout ถ้ามี

ถ้าเรียกแบชเป็นเชลล์โต้ตอบที่ไม่ใช้ล็อกอิน มันจะไปอ่านและรันคำสั่งใน ~/.bashrc ถ้ามี สามารถสั่งไม่ให้รันได้ด้วยออปชัน --norc และสั่งให้รันจากไฟล์ที่กำหนดด้วยออปชัน --rcfile

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

ถ้าเรียกแบชโดยใช้ชื่อ sh มันจะเลียนแบบการทำงานของบอร์นเชลล์มากที่สุดเท่าที่ทำได้ ตราบเท่าที่ยังเป็นตามมาตรฐาน POSIX เมื่อเป็นล็อกอินเชลล์หรือมีออปชัน --login มันจะไปหา /etc/profile และ ~/.profile ตามลำดับ และสามารถใช้ --noprofile เพื่องดการรันคำสั่งเริ่มต้น เมื่อไม่เป็นล็อกอินเชลล์ มันจะหาไฟล์ที่กำหนดโดยตัวแปร ENV และเมื่อเรียกเพื่อรันสคริปจะไม่รันคำสั่งเริ่มต้นเลย

ถ้าแบชทำงานในโหมด POSIX โดยใช้ออพชัน --posix จะรันคำสั่งจากไฟล์ที่ระบุใน ENV เท่านั้นเพื่อเป็นไปตามมาตรฐาน POSIX

แบชยังตรวจว่ามันถูกเรียกจาก remote shell daemon ซึ่งมักเป็น rshd หรือไม่ ถ้าใช่ ก็จะรันคำสั่งใน ~/.bashrc (ยกเลิกได้โดยออพชัน --norc และเปลี่ยนไฟล์โดยใช้ออพชัน --rcfile แต่ปกติ rshd มักไม่สามารถรันเชลล์โดยระบุออพชันเหล่านี้)

อ้างอิง
-------

* "Bash Reference Manual". สืบค้นเมื่อ 2008-06-21.

1. ↑  Ramey, Chet. "Bash - the GNU shell (Reflections and Lessons Learned)". คลังข้อมูลเก่าเก็บจากแหล่งเดิมเมื่อ 2005-03-29. สืบค้นเมื่อ 2008-01-15.

แหล่งข้อมูลอื่น
---------------

* เว็บเพจโปรแกรม bash เก็บถาวร 2006-08-13 ที่ เวย์แบ็กแมชชีน
* เว็บเพจ bash ของโครงการกนู