ความหมายของ & ในตอนท้ายของคำสั่งคืออะไร?


12

ฉันมีบรรทัดสคริปต์เริ่มต้น:

pyprogramm >> /dev/null  2>&1 &

ความหมาย:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

แต่สุดท้าย&หมายถึงอะไร

คำตอบ:


16

& terminator คืออะไร

ตัว&ดำเนินการต่อท้ายที่ส่วนท้ายของคำสั่งถูกใช้เพื่อทำให้คำสั่งเป็นพื้นหลัง นี่เป็นไวยากรณ์มาตรฐานที่ระบุโดยมาตรฐาน POSIX :

รายการแบบอะซิงโครนัส

หากคำสั่งถูกยกเลิกโดยผู้ควบคุม ('&') เชลล์จะดำเนินการคำสั่งแบบอะซิงโครนัสในเชลล์ย่อย ซึ่งหมายความว่าเชลล์จะไม่รอให้คำสั่งเสร็จสิ้นก่อนดำเนินการคำสั่งถัดไป

รูปแบบสำหรับรันคำสั่งในพื้นหลังคือ:

command1 & [command2 & ... ]

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

จากคำจำกัดความคุณจะเห็นว่า&ยังทำหน้าที่เป็นตัวยกเลิกคำสั่งสำหรับรายการคำสั่งเหมือนที่;ทำ ในตัวอย่างเฉพาะของคุณpyprogramm >> /dev/null 2>&1 &มีเพียงหนึ่งคำสั่งในรายการ

ตามลำดับ; list เทียบกับ asynchronous & รายการ

ให้เป็นปกติมากกว่านี้,

echo Hello ; echo World ;

และ

echo Hello & echo World &

เป็นตัวอย่างสองรายการที่ยกเลิกโดยตัวดำเนินการ;และ &ข้อแตกต่างคือ&รายการที่ถูกยกเลิกจะมีการเชื่อมต่อกับอินพุต/dev/nullหากการควบคุมงานถูกปิดใช้งาน

หากการควบคุมงานถูกปิดใช้งาน (ดู set, -m), อินพุตมาตรฐานสำหรับรายการอะซิงโครนัสก่อนที่จะทำการเปลี่ยนเส้นทางที่ชัดเจนใด ๆ จะถูกพิจารณาว่าได้รับมอบหมายให้เป็นไฟล์ที่มีคุณสมบัติเดียวกันกับ / dev / null สิ่งนี้จะไม่เกิดขึ้นหากเปิดใช้งานการควบคุมงาน ในทุกกรณีการเปลี่ยนเส้นทางที่ชัดเจนของอินพุตมาตรฐานจะแทนที่กิจกรรมนี้

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

โปรดทราบว่าจากคำจำกัดความที่เรากล่าวถึงก่อนหน้านี้&จะดำเนินการคำสั่งใน subshell ในทางตรงกันข้าม;รายการที่ถูกยกเลิกจะถูกดำเนินการในเชลล์ปัจจุบัน นอกจากนี้ยังมีความแตกต่างในสถานะทางออก สำหรับ&มาตรฐานพูดว่า:

สถานะการออกของรายการอะซิงโครนัสจะเป็นศูนย์

สิ่งนี้มีความสำคัญเมื่อคุณต้องการให้หลายคำสั่งอยู่ในพื้นหลัง เมื่อคุณเขียนสคริปต์หรือคำสั่งคุณจะต้องเลือกคำสั่งที่คุณไม่สนใจว่ามันล้มเหลวหรือไม่หรือคุณจะต้องหาวิธีจัดการสถานะทางออกที่ไม่ใช่ศูนย์ (ข้อผิดพลาด) ในตัวอย่างเฉพาะของคุณการpyprogramm >> /dev/null 2>&1 &รันในพื้นหลังควรมีวิธีการระบุว่าล้มเหลวหรือไม่อย่างไรก็ตามตัดสินว่าคุณใช้2>&1คุณกำลังซ่อนเอาต์พุตข้อผิดพลาดโดยการเปลี่ยนเส้นทางและคุณอาจถือว่าสคริปต์ไม่ควรล้มเหลว

ในทางตรงกันข้าม;สถานะการออกจะถูกกำหนดเป็น:

สถานะทางออกของรายการตามลำดับจะเป็นสถานะออกของคำสั่งสุดท้ายในรายการ

สิ่งนี้มีความเกี่ยวข้องกับวิธีที่คุณเขียนรายการลำดับของคำสั่งในบรรทัดคำสั่งและวิธีที่คุณต้องการจัดการสิ่งต่าง ๆ หากคำสั่งบางรายการในรายการล้มเหลว


บันทึกด้านข้างและการอ่านเพิ่มเติม

  • ความจริงที่ว่านี้คือความหมาย POSIX หมายความว่าทุกบอร์นเหมือนเปลือกหอย, ความหมายbash, dashและkshต้องสนับสนุน

  • &ในการเปลี่ยนเส้นทางจะแตกต่างจาก&เป็นคำสั่งสิ้นสุด มันหมายถึงการทำสำเนา (คัดลอก) วัตถุ file-descriptor ดูสิ่งที่ & หมายถึงอะไรในการเปลี่ยนเส้นทางผลลัพธ์?

  • ในbashนั้นยังมี|&ผู้ประกอบการ (หมายเหตุไม่มีช่องว่างระหว่างท่อและเครื่องหมายแอมเปอร์แซนด์) จากทุบตีคู่มือ :

    หาก | & ถูกใช้ข้อผิดพลาดมาตรฐานของคำสั่งนอกเหนือจากเอาต์พุตมาตรฐานเชื่อมต่อกับอินพุตมาตรฐานของ command2 ผ่านไพพ์ มันเป็นชวเลขสำหรับ 2> & 1 | การเปลี่ยนทิศทางโดยนัยของข้อผิดพลาดมาตรฐานไปยังเอาต์พุตมาตรฐานถูกดำเนินการหลังจากการเปลี่ยนทิศทางใด ๆ ที่ระบุโดยคำสั่ง


2
สิ่งที่คุณพูดเกี่ยวกับการ&ซ่อนเอาต์พุตไม่ถูกต้อง วรรคจากมาตรฐานที่คุณกำลังอ้างพูดถึงการป้อนข้อมูลไม่เอาท์พุท สาเหตุของความแตกต่างระหว่างการควบคุมงานที่ถูกเปิดใช้งานหรือไม่ก็คือกระบวนการเบื้องหลังที่พยายามอ่านจาก tty จะถูกระงับ เมื่อถึงจุดนั้นคุณต้องใช้การควบคุมงานเพื่อวางไว้ในส่วนหน้าเพื่อให้อินพุตที่กำลังรออยู่ สิ่งเหล่านี้ไม่สามารถทำได้หากไม่มีการควบคุมงานดังนั้นหากปิดการควบคุมงาน stdin จะต้องถูกเปลี่ยนเส้นทางจาก/dev/nullหรือเทียบเท่า
kasperd

ฉันเห็นข้อผิดพลาดในการแก้ไขของคุณเช่นกัน ในที่เดียวที่คุณเปิดใช้งานการเขียนที่คุณควรจะปิดการเขียน
kasperd

@kasperd ใช่ฉันเพิ่งอ่านหน้า POSIX อีกครั้งเมื่อฉันสังเกตเห็นเช่นกัน แก้ไขแล้ว แจ้งให้เราทราบหากมีสิ่งใดที่ต้องการแก้ไขอีก ขอบคุณ :)
Sergiy Kolodyazhnyy

3

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


0

&สิ่งนี้คืนการควบคุมสคริปต์ไปยังระบบปฏิบัติการ แต่ส่งการตอบสนองไปยังพื้นหลังไม่ใช่เพราะnohupส่งการดำเนินการทั้งหมดโดยตรง

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