เป็นโปรแกรม "ถ้า" และ "แล้ว" ที่จริงแล้ว


15

ฉันอ่านว่าใช้เครื่องหมายอัฒภาคเพื่อคั่นโปรแกรม:

$ echo 3; ls -la

มันหมายความว่าอย่างนั้นifหรือthenและelseเป็นโปรแกรมแยกต่างหากที่นี่

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

คำถามนี้ไม่เกี่ยวกับเครื่องหมายอัฒภาค



1
@StephenRauch ไม่ได้ซ้ำกันจริงๆ ยิ่งกว่านั้นเป็นผลพลอยได้ที่สมเหตุสมผลจากความพยายามนั้นเพื่อทำความเข้าใจเพิ่มเติม
user207673

สูตร programm-y เพิ่มเติม:[ $variable == abcdef ] && echo yes || echo no
Hagen von Eitzen

2
@ HagenvonEitzen ที่ไม่เทียบเท่ากันอย่างเคร่งครัดหากคำสั่งภายในสาขาแรกล้มเหลวที่สองจะดำเนินการ
Morgen

คำตอบ:


26

;งบแยก (พูดอย่างอิสระ) เป็นไปได้ (เกือบ) เสมอที่จะแทนที่;โดยขึ้นบรรทัดใหม่

เพื่อบอกว่า;แยกสองโปรแกรมดังนั้นifและthenจะต้องเป็น "โปรแกรม" นั้นเรียบง่ายไปหน่อยเนื่องจากคำสั่งอาจทำจากคำสงวนฟังก์ชันเชลล์ฟังก์ชันยูทิลิตี้ในตัวและยูทิลิตี้ภายนอกในตัว . ฯลฯ

ทั้งสองifและthenเป็นคำที่สงวนไว้ในไวยากรณ์เชลล์ไม่ใช่ "โปรแกรม" ที่นี่พวกเขาจะใช้ในการสร้างสิ่งที่เรียกว่าเทคนิคคำสั่งผสม

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


7

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

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

if, then, elseและfiมีทุกคำสงวน พวกเขามีความหมายโดยเฉพาะอย่างยิ่งเมื่อมีการแยกการป้อนข้อมูลที่หนึ่งให้กับเปลือกตามของไวยากรณ์ ในทำนองเดียวกัน;คือแยกผู้ประกอบการ

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

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

echoอีกโปรแกรมที่คล้ายกันมีชื่ออยู่ในคำถามของคุณ อีกครั้งเชลล์ส่วนใหญ่มีโปรแกรมนี้ในตัว แต่อีกครั้งยังมีรุ่นภายนอกของโปรแกรมบางแห่งเช่น/bin/echoหรือ/usr/bin/echoเพื่อให้โปรแกรมอื่นที่ไม่ใช่เชลล์เรียกใช้

lsโปรแกรมที่สามชื่อในคำถามของคุณคือ เปลือกหอยโดยทั่วไปจะไม่ได้สร้างขึ้นในรุ่นของโปรแกรมนี้และมันเป็นโปรแกรมภายนอกจะพบที่ไหนสักแห่งเช่นหรือ/bin/ls/usr/bin/ls

สำหรับเชลล์ Bourne Again คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสิ่งนี้ได้ในคุณสมบัติเชลล์ขั้นพื้นฐานของเอกสารข้อมูลเชลล์ GNU Bourne Again เปลือกหอยอื่น ๆ มีไวยากรณ์ที่แตกต่างกันตามธรรมชาติ สเปก Unix เดี่ยวอธิบายไวยากรณ์ว่าทุกเปลือก POSIX สอดคล้อง (ในโหมด POSIX สอดคล้องของพวกเขา) ควรจะเป็นไปตาม

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

  • " ไวยากรณ์ของเชลล์ " เชลล์ภาษาคำสั่ง ข้อกำหนดเฉพาะพื้นฐานปัญหาที่ 7 กลุ่มที่เปิด IEEE 1003.1-2008 ไอ 1937218812
  • test. ยูทิลิตี้ ข้อกำหนดเฉพาะพื้นฐานปัญหาที่ 7 กลุ่มที่เปิด IEEE 1003.1-2008 ไอ 1937218812
  • " ไวยากรณ์ของเชลล์ " คู่มือการใช้งาน Z เชลล์ รุ่น 5.3.1 2017

5

จริงๆแล้วมันเป็นเรื่องที่ไม่ไกลเกินเอื้อมที่จะคิด if , thenและelseเป็นโปรแกรมภายนอก ในความเป็นจริงแล้วเชลล์ ธ อมป์สันใน Unix รุ่นที่ 1 ได้ติดตั้งifและgotoเป็นโปรแกรมภายนอก สิ่งนี้เป็นไปได้เนื่องจากตัวประมวลผลย่อยแบ่งใช้ตัวอธิบายไฟล์ด้วยกระบวนการเชลล์ดังนั้น goto (ไปข้างหน้า) จึงต้องอ่านอินพุตจนกว่าจะพบเลเบลเป้าหมายแล้วออก ดูทอมป์สันเปลือก


หรืออันที่จริงเห็นองค์ Bercot ของifและซึ่งเป็นส่วนหนึ่งของifelse execlineสิ่งเหล่านี้ไม่ใช่ifคำถาม
JdeBP

2
"จริงๆแล้วมันไม่ได้ไกลเกินกว่าที่จะคิดว่าถ้าอย่างนั้นและอื่น ๆ ที่เป็นโปรแกรมภายนอก"ก็เป็นเพราะพวกเขาไม่ได้
การแข่งขัน Lightness กับโมนิก้า

2

thenและelseไม่ได้โปรแกรม ส่วนอื่น ๆ คือ สังเกตว่าไม่มี;'อยู่ข้างหลังพวกเขาโดยตรง แต่หลังจากคำสั่งพวกมันนำหน้า

[ ... ] เป็นคำสั่งและความต้องการ;ถ้าตามด้วยจุดเริ่มต้นของคำสั่งอื่น

AFAIK โครงสร้างการควบคุมทั้งหมดใน Bash และกระสุน nix ส่วนใหญ่น่าจะเหมือนกัน มีคำแนะนำให้ล่าม ในทางกลับกันการทดสอบหรือเงื่อนไขนั้นใช้โปรแกรม / กระบวนการที่ "เรียกใช้งาน" และเป็นคำสั่ง เนื่องจากthenเป็นส่วนหนึ่งของเส้นที่นำไปสู่echo[ ... ]คำสั่งจะต้องมีการแยกจากกันโดยขึ้นบรรทัดใหม่จากคำสั่งก่อนหน้า echo yesมันไม่จำเป็นที่จะต้องแยกออกจากคำสั่งควบคุมการ

ถูกกฎหมายแม้ว่าจะน่าเกลียดและอ่านยาก แต่คุณก็สามารถทำได้

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

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

ที่น่าสนใจพอที่โครงสร้างการควบคุมทั้งหมด ( if ... fi) ;เป็นคำสั่งของเชลล์และครบถ้วนได้จบลงด้วยการขึ้นบรรทัดใหม่หรือ บรรทัดสุดท้ายไม่สามารถเป็นได้fi echo donefi; echo doneแต่ต้อง เช่นเดียวกับการมอบหมายVARIABLE='abcdef'เป็นคำสั่ง

แม้ว่าโครงสร้างการควบคุมทั้งหมดจะเป็นคำสั่ง แต่ก็ยังไม่ใช่โปรแกรม


1

if, elif, thenและfiเป็นคำหลักที่สงวนไว้ทั้งหมดที่ใช้ในการดำเนินการอย่างใดอย่างหนึ่งของโครงสร้างที่อ้างว่าเป็นคำสั่งสารประกอบในเปลือกซึ่งหมายความว่าไม่สามารถมีคำสั่ง (หรือมากกว่าคำสั่งอื่น) โดยใด ๆ ของชื่อผู้ที่อยู่ในเปลือก วัตถุประสงค์ของการ;โดยทั่วไปไม่ได้ที่จะแยกออกคำสั่ง แต่จะยุติคำสั่งรายการ ตัวอย่างเช่นต่อไปนี้เป็นifคำสั่งที่ถูกต้อง:

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

เงื่อนไขของคำสั่งคือรายการคำสั่งif echo foo; echo bar; echo bazตัวแยกวิเคราะห์รู้ว่าเงื่อนไขสิ้นสุดลงthenแล้วซึ่งตามหลังเซมิโคลอนทันทีไม่สามารถเป็นคำสั่งได้เนื่องจากเป็นคำหลักที่สงวนไว้ ดังนั้นจึงรู้ว่าสิ่งต่อไปนี้ thenคือจุดเริ่มต้นของร่างกาย ในทำนองเดียวกันfiเป็นคำหลักที่สงวนไว้จึงไม่สามารถเป็นคำสั่งที่สามในเนื้อความของifคำสั่ง แต่ทำเครื่องหมายจุดสิ้นสุดของคำสั่งผสม


ขอบคุณถ้ามีการใช้งานif program1 foo; program2 bar; program3 baz; สถานะของโปรแกรมควรจะเป็น0เช่นนั้นเชลล์จะไปถึงthen? สุดท้าย?
Maxim Koretskyi

program3 bazเพียงแค่ สถานะทางออกของรายการคำสั่งคือสถานะออกของคำสั่งสุดท้ายในรายการนั้น อีกสองคนสามารถล้มเหลวโดยไม่ส่งผลกระทบต่อสภาพ
chepner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.