วัตถุประสงค์ของ“ &&” ในคำสั่งเชลล์คืออะไร


354

เท่าที่ฉันรู้การใช้&คำสั่งหลังจากนั้นสำหรับการรันในพื้นหลัง

ตัวอย่าง&การใช้งาน:tar -czf file.tar.gz dirname &

แต่จะเป็น&&อย่างไร (ดูตัวอย่างนี้: /server/215179/centos-100-disk-full-how-to-remove-log-files-history-etc#answer-215188 )

คำตอบ:


398

&&ช่วยให้คุณทำบางสิ่งบางอย่างขึ้นอยู่กับว่าคำสั่งก่อนหน้าเสร็จเรียบร้อยแล้ว - do_something && do_something_else_that_depended_on_somethingที่ว่าทำไมคุณมีแนวโน้มที่จะเห็นมันเป็นล่ามโซ่


391

นอกจากนี้คุณยังมี||ตรรกะหรือหรือ;ซึ่งเป็นเพียงตัวคั่นที่ไม่สนใจสิ่งที่เกิดขึ้นกับคำสั่งก่อนหน้านี้

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

รายละเอียดบางอย่างเกี่ยวกับเรื่องนี้อยู่ที่นี่รายการคำสั่งในคู่มือทุบตี


5
false && echo "Will not be printed"บางทีคุณอาจต้องการที่จะเพิ่ม
MTSan

112

บรรทัดคำสั่ง - มีจุดประสงค์&&อะไร?

ในเปลือกเมื่อคุณเห็น

$ command one && command two

ความตั้งใจที่จะดำเนินการคำสั่งที่ตามมาก็ต่อ&&เมื่อคำสั่งแรกประสบความสำเร็จ นี่เป็นสำนวนของกระสุน Posix และไม่เพียง แต่พบใน Bash

มีวัตถุประสงค์เพื่อป้องกันไม่ให้การทำงานของกระบวนการที่สองหากล้มเหลวในครั้งแรก

คุณอาจสังเกตเห็นว่าฉันใช้คำว่า "เจตนา" - นั่นเป็นเหตุผลที่ดี ไม่ใช่ทุกโปรแกรมที่มีพฤติกรรมเหมือนกันดังนั้นเพื่อให้สามารถใช้งานได้คุณต้องเข้าใจว่าโปรแกรมพิจารณา "ความล้มเหลว" และวิธีจัดการกับมันโดยการอ่านเอกสารประกอบและหากจำเป็นให้ซอร์สโค้ด

เชลล์ของคุณพิจารณาค่าส่งคืนเป็น 0 สำหรับค่าจริงตัวเลขบวกอื่น ๆ สำหรับค่าเท็จ

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

&&จะเรียกว่าAND_IFในไวยากรณ์ POSIX เชลล์ซึ่งเป็นส่วนหนึ่งของand_orรายการของคำสั่งซึ่งยังรวมถึง||ซึ่งเป็นOR_IFที่มีความหมายคล้ายกัน

สัญลักษณ์ไวยากรณ์ที่ยกมาจากเอกสาร:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

และไวยากรณ์ (ที่ยกมาจากเอกสารประกอบ) ซึ่งแสดงให้เห็นว่าจำนวนAND_IFs ( &&) และ / หรือOR_IFs ( ||) ใด ๆ ที่สามารถหงุดหงิดเข้าด้วยกัน (ตามที่and_orกำหนดไว้ซ้ำ):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

โอเปอเรเตอร์ทั้งสองมีลำดับความสำคัญเท่ากันและได้รับการประเมินจากซ้ายไปขวา ตามที่เอกสารระบุไว้:

AND-ORรายชื่อเป็นลำดับหนึ่งหรือมากกว่าท่อแยกจากกันโดยผู้ประกอบการและ"&&""||"

รายชื่อเป็นลำดับหนึ่งหรือมากกว่าและหรือรายชื่อแยกจากกันโดยผู้ประกอบการ';'และ'&'และยกเลิกเลือกโดย';', '&'หรือ

ผู้ประกอบการ"&&"และ"||"จะต้องมีความสำคัญเท่ากันและจะได้รับการประเมินด้วยการเชื่อมโยงด้านซ้าย ตัวอย่างเช่นคำสั่งทั้งสองต่อไปนี้เขียนแถบไปยังเอาต์พุตมาตรฐาน:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. ในกรณีแรก false เป็นคำสั่งที่ออกโดยมีสถานะเป็น 1

    $ false
    $ echo $?
    1

    ซึ่งหมายความว่าecho fooไม่ทำงาน (เช่นการลัดวงจรecho foo) จากนั้นคำสั่งecho barจะถูกดำเนินการ

  2. ในกรณีที่สองออกจริงด้วยรหัส 0

    $ true
    $ echo $?
    0

    และดังนั้นจึงecho fooไม่ถูกดำเนินการจากนั้นecho barถูกดำเนินการ


31

การใช้งานที่ค่อนข้างบ่อยสำหรับ '&&' กำลังรวบรวมซอฟต์แวร์ด้วยเครื่องมืออัตโนมัติ ตัวอย่างเช่น:

./configure --prefix=/usr && make && sudo make install

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

บางครั้งฉันก็ถูกพาไป ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

ฉันทำสิ่งนี้เมื่อยกตัวอย่างเช่นการสร้าง linux จากกล่องเริ่มต้น


2
เก่งใน REPL แต่สำหรับสคริปต์ฉันอยากได้set -o errexitBash
แฟรงคลินหยู

19

&&สตริงคำสั่งเข้าด้วยกัน คำสั่งต่อเนื่องจะดำเนินการก็ต่อเมื่อคำสั่งก่อนหน้านั้นสำเร็จ

ในทำนองเดียวกัน||จะช่วยให้คำสั่งต่อเนื่องในการดำเนินการหากล้มเหลวก่อนหน้านี้

ดูโปรแกรมทุบตีเชลล์


8

ดูตัวอย่าง:

mkdir test && echo "Something" > test/file

เชลล์จะพยายามสร้างไดเรกทอรีtestจากนั้นถ้าสำเร็จก็จะลองสร้างไฟล์ข้างใน

ดังนั้นคุณอาจขัดจังหวะลำดับขั้นตอนหากหนึ่งในนั้นล้มเหลว


8

มันจะดำเนินการคำสั่งที่สองหากคำสั่งแรกจบลงอย่างประสบความสำเร็จ เหมือนคำสั่ง if:

 if (1 == 1 && 2 == 2)
  echo "test;"

มันพยายามครั้งแรกถ้า 1 == 1 หากเป็นจริงมันจะตรวจสอบว่า 2 == 2


1
มีคนอธิบายได้ไหมว่าเพราะเหตุใดปัญหานี้จึงถูกลดระดับลงสำหรับผู้ใช้ที่สะดุดกับคำถาม
user3243242

1
@ user3243242 ไม่ผิดเพียงเป็นตัวอย่างที่ไม่ดีที่แสดงให้เห็นถึงการใช้งานของ&&
dan

มันเป็นความเข้าใจที่ดีว่าifการทดสอบทำงานอย่างไรในการทุบตี ฉันไม่เคยคิดเลยว่ามันจะเหมือนสายโซ่ของคำสั่งเปรียบเทียบทำลายเมื่อใด ๆ ของพวกเขาล้มเหลว ดังนั้นคุณมี upvote ของฉัน :)
PiRK

1
ผลที่ตามมาคือคุณสามารถรับพฤติกรรมที่ตรงกันข้ามโดยการใช้||คำสั่งลูกโซ่จนกว่าพวกเขาจะประสบความสำเร็จ: eei || leu || uie || echo prout3 || echo "never executed"
PiRK

7

command_1 && command_2: execute command_2 เมื่อ command_1 สำเร็จเท่านั้น

command_1 || command_2: execute command_2 เฉพาะเมื่อ command_1 ดำเนินการไม่สำเร็จ

ความรู้สึกที่คล้ายกันเป็นวิธีการที่ว่า 'ถ้า' เงื่อนไขจะถูกดำเนินการในการเขียนโปรแกรมภาษาหลักเช่นในif (condition_1 && condition_2){...}condition_2 จะถูกมองข้ามถ้า condition_1 เป็นfalseและในif (condition_1 || condition_2){...}condition_2 จะถูกมองข้ามถ้า condition_1 trueคือ ดูสิมันเป็นกลอุบายแบบเดียวกับที่คุณใช้สำหรับการเข้ารหัส :)


ฉันไม่รู้ว่าคุณหมายถึงอะไรโดย 'ตรงกันข้าม' แต่ $ echo '1' || echo '2' พิมพ์เฉพาะ '1' และ $ mis_command || echo '2' พิมพ์ข้อความแสดงข้อผิดพลาดและ '2' ในบรรทัดถัดไป คุณช่วยอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับสิ่งที่คุณคิดว่าผิดเกี่ยวกับมันได้หรือไม่
Xiaonin Li

เมื่อวานนี้ฉันเหนื่อยเกินไปแล้ว ขออภัยสำหรับฉันมันเท่านั้น: / ฉันต้องการให้คุณแก้ไขบางสิ่งบางอย่างในตัวคุณตอบถ้าคุณต้องการฉัน upvote (เพื่อให้คำตอบของคุณ 0 ตอนนี้ stackoverflow ขอแก้ไขดังนั้นฉันไม่สามารถ)
Arount

@ จำนวนมันก็โอเคไม่ต้องกังวล ดังนั้นฉันเพิ่งส่งการแก้ไข เป็นเช่นนั้นคุณสามารถลบการลงคะแนนได้หรือไม่
Xiaonin Li

อ๋ออีกครั้งขอโทษจริง ๆ
Arount

0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

เมื่อโปรแกรมตรวจสอบว่าคำสั่งจากนั้นโปรแกรมจะสร้างหมายเลขที่เรียกว่ารหัสออกหากทั้งสองเงื่อนไขเป็นจริงรหัสออกเป็นศูนย์ (0) มิฉะนั้นรหัสออกจะเป็นจำนวนบวก เฉพาะเมื่อแสดงเท่ากันหากรหัสออกมีการสร้างศูนย์ (0) ซึ่งหมายความว่าทั้งสองเงื่อนไขเป็นจริง


ยินดีต้อนรับสู่ stackoverflow โปรดตรวจสอบให้แน่ใจว่าข้อมูลโค้ดของคุณใช้ได้ก่อนโพสต์ที่นี่ คุณต้องแก้ไขให้ถูกต้องif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu

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