กลับไปหน้าบทความ

อ่าน 12 นาที

ซีเชลล์

C shell ( cshหรือเวอร์ชันปรับปรุงtcsh ) เป็นUnix shellที่สร้างโดยBill Joyขณะที่เขาเป็นนักศึกษาปริญญาโทที่มหาวิทยาลัยแคลิฟอร์เนีย เบิร์กลีย์ในช่วงปลายทศวรรษ 1970...

ซีเชลล์

ซีเชลล์
ผู้เขียนต้นฉบับบิล จอย
ปล่อยพ.ศ. 2521 ( 1978 )
เวอร์ชันสุดท้าย
8.2 / 10 ธันวาคม 2536 ( 10 ธันวาคม 1993 )
เขียนเป็นซี
ระบบปฏิบัติการBSD , ยูนิกซ์ , UNOS , ลินุกซ์ , macOS
ผู้สืบทอดtcsh
พิมพ์เชลล์ยูนิกซ์
ใบอนุญาตใบอนุญาต BSD
ที่เก็บข้อมูล
  • NetBSD (1.56 15/09/2022)
  • OpenBSD (1.51 2024/07/28)
C Shell ที่ทำงานบนWindows Services สำหรับ UNIX

C shell ( cshหรือเวอร์ชันปรับปรุงtcsh ) เป็นUnix shellที่สร้างโดยBill Joyขณะที่เขาเป็นนักศึกษาปริญญาโทที่มหาวิทยาลัยแคลิฟอร์เนีย เบิร์กลีย์ในช่วงปลายทศวรรษ 1970 มีการเผยแพร่อย่างกว้างขวาง โดยเริ่มจากเวอร์ชัน 2BSD ของBerkeley Software Distribution (BSD) ซึ่ง Joy เผยแพร่ครั้งแรกในปี 1978 [ 1 ] [ 2 ]ผู้มีส่วนร่วมในช่วงแรกในด้านแนวคิดหรือโค้ด ได้แก่ Michael Ubell, Eric Allman , Mike O'Brien และ Jim Kulp [ 3 ]

C shell คือโปรแกรมประมวลผลคำสั่งที่มักทำงานในหน้าต่างข้อความ ทำให้ผู้ใช้สามารถพิมพ์และเรียกใช้คำสั่งได้ C shell ยังสามารถอ่านคำสั่งจากไฟล์ที่เรียกว่าสคริปต์ได้ ด้วย เช่นเดียวกับ Unix shell อื่นๆ มันรองรับการใช้สัญลักษณ์ตัวแทน (wildcard) ในชื่อไฟล์การส่งข้อมูล ผ่านท่อ (piping ) เอกสาร here การ แทนที่คำ สั่ง ตัวแปรและโครงสร้างควบคุมสำหรับการทดสอบเงื่อนไขและการวนซ้ำสิ่งที่ทำให้ C shell แตกต่างจาก shell อื่นๆ โดยเฉพาะในช่วงทศวรรษ 1980 คือคุณสมบัติแบบโต้ตอบและรูปแบบโดยรวม คุณสมบัติใหม่เหล่านี้ทำให้ใช้งานง่ายและเร็วขึ้น รูปแบบโดยรวมของภาษามีลักษณะคล้ายกับภาษา C มากขึ้น และถูกมองว่าอ่านง่ายกว่า

ในระบบหลายๆ ระบบ เช่นmacOSและRed Hat Linuxนั้น csh จริงๆ แล้วคือtcshซึ่งเป็นเวอร์ชันที่ได้รับการปรับปรุงของ csh บ่อยครั้งที่ไฟล์ใดไฟล์หนึ่งจะเป็นฮาร์ดลิงก์หรือลิงก์สัญลักษณ์ไปยังอีกไฟล์หนึ่ง ดังนั้นชื่อใดชื่อหนึ่งจึงหมายถึงเวอร์ชันที่ได้รับการปรับปรุงของเชลล์ C เดียวกัน โค้ดต้นฉบับของ csh ที่อยู่ใน และไบนารี่เป็นส่วน หนึ่ง src/bin/csh/ของNetBSDและOpenBSD

บนDebianและระบบปฏิบัติการที่พัฒนาต่อยอดจาก Debian บางระบบ (รวมถึงUbuntu ) มีแพ็กเกจที่แตกต่างกันสองแบบคือ csh และ tcsh โดยแพ็กเกจแรกนั้นอิงตาม csh เวอร์ชัน BSD ดั้งเดิม[ 4 ] [ 5 ]และแพ็กเกจหลังคือ tcsh ที่ได้รับการปรับปรุง[ 6 ] [ 7 ]

tcsh เพิ่มการเติมชื่อไฟล์และคำสั่งอัตโนมัติ รวมถึงแนวคิดการแก้ไขบรรทัดคำสั่งที่ยืมมาจาก ระบบ Tenexซึ่งเป็นที่มาของ "t" [ 8 ]เนื่องจาก tcsh เพิ่มฟังก์ชันการทำงานเท่านั้นและไม่ได้เปลี่ยนแปลงสิ่งที่มีอยู่แล้ว จึงยังคงเข้ากันได้ กับ C shell ดั้งเดิม [ 9 ]แม้ว่าจะเริ่มต้นจากการเป็นสาขาแยกย่อยจากซอร์สโค้ดดั้งเดิมที่ Joy สร้างขึ้น แต่ปัจจุบัน tcsh เป็นสาขาหลักสำหรับการพัฒนาอย่างต่อเนื่อง tcsh มีความเสถียรมาก แต่ยังคงมีการออกเวอร์ชันใหม่ประมาณปีละครั้ง ซึ่งส่วนใหญ่ประกอบด้วยการแก้ไขข้อบกพร่องเล็กน้อย[ 10 ]

วัตถุประสงค์และคุณลักษณะของการออกแบบ

เป้าหมายหลักในการออกแบบ C shell คือการทำให้มีรูปลักษณ์คล้ายกับภาษาโปรแกรม C มากขึ้น และควรใช้งานได้ดีกว่าในรูปแบบการโต้ตอบ

น่าจะเป็น C มากกว่า

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

เมื่อพิจารณาตามมาตรฐานในปัจจุบัน C shell อาจดูไม่เหมือนภาษา C มากไปกว่าภาษาสคริปต์ยอดนิยมอื่นๆ แต่ในช่วงทศวรรษ 1980 และ 1990 ความแตกต่างนั้นถือว่าโดดเด่น โดยเฉพาะอย่างยิ่งเมื่อเปรียบเทียบกับBourne shell (หรือที่รู้จักกันในชื่อsh ) ซึ่งเป็นเชลล์ที่ได้รับความนิยมในขณะนั้น เขียนโดยStephen Bourneที่Bell Labs ตัวอย่างนี้แสดงให้เห็นถึง ตัวดำเนินการนิพจน์และ ไวยากรณ์แบบดั้งเดิมของ C shell

เปลือกบอร์น
#!/bin/sh if [ $days -gt 365 ] then echoนี่เกินหนึ่งปี แล้วfi

ซีเชลล์

#!/bin/csh ถ้า( $days > 365 ) แล้วechoนี่เกินหนึ่งปีแล้ว endif

Bourne sh ขาดไวยากรณ์การแสดงออกเงื่อนไขในวงเล็บเหลี่ยมต้องได้รับการประเมินโดยวิธีที่ช้ากว่าในการเรียกใช้ โปรแกรม ทดสอบ ภายนอก คำสั่ง ของ sh ifรับคำอาร์กิวเมนต์เป็นคำสั่งใหม่ที่จะทำงานเป็นกระบวนการลูกหากกระบวนการลูกจบด้วยรหัสส่งคืน เป็นศูนย์ sh จะมองหาthenข้อความ (คำสั่งแยกต่างหาก แต่มักจะเขียนรวมกันในบรรทัดเดียวกันด้วยเครื่องหมายเซมิโคลอน) และเรียกใช้บล็อกที่ซ้อนกันนั้น มิฉะนั้น มันจะเรียกใช้ else การเชื่อมโยงโปรแกรมทดสอบแบบฮาร์ดลิงก์ทั้งในรูปแบบ " test" และ " [" ทำให้ได้ข้อได้เปรียบเชิงสัญลักษณ์ของวงเล็บเหลี่ยมและลักษณะที่ดูเหมือนว่าฟังก์ชันการทำงานของการทดสอบเป็นส่วนหนึ่งของภาษา sh การใช้คำหลักแบบย้อนกลับของ sh เพื่อทำเครื่องหมายจุดสิ้นสุดของบล็อกควบคุมเป็นรูปแบบที่ยืมมาจากALGOL 68 [ 11 ]

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

ต่อไปนี้เป็นตัวอย่างที่สอง ซึ่งเปรียบเทียบสคริปต์ที่คำนวณเลขยกกำลัง 10 ตัวแรกที่หารด้วย 2 ลงตัว

เปลือกบอร์น
#!/bin/sh i = 2 j = 1 while [ $j -le 10 ] do echo '2 **' $j = $i i = ` expr $i '*' 2 ` j = ` expr $j + 1 ` done   
ซีเชลล์
#!/bin/csh set i = 2 set j = 1 while ( $j < = 10 ) echo '2 **' $j = $i @ i * = 2 @ j++ จบ

เนื่องจากไม่มีไวยากรณ์สำหรับแสดงนิพจน์ สคริปต์ sh จึงใช้การแทนที่คำสั่งและ คำสั่ง expr ( เชลล์ POSIX สมัยใหม่ มีไวยากรณ์ดังกล่าว: คำสั่งสามารถเขียนได้i=$((i * 2))เป็น หรือ: "$((i *= 2))")

สุดท้ายนี้ นี่คือตัวอย่างที่สาม ซึ่งแสดงให้เห็นถึงรูปแบบที่แตกต่างกันของการ ใช้คำสั่ง switch

เปลือกบอร์น
#!/bin/sh for i in d* do case $i in d? ) echo $i is short ;; * ) echo $i is long ;; esac done
ซีเชลล์
#!/bin/csh foreach i ( d* ) switch ( $i ) case d?: echo $i is short breaksw  default : echo $i is long endsw end

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

การปรับปรุงเพื่อการใช้งานแบบโต้ตอบ

วัตถุประสงค์ที่สองคือการปรับปรุง C shell ให้เหมาะสมกับการใช้งานแบบโต้ตอบมากขึ้น มีการเพิ่มคุณสมบัติใหม่มากมายที่ทำให้ใช้งานง่าย เร็วขึ้น และเป็นมิตรต่อ ผู้ใช้มากขึ้น โดยการพิมพ์คำสั่งที่เทอร์มินัล ผู้ใช้สามารถทำสิ่งต่างๆ ได้ด้วยการกดแป้นพิมพ์น้อยลงและทำงานได้เร็วขึ้น คุณสมบัติใหม่ที่สำคัญที่สุดเหล่านี้ได้แก่ กลไกประวัติและการแก้ไข นามแฝง สแต็กไดเร็กทอรี สัญกรณ์ทิลเด คำสั่ง cdpath การควบคุมงาน และการแฮชเส้นทาง คุณสมบัติใหม่เหล่านี้ได้รับความนิยมอย่างมาก และหลายอย่างถูกคัดลอกโดย Unix shell อื่นๆ ในเวลาต่อมา

ประวัติศาสตร์

ประวัติคำสั่งช่วยให้ผู้ใช้สามารถเรียกคำสั่งก่อนหน้าและเรียกใช้ซ้ำได้โดยการพิมพ์เพียงไม่กี่ครั้งอย่างรวดเร็ว ตัวอย่างเช่น การพิมพ์เครื่องหมายอัศเจรีย์สองตัว (" !!") [ 12 ]เป็นคำสั่งจะทำให้คำสั่งก่อนหน้าถูกเรียกใช้ทันที การรวมแป้นพิมพ์สั้นๆ อื่นๆ เช่น " !$" (หมายถึง "อาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้า") ช่วยให้สามารถนำส่วนต่างๆ ของคำสั่งก่อนหน้ามาวางรวมกันและแก้ไขเพื่อสร้างคำสั่งใหม่ได้

ตัวดำเนินการแก้ไข

การแก้ไขสามารถทำได้ไม่เฉพาะกับข้อความของคำสั่งก่อนหน้าเท่านั้น แต่ยังรวมถึงการแทนที่ตัวแปรด้วย ตัวดำเนินการมีตั้งแต่การค้นหา/แทนที่สตริงแบบง่าย ไปจนถึงการแยกวิเคราะห์พาธเนมเพื่อดึงส่วนเฉพาะออกมา

ชื่อเรียกอื่น

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

สแต็กไดเร็กทอรี

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

สัญกรณ์ทิลเด

สัญกรณ์ทิลเด (Tilde notation) เป็นวิธีการเขียนย่อในการระบุพาธที่สัมพันธ์กับไดเร็กทอรีหลักโดยใช้เครื่องหมาย " ~"

การเติมชื่อไฟล์อัตโนมัติ

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

ซีดีพาธ

คำสั่ง cdpath ขยายแนวคิดของเส้นทางการค้นหาไปยังcdคำสั่ง (เปลี่ยนไดเร็กทอรี): หากไดเร็กทอรีที่ระบุไม่อยู่ในไดเร็กทอรีปัจจุบัน csh จะพยายามค้นหาในไดเร็กทอรี cdpath

การควบคุมงาน

จนกระทั่งถึงช่วงทศวรรษ 1980 ผู้ใช้ส่วนใหญ่ยังคงใช้เทอร์มินัลแบบโหมดตัวอักษรอย่างง่าย ซึ่งไม่สามารถใช้งานหลายหน้าต่างพร้อมกันได้ ดังนั้นจึงสามารถทำงานได้เพียงครั้งละหนึ่งงานเท่านั้น ระบบควบคุมงานของ C shell ช่วยให้ผู้ใช้สามารถระงับกิจกรรมปัจจุบันและสร้างอินสแตนซ์ใหม่ของ C shell ซึ่งเรียกว่างาน โดยการพิมพ์คำสั่ง `c-json` ^Zจากนั้นผู้ใช้สามารถสลับไปมาระหว่างงานต่างๆ ได้โดยใช้fgคำสั่ง `c-json` งานที่กำลังทำงานอยู่จะเรียกว่าอยู่ในพื้นหน้า ส่วนงานอื่นๆ จะเรียกว่าถูกระงับ (หยุด) หรือกำลังทำงานอยู่ในพื้น หลัง

การแฮชเส้นทาง

การแฮชเส้นทางช่วยเพิ่มความเร็วในการค้นหาไฟล์ปฏิบัติการของเชลล์ C แทนที่จะเรียกใช้ระบบไฟล์ในแต่ละไดเร็กทอรีเส้นทางทีละรายการจนกว่าจะพบไฟล์หรือหมดความเป็นไปได้ เชลล์ C จะตรวจสอบตารางแฮช ภายใน ที่สร้างขึ้นโดยการสแกนไดเร็กทอรีเส้นทาง ตารางนั้นมักจะบอกเชลล์ C ได้ว่าไฟล์นั้นอยู่ที่ใด (ถ้ามีอยู่) โดยไม่ต้องค้นหา และสามารถรีเฟรชได้ด้วยrehashคำสั่ง

ภาพรวมของภาษา

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

คำแถลงพื้นฐาน

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

ในระดับประโยคพื้นฐาน ไวยากรณ์นี้มีลักษณะเด่นบางประการดังนี้:

การใช้ไวลด์การ์ด

เช่นเดียวกับเชลล์ Unix อื่นๆ เชลล์ C จะถือว่าอาร์กิวเมนต์บรรทัดคำสั่งใดๆ ที่มีอักขระตัวแทน (wildcard characters) เป็นรูปแบบ และแทนที่ด้วยรายการชื่อไฟล์ทั้งหมดที่ตรงกัน (ดูglobbing )

  • *สามารถจับคู่กับตัวอักษรได้ไม่จำกัดจำนวน
  • ?ตรงกับอักขระตัวเดียวใดๆ ก็ได้
  • [... ]ตรงกับอักขระใดๆ ก็ได้ที่อยู่ภายในวงเล็บเหลี่ยม อนุญาตให้ใช้ช่วงได้ โดยใช้เครื่องหมายขีดกลาง
  • [^... ]ตรงกับอักขระใดๆที่ไม่อยู่ในชุดที่กำหนดไว้

นอกจากนี้ เชลล์ C ยังได้นำเสนอความสะดวกในการเขียนสัญลักษณ์หลายอย่าง (บางครั้งเรียกว่าglobbing แบบขยาย ) ซึ่งต่อมาเชลล์ Unix อื่นๆ ก็ได้นำไปใช้ตาม

  • abc{def,ghi}เป็นการสลับ (หรือที่เรียกว่าการขยายวงเล็บปีกกา ) และขยายเป็นabcdef abcghi
  • ~หมายถึงโฟลเดอร์โฮมของผู้ใช้ปัจจุบัน
  • ~userหมายถึงโฟลเดอร์หลักของผู้ใช้

*/*.cรองรับการใช้ สัญลักษณ์ตัวแทนหลายตัวในระดับไดเร็กทอรี เช่น " "

ตั้งแต่เวอร์ชัน 6.17.01 เป็นต้นไป การใช้สัญลักษณ์ตัวแทนแบบเรียกซ้ำในzsh (เช่น " **/*.c" หรือ " ***/*.html") ก็ได้รับการสนับสนุนด้วยglobstarตัวเลือกดังกล่าว เช่นกัน

การมอบความรับผิดชอบในการตีความสัญลักษณ์ตัวแทน (wildcard) ให้กับเชลล์นั้นเป็นการตัดสินใจที่สำคัญในระบบ Unix หมายความว่าสัญลักษณ์ตัวแทนจะใช้งานได้กับทุกคำสั่ง และในลักษณะเดียวกันเสมอ อย่างไรก็ตาม การตัดสินใจนี้ขึ้นอยู่กับความสามารถของ Unix ในการส่งรายการอาร์กิวเมนต์ที่ยาวได้อย่างมีประสิทธิภาพผ่าน การเรียกใช้ระบบ execที่ csh ใช้ในการเรียกใช้คำสั่ง ในทางตรงกันข้าม ในWindowsการตีความสัญลักษณ์ตัวแทนมักจะดำเนินการโดยแต่ละแอปพลิเคชัน นี่เป็นมรดกจาก MS-DOS ซึ่งอนุญาตให้ส่งบรรทัดคำสั่งไปยังแอปพลิเคชันได้เพียง 128 ไบต์เท่านั้น ทำให้การใช้สัญลักษณ์ตัวแทนโดยพรอมต์คำสั่ง DOS ทำได้ไม่สะดวก แม้ว่าWindows รุ่นใหม่จะสามารถส่งบรรทัดคำสั่งที่มีอักขระ Unicodeได้มากถึงประมาณ 32K แต่ภาระในการตีความสัญลักษณ์ตัวแทนยังคงอยู่ที่แอปพลิเคชัน

การเปลี่ยนเส้นทางการรับส่งข้อมูล

โดยค่าเริ่มต้น เมื่อ csh รันคำสั่ง คำสั่งนั้นจะรับช่วงไฟล์แฮนเดิล stdio ของ csh สำหรับstdin , stdoutและstderrซึ่งโดยปกติแล้วจะชี้ไปยังหน้าต่างคอนโซลที่เชลล์ C กำลังทำงานอยู่ ตัวดำเนินการเปลี่ยนเส้นทางการรับส่งข้อมูลอนุญาตให้คำสั่งใช้ไฟล์แทนสำหรับการป้อนข้อมูลหรือแสดงผล

  • > fileหมายความว่าเอาต์พุตมาตรฐาน (stdout) จะถูกเขียนลงในไฟล์โดยจะเขียนทับไฟล์ที่มีอยู่แล้ว และจะสร้างไฟล์ใหม่หากไม่มีอยู่ ข้อผิดพลาดจะยังคงปรากฏในหน้าต่างเชลล์
  • >& fileหมายความว่าทั้ง stdout และ stderr จะถูกเขียนลงในไฟล์โดยจะเขียนทับไฟล์เดิมหากไฟล์นั้นมีอยู่แล้ว และจะสร้างไฟล์ใหม่หากไม่มีอยู่
  • >> fileหมายความว่าเอาต์พุตมาตรฐาน (stdout ) จะถูกเพิ่มต่อท้ายไฟล์
  • >>& fileหมายความว่าทั้ง stdout และ stderr จะถูกเพิ่ม ต่อท้ายไฟล์
  • < fileหมายความว่า stdin จะถูกอ่านจากไฟล์
  • << stringเป็นเอกสาร here document stdin จะอ่านบรรทัดต่อไปนี้จนถึงบรรทัดที่ตรงกับสตริง .

การเปลี่ยนเส้นทาง stderr เพียงอย่างเดียวเป็นไปไม่ได้หากปราศจากความช่วยเหลือจากซับเชลล์

set filter = "$home" '/filter' mkfifo "$filter" cat "$filter" & ( ( ls /root/ || echo No access. ) > "$filter" ) >& /dev/null 

ระบบที่รองรับตัวระบุไฟล์ในรูปแบบไฟล์ อาจใช้วิธีการแก้ไขปัญหาดังต่อไปนี้

( ( ( echo ok ; '' ) > /dev/fd/0 ) >& /dev/null < /dev/fd/1 ) | ( echo "$<" bye )

การเข้าร่วม

สามารถรวมคำสั่งต่างๆ ไว้ในบรรทัดเดียวกันได้

  • ;หมายความว่าให้รันคำสั่งแรกก่อน แล้วจึงรันคำสั่งถัดไป
  • &&หมายความว่าให้รันคำสั่งแรกก่อน และหากสำเร็จโดยมีรหัสส่งคืน เป็น 0 ให้รันคำสั่งถัดไป
  • ||หมายความว่าให้รันคำสั่งแรกก่อน และหากล้มเหลวโดยมีรหัสส่งคืนที่ไม่ใช่ศูนย์ ให้รันคำสั่งถัดไป

ท่อ

สามารถเชื่อมต่อคำสั่งต่างๆ โดยใช้ท่อ (pipe) ซึ่งจะทำให้ผลลัพธ์ของคำสั่งหนึ่งถูกส่งไปยังอินพุตของคำสั่งถัดไป คำสั่งทั้งสองจะทำงานพร้อมกัน

  • |หมายถึงการเชื่อมต่อ stdout กับ stdin ของคำสั่งถัดไป ข้อผิดพลาดยังคงปรากฏในหน้าต่างเชลล์
  • |&หมายความว่าให้เชื่อมต่อทั้ง stdout และ stderr เข้ากับ stdin ของคำสั่งถัดไป

การทำงานพร้อมกันหมายถึง "การทำงานแบบขนาน" ใน ระบบ มัลติคอร์ (โปรเซสเซอร์หลายตัว) คำสั่งที่ส่งผ่านทางไปป์อาจทำงานพร้อมกันจริงๆ มิเช่นนั้นตัวจัดตารางเวลาในระบบปฏิบัติการจะจัดสรรเวลาให้ระหว่างคำสั่งเหล่านั้น

เมื่อได้รับคำสั่ง เช่น " a | b" เชลล์จะสร้างไปป์จากนั้นเริ่มต้นทั้งaและbโดยเปลี่ยนเส้นทาง stdio สำหรับคำสั่งทั้งสอง เพื่อให้aเขียน stdout ของมันลงในอินพุตของไปป์ ในขณะที่bอ่าน stdin จากเอาต์พุตของไปป์ ไปป์ถูกใช้งานโดยระบบปฏิบัติการโดยมีบัฟเฟอร์จำนวนหนึ่ง เพื่อให้aสามารถเขียนได้ชั่วขณะก่อนที่ไปป์จะเต็ม แต่เมื่อไปป์เต็ม การเขียนใหม่ใดๆ จะถูกบล็อกภายในระบบปฏิบัติการจนกว่าจะbอ่านข้อมูลได้มากพอที่จะปลดบล็อกการเขียนใหม่ หากbพยายามอ่านข้อมูลมากกว่าที่มีอยู่ มันจะถูกบล็อกจนกว่าaจะเขียนข้อมูลเพิ่มเติมเสร็จ หรือจนกว่าไปป์จะปิด เช่น หากaออกจากโปรแกรม

การทดแทนตัวแปร

หากคำใดมีเครื่องหมายดอลลาร์ " $" อักขระที่ตามมาจะถูกนำมาใช้เป็นชื่อตัวแปร และการอ้างอิงจะถูกแทนที่ด้วยค่าของตัวแปรนั้น ตัวดำเนินการแก้ไขต่างๆ ที่พิมพ์เป็นส่วนต่อท้ายของการอ้างอิง จะช่วยให้สามารถแก้ไขเส้นทางไฟล์ (เช่น " :e" เพื่อแยกเฉพาะส่วนขยาย) และดำเนินการอื่นๆ ได้

การอ้างอิงและการหลีกเลี่ยง

กลไกการอ้างอิงช่วยให้สามารถใช้ตัวอักษรพิเศษ เช่น ช่องว่าง ตัวอักษรแทน วงเล็บ และเครื่องหมายดอลลาร์ เป็นข้อความ ตามตัวอักษรได้

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

เครื่องหมายอัญประกาศคู่ซ้อนเครื่องหมายอัญประกาศคู่ต้อง"\""ใช้เครื่องหมาย `\n` เพื่อหลีกเลี่ยงการขยายตัวแปร เช่นเดียวกับสัญลักษณ์ดอลลาร์ เพื่อป้องกัน การขยายตัวแปร "\$"สำหรับเครื่องหมายแบ็กติ๊ก เพื่อป้องกันการซ้อนของการแทนที่คำสั่ง ต้องใช้เครื่องหมาย"'\`'"อัญประกาศเดี่ยว

การแทนที่คำสั่ง

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

  • `คำสั่งนี้`หมายถึง นำเอาผลลัพธ์จากคำสั่งมาแยกวิเคราะห์เป็นคำพูด แล้ววางกลับเข้าไปในบรรทัดคำสั่ง

ต่อไปนี้เป็นตัวอย่างของการแทนที่คำสั่งแบบซ้อนกันโดยใช้Leaning toothpick syndrome :

เสียงสะท้อน"`เสียงสะท้อน " \"\` "เสียงสะท้อน " \"\\\"\\\`\" "เสียงสะท้อน " \"\\\"\\\\\\\"\\\\\\\`\\\"\" "เสียงก้อง " \"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\`\\\\\\\"\\\"\" "เสียงสะท้อน " \"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`\\\\\\\\\\\\\\"\\\\\\\"\\\"\" "pwd" \"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`\\\\\\\\\\\\\\\ \"\\\\\\\\\\\\\\\`\\\\\\\\\\\\\\"\\\\\\\"\\\\\\\`\\\\\\\"\\\"\\\`\\\"\"\`\" "`"

การดำเนินการเบื้องหลัง

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

  • คำสั่งนี้ &หมายถึงการเริ่มคำสั่งในพื้นหลังและจะพร้อมรับคำสั่งใหม่ทันที

ซับเชลล์

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

  • ( commands )หมายถึงการรันคำสั่งในซับเชลล์

โครงสร้างควบคุม

ภาษาซีเชลล์มีโครงสร้างควบคุมสำหรับทั้งการตรวจสอบเงื่อนไขและการวนซ้ำโครงสร้างควบคุมสำหรับการตรวจสอบเงื่อนไขคือคำสั่ง if และ switch ส่วนโครงสร้างควบคุมสำหรับการวนซ้ำคือคำสั่ง while, foreach และ repeat

คำสั่ง if

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

ถ้า(นิพจน์)คำสั่ง 

รูปแบบยาวใช้คีย์เวิร์ด then, else และ endif เพื่อให้สามารถซ้อนบล็อกคำสั่งไว้ภายในเงื่อนไขได้

ถ้า(นิพจน์ 1 ) แล้วคำสั่ง มิฉะนั้นถ้า(นิพจน์ 2 ) แล้วคำสั่ง ... คำสั่ง อื่น ๆendif

หากคำหลัก else และ if ปรากฏอยู่ในบรรทัดเดียวกัน csh จะเชื่อมโยงคำสั่งเหล่านั้นเข้าด้วยกันแทนที่จะซ้อนกัน และบล็อกจะสิ้นสุดด้วยคำสั่ง endif เพียงคำสั่งเดียว

คำสั่งสวิตช์

คำสั่ง switch จะเปรียบเทียบสตริงกับรายการรูปแบบ ซึ่งอาจมีอักขระตัวแทน (wildcard) หากไม่มีสิ่งใดตรงกัน ระบบจะดำเนินการตามการกระทำเริ่มต้น (ถ้ามี)

switch ( string ) case pattern1: คำสั่ง  รูปแบบ กรณีbreaksw 2: คำสั่ง เบรกสว ... ค่าเริ่มต้น : คำสั่ง แตกหักสิ้นสุด

ในขณะที่คำสั่ง

คำสั่ง whileจะประเมินนิพจน์ หากนิพจน์เป็นจริง เชลล์จะรันคำสั่งที่ซ้อนกัน จากนั้นจะทำซ้ำไปเรื่อยๆ ตราบใดที่นิพจน์ยังคงเป็นจริง

ในขณะที่(นิพจน์) คำสั่ง จบ

สำหรับแต่ละคำสั่ง

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

สำหรับตัวแปรวนซ้ำแต่ละตัว(รายการค่า) คำสั่ง จบ

ย้ำคำกล่าว

คำสั่ง repeat จะทำซ้ำคำสั่งเดียวเป็นจำนวนเต็มครั้ง

ทำซ้ำคำสั่งจำนวนเต็ม 

ตัวแปร

เชลล์ C ใช้ทั้งตัวแปรเชลล์และตัวแปรสภาพแวดล้อม [ 13 ] ตัวแปรสภาพแวดล้อมที่สร้างขึ้นโดยใช้setenvคำสั่ง จะเป็นสตริงธรรมดาเสมอ ซึ่งส่งผ่านไปยังกระบวนการลูก ใด ๆ ที่เรียกใช้ตัวแปรเหล่านี้ผ่านอาร์กิวเมนต์ envp[]ของmain()

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

ใน csh เวอร์ชันปัจจุบัน สตริงสามารถมีความยาวได้ตามต้องการ สูงสุดถึงหลายล้านตัวอักษร

สามารถขยายขนาดตัวแปรได้ตามต้องการ อย่างไรก็ตาม หากต้องการใช้งานกับขนาดคงที่ ควรใช้ไวยากรณ์ต่อไปนี้

# สร้างตัวแปรที่มีขนาดใหญ่พอที่จะเก็บองค์ประกอบได้ 1024 รายการset fixed = { , }{ , }{ , }{ , }{ , }{ , }{ , }{ , }{ , }{ , }{ , }

การแสดงออก

C shell ใช้ไวยากรณ์นิพจน์จำนวนเต็ม 32 บิต โดยมีตัวดำเนินการที่ยืมมาจากภาษา C แต่มีตัวดำเนินการเพิ่มเติมอีกเล็กน้อยสำหรับการเปรียบเทียบสตริงและการทดสอบระบบไฟล์ เช่น การทดสอบการมีอยู่ของไฟล์ ตัวดำเนินการต้องคั่นด้วยช่องว่างจากตัวถูกดำเนินการ ตัวแปรจะถูกอ้างอิงโดยใช้$ชื่อตัวแปร

ลำดับความสำคัญของตัวดำเนินการก็ยืมมาจากภาษา C เช่นกัน แต่มี กฎ การเชื่อมโยงตัวดำเนินการ ที่แตกต่างกัน เพื่อแก้ไขความกำกวมว่าอะไรมาก่อนในลำดับของตัวดำเนินการที่มีลำดับความสำคัญเท่ากัน ในภาษา C การเชื่อมโยงจะเป็นจากซ้ายไปขวาสำหรับตัวดำเนินการส่วนใหญ่ ใน C shell จะเป็นจากขวาไปซ้าย ตัวอย่างเช่น

// กลุ่ม C จากซ้ายint i = 10 / 5 * 2 ; printf ( "%d \n " , i ); // พิมพ์ 4 i = 7 - 4 + 2 ; printf ( "%d \n " , i ); // พิมพ์ 5 i = 2 >> 1 << 4 ; printf ( "%d \n " , i ); // พิมพ์ 16
# กลุ่มเชลล์ C จากทางขวา @ i = 10 / 5 * 2 echo $i # พิมพ์ 1 @ i = 7 - 4 + 2 echo $i # พิมพ์ 1 @ i = ( 2 >> 1 << 4 ) echo $i # พิมพ์ 0

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

ค่าที่ส่งคืนจะจำกัดอยู่ที่ 8 บิต สำหรับexitนิพจน์ สามารถใช้ตัวดำเนินการปฏิเสธเอกภาคเพื่อประเมินค่าแบบ 32 บิตได้

ออก  !! 256 # ส่งคืนค่า 1

แผนกต้อนรับ

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

ในปี พ.ศ. 2526 ทั้ง csh และ Bourne shell สามารถใช้งานได้กับ ระบบปฏิบัติการ UNOS ของ Charles River Data Systems รวมถึงเครื่องมือ UNIX อื่นๆ ภายใต้ใบอนุญาตของBell Laboratories [ 15 ]

ในตอนแรกและตลอดช่วงทศวรรษ 1980 ไม่สามารถรับประกันได้ว่า csh จะมีอยู่ในระบบ Unix และระบบที่คล้าย Unix ทั้งหมด แต่ sh นั้นมี ซึ่งทำให้เป็นตัวเลือกที่ดีกว่าสำหรับสคริปต์ใดๆ ที่อาจต้องทำงานบนเครื่องอื่นๆ ในช่วงกลางทศวรรษ 1990 csh มีให้ใช้งานอย่างแพร่หลาย แต่การใช้ csh สำหรับการเขียนสคริปต์ก็เผชิญกับคำวิจารณ์ใหม่จากคณะกรรมการPOSIX [ 16 ]ซึ่งระบุว่าควรมีเชลล์ที่ต้องการเพียงตัวเดียวคือKornShellสำหรับทั้งการใช้งานแบบโต้ตอบและการเขียนสคริปต์ เชลล์ C ยังเผชิญกับคำวิจารณ์จากผู้อื่น[ 17 ] [ 18 ]เกี่ยวกับข้อบกพร่องที่ถูกกล่าวหาของเชลล์ C ในด้านไวยากรณ์ คุณสมบัติที่ขาดหายไป และการใช้งานที่ไม่ดี

  • ข้อบกพร่องทางไวยากรณ์: โดยทั่วไปแล้วเป็นความไม่สอดคล้องกันที่เรียบง่ายแต่ไม่จำเป็นในคำจำกัดความของภาษา ตัวอย่างเช่น คำ สั่ง set, setenvและaliasต่างก็ทำหน้าที่เดียวกันโดยพื้นฐาน กล่าวคือ การเชื่อมโยงชื่อกับสตริงหรือชุดคำ แต่ทั้งสามคำสั่งมีความแตกต่างเล็กน้อยที่ไม่จำเป็น เครื่องหมายเท่ากับจำเป็นสำหรับคำสั่งsetแต่ไม่จำเป็นสำหรับ คำสั่ง setenvหรือaliasวงเล็บจำเป็นสำหรับรายการคำsetแต่ไม่จำเป็นสำหรับ คำสั่ง setenvหรือaliasเป็นต้น ในทำนองเดียวกัน โครงสร้างการวนซ้ำ if, switchและ ใช้คำหลักที่แตกต่างกันโดยไม่จำเป็น ( endif, endswและend) เพื่อยุติบล็อกที่ซ้อนกัน
  • คุณสมบัติที่ขาดหายไป: ที่ถูกกล่าวถึงบ่อยที่สุดคือ การขาดความสามารถในการจัดการ ไฟล์แฮนเดิล ของ stdioอย่างอิสระ และการสนับสนุนฟังก์ชัน แม้ว่าจะขาดการสนับสนุนฟังก์ชัน แต่การใช้นามแฝงก็เป็นวิธีแก้ปัญหาได้ สำหรับโค้ดหลายบรรทัด นามแฝงต้องอยู่ภายในเครื่องหมายอัญประกาศเดี่ยว และท้ายบรรทัดแต่ละบรรทัดต้องมีเครื่องหมายแบ็กสแลชนำหน้า (ท้ายบรรทัดสุดท้ายต้องมีเครื่องหมายอัญประกาศเดี่ยวนำหน้าเพื่อกำหนดขอบเขตของนามแฝง) การเรียกซ้ำเป็นวิธีที่เหมาะสมกว่าการใช้นามแฝงในสคริปต์เพื่อแก้ปัญหาเรื่องฟังก์ชัน (ตัวอย่างแสดงอยู่ด้านล่าง)
  • การนำไปใช้ซึ่งใช้ตัวแยกวิเคราะห์ แบบเฉพาะกิจ ได้รับการวิพากษ์วิจารณ์อย่างรุนแรงที่สุด ในช่วงต้นทศวรรษ 1970 เทคโนโลยีคอมไพเลอร์ มีความเป็นผู้ใหญ่มากพอ [ 19 ]ที่การนำภาษาใหม่ส่วนใหญ่มาใช้จะใช้ ตัวแยกวิเคราะห์แบบ บนลงล่างหรือล่างขึ้นบนที่สามารถรับรู้ไวยากรณ์แบบ เรียกซ้ำได้อย่างสมบูรณ์ ไม่เป็นที่ทราบแน่ชัดว่าเหตุใดจึงเลือกใช้การออกแบบแบบเฉพาะกิจแทนสำหรับเชลล์ C อาจเป็นเพราะอย่างที่จอยกล่าวไว้ในการสัมภาษณ์ในปี 2009 ว่า "ตอนที่ผมเริ่มทำสิ่งเหล่านี้กับ Unix ผมยังไม่ใช่โปรแกรมเมอร์ที่ดีนัก" [ 20 ]การออกแบบแบบเฉพาะกิจหมายความว่าภาษาเชลล์ C ไม่ใช่ภาษาแบบเรียกซ้ำอย่างสมบูรณ์ มีข้อจำกัดเกี่ยวกับความซับซ้อนของคำสั่งที่สามารถจัดการได้

มันใช้งานได้กับคำสั่งที่พิมพ์แบบโต้ตอบส่วนใหญ่ แต่สำหรับคำสั่งที่ซับซ้อนกว่าที่ผู้ใช้อาจเขียนในสคริปต์ มันอาจล้มเหลวได้ง่าย ทำให้เกิดข้อความแสดงข้อผิดพลาดที่เข้าใจยากหรือผลลัพธ์ที่ไม่พึงประสงค์ ตัวอย่างเช่น C shell ไม่รองรับการส่งข้อมูลผ่านไปป์ระหว่างโครงสร้างควบคุม การพยายามส่งเอาต์พุตของforeachคำสั่งไปยังgrepอีกโครงสร้างหนึ่งจึงใช้งานไม่ได้ (วิธีแก้ปัญหา ซึ่งใช้ได้ผลกับข้อร้องเรียนหลายอย่างที่เกี่ยวข้องกับตัวแยกวิเคราะห์ คือการแบ่งโค้ดออกเป็นสคริปต์แยกต่างหาก หากforeachย้ายไปยังสคริปต์แยกต่างหาก การส่งข้อมูลผ่านไปป์จะทำงานได้ เพราะสคริปต์จะทำงานโดยการสร้างสำเนาใหม่ของ csh ที่สืบทอดแฮนเดิล stdio ที่ถูกต้อง นอกจากนี้ยังสามารถแบ่งโค้ดในไฟล์เดียวได้ ตัวอย่างวิธีการแบ่งโค้ดในไฟล์เดียวแสดงไว้ด้านล่าง)

อีกตัวอย่างหนึ่งคือพฤติกรรมที่ไม่พึงประสงค์ในโค้ดส่วนต่อไปนี้ ทั้งสองส่วนดูเหมือนจะหมายความว่า "ถ้า 'myfile' ไม่มีอยู่ ให้สร้างมันขึ้นมาโดยการเขียน 'mytext' ลงไป" แต่เวอร์ชันทางด้านขวาจะสร้างไฟล์ว่างเสมอ เพราะลำดับการประเมินของ C shell คือการค้นหาและประเมินตัวดำเนินการเปลี่ยนเส้นทางการอ่าน/เขียน (I/O redirection operators) ในแต่ละบรรทัดคำสั่งขณะที่อ่าน ก่อนที่จะตรวจสอบส่วนที่เหลือของบรรทัดเพื่อดูว่ามีโครงสร้างควบคุมอยู่หรือไม่

# ทำงานได้ตามที่คาดไว้หาก( ! -e myfile ) แล้วให้แสดงข้อความของฉันแทนไฟล์ของฉัน จบเงื่อนไข 
# สร้างไฟล์เปล่าเสมอหาก( ! -e myfile ) echo mytext > myfile 
# วิธีแก้ปัญหาเฉพาะหน้า (สำหรับ tcsh เท่านั้น) ถ้า( ! -e myfile ) eval "echo mytext > myfile"
# วิธีแก้ปัญหาที่สอง (สำหรับ csh และ tcsh) ( exit ( -e myfile ) && ( ( echo mytext > myfile ) >& /dev/null || echoไม่สามารถสร้างไฟล์ได้) || echoไฟล์มีอยู่แล้ว 

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

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

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

#!/bin/csh -f set cmdlist = ( 'date # 1' \ 'uname # 2' \ 'tty # 3' \ 'id # 4' ) echo -n 'ป้อนหมายเลขเพื่อเรียกใช้คำสั่งจากประวัติ: ' set cmdexec = "$<" ( exit (  ! ( "$cmdexec" > 0 && \ "$cmdexec" < = "$#cmdlist" ) ) ) >& /dev/null if ( "$status" ) then echo 'หมายเลขเหตุการณ์ไม่ถูกต้อง' foreach cmd ( $cmdlist :q ) echo "$cmd" end exit -1 endif eval "$cmdlist[$cmdexec]"

ควรใช้วิธีการเขียนโค้ดแบบเรียกซ้ำเพื่อแก้ปัญหาเรื่องฟังก์ชันจะดีกว่า

#!/bin/csh -f if (  ! "$?main" ) then  if (  ! "$?0" ) then echo 'คุณต้องเรียกใช้สคริปต์นี้โดยการเรียกไฟล์โดยตรง' exit -1 endif alias function 'set argv = ( \!* ) ; source "$main"' set main = "$0" set ret = "`function myfunc`" echo "$ret" exit endifไปที่"$1" ; เลื่อน ฟังก์ชันของฉัน: ฟังก์ชัน myfunc2 echo "ฟังก์ชัน" exit มายฟังก์2: echo "ฟังก์ชันอื่น" exit

อิทธิพล

เชลล์ Hamilton Cแบบ 64 บิตบนเดสก์ท็อปWindows 7

C shell ประสบความสำเร็จอย่างมากในการนำเสนอนวัตกรรมมากมาย รวมถึงกลไกประวัติการใช้งานชื่อแทน (aliases)สั ญ กรณ์ทิลเด (tilde notation ) การเติมชื่อไฟล์แบบโต้ตอบ ไวยากรณ์นิพจน์ที่สร้างขึ้นใน shell และอื่นๆ อีกมากมาย ซึ่งต่อมาถูกคัดลอกโดย Unix shell อื่นๆ แต่ในทางตรงกันข้ามกับshซึ่งได้ก่อให้เกิดโคลนที่พัฒนาขึ้นอย่างอิสระจำนวนมาก รวมถึงkshและbash มีเพียง โคลนของ csh เพียงสองตัวเท่านั้นที่เป็นที่รู้จัก (เนื่องจากtcshมีพื้นฐานมาจากโค้ด csh ที่เขียนขึ้นโดย Bill Joy จึงไม่ถือว่าเป็นโคลน)

ในปี พ.ศ. 2529 Allen Holubได้เขียนหนังสือชื่อ On Command: Writing a Unix-Like Shell for MS-DOS [ 21 ]ซึ่งเป็นหนังสือที่อธิบายโปรแกรมที่เขาเขียนชื่อ "SH" แต่ในความเป็นจริงแล้ว โปรแกรมดังกล่าวได้คัดลอกการออกแบบภาษาและคุณสมบัติของ csh ไม่ใช่ sh แผ่นดิสก์ที่บรรจุซอร์สโค้ดฉบับเต็มของ SH และชุดยูทิลิตี้แบบ Unix พื้นฐาน (cat, cp, grep เป็นต้น) มีจำหน่ายในราคา 25 และ 30 ดอลลาร์ตามลำดับจากสำนักพิมพ์ โครงสร้างการควบคุม ไวยากรณ์การแสดงออก กลไกประวัติ และคุณสมบัติอื่นๆ ใน SH ของ Holub นั้นเหมือนกับของ C shell ทุกประการ

ในปี พ.ศ. 2531 Hamilton Laboratories เริ่มจัดส่งHamilton C shellสำหรับOS/2 [ 22 ] ซึ่งรวมถึงทั้งโคลน csh และชุดยูทิลิตี้แบบ Unix ในปี พ.ศ. 2535 Hamilton C shell ได้รับการเผยแพร่สำหรับWindows NT [ 23 ] เวอร์ชัน Windows ยังคงได้รับการสนับสนุนอย่างต่อเนื่อง แต่เวอร์ชัน OS/2 ถูกยกเลิกในปี พ.ศ. 2546 [ 23 ]เอกสารอ้างอิงฉบับย่อในช่วงต้นปี พ.ศ. 2533 [ 24 ] อธิบายถึงเจตนาว่า "การปฏิบัติตามภาษา C shell อย่างสมบูรณ์ (ยกเว้นการควบคุมงาน )" แต่มีการปรับปรุงการออกแบบภาษาและการปรับให้เข้ากับความแตกต่างระหว่าง Unix และพีซี การปรับปรุงที่สำคัญที่สุดคือตัวแยกวิเคราะห์แบบบนลงล่างที่อนุญาตให้โครงสร้างควบคุมซ้อนกันหรือส่งผ่านได้ ซึ่ง C shell ดั้งเดิมไม่สามารถรองรับได้เนื่องจากตัวแยกวิเคราะห์แบบเฉพาะกิจ Hamilton ยังเพิ่มคุณสมบัติภาษาใหม่ ๆ รวมถึงขั้นตอนในตัวและขั้นตอนที่ผู้ใช้กำหนด ตัวแปรโลคัลแบบบล็อกโครงสร้าง และเลขคณิตจุดลอยตัว การปรับให้เข้ากับพีซีรวมถึงการรองรับชื่อไฟล์และข้อกำหนดอื่นๆ บนพีซี และการใช้เธรดแทนการสร้างกระบวนการใหม่ (ซึ่งไม่มีใน OS/2 หรือ Windows) เพื่อให้เกิดการประมวลผลแบบขนานเช่น ในการตั้งค่าไปป์ไลน์

ในปี 2026 Tropibyte ได้ปล่อย C Shell สำหรับ Windows (cshw) ซึ่งเป็นการใช้งาน csh แบบเนทีฟสำหรับ Win32 ที่แจกจ่ายโดยไม่ต้องพึ่งพา Cygwin หรือ WSL เช่นเดียวกับ Hamilton C shell มันหลีกเลี่ยงการขนานแบบใช้ fork โดยใช้ coroutines และกลไกการซิงโครไนซ์ของ Windows แทน[ 25 ]

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • แอนเดอร์สัน, เกล; พอล แอนเดอร์สัน (1986). คู่มือภาคสนามเชลล์ C ของ UNIX . เพรนติส-ฮอลล์. ISBN 0-13-937468-X.
  • Wang, Paul (1988). An Introduction to Berkeley UNIX . Wadsworth Pub. Co. ISBN 0-534-08862-7.
  • DuBois, Paul (1995). การใช้ csh และ tcsh . O'Reilly & Associates. ISBN 1-56592-132-1.
  • Arick, Martin R. (1993). คู่มืออ้างอิง UNIX C Shell . John Wiley & Sons. ISBN 0-471-55680-7.
  • "บทนำสู่การเขียน โปรแกรมC Shell"ภาควิชาวิทยาการคอมพิวเตอร์ วิทยาลัยแคนิเซียส เก็บถาวรจากต้นฉบับเมื่อวันที่ 19 สิงหาคม 2554 เรียกดูเมื่อวันที่ 23 มิถุนายน 2553
  • บทนำเกี่ยวกับเชลล์ Cโดยวิลเลียม จอย
  • Linux ฉบับย่อ: บทที่ 8. csh และ tcsh
  • ซอร์สโค้ด csh ของ 2BSD ฉบับประวัติศาสตร์ลงวันที่ 2 กุมภาพันธ์ 1980
  • Unix Treeคือชุดการแจกจ่ายระบบปฏิบัติการ Unix ในอดีตทั้งหมด
  • การเขียนโปรแกรม Csh ถือว่าเป็นอันตราย
  • 10 เหตุผลสำคัญที่ไม่ควรใช้ C shell
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=C_shell&oldid=1355230400 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ซีเชลล์

C shell ( cshหรือเวอร์ชันปรับปรุงtcsh ) เป็นUnix shellที่สร้างโดยBill Joyขณะที่เขาเป็นนักศึกษาปริญญาโทที่มหาวิทยาลัยแคลิฟอร์เนีย เบิร์กลีย์ในช่วงปลายทศวรรษ 1970...

วัตถุประสงค์และคุณลักษณะของการออกแบบ

เป้าหมายหลักในการออกแบบ C shell คือการทำให้มีรูปลักษณ์คล้ายกับ ภาษาโปรแกรม C มากขึ้น และควรใช้งานได้ดีกว่าในรูปแบบการโต้ตอบ

น่าจะเป็น C มากกว่า

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

การปรับปรุงเพื่อการใช้งานแบบโต้ตอบ

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