เรียกใช้คำสั่งโดยไม่ทำให้ฉันต้องรอ


145

บน CLI บางครั้งคำสั่งที่ฉันพิมพ์ต้องใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์และบางครั้งฉันก็รู้ว่าจะเกิดขึ้นเมื่อใด ฉันสับสนเล็กน้อยเกี่ยวกับ "backgrounding" และใน Linux

อะไรคือวิธีที่ใช้กันมากที่สุด (หรือวิธีที่ใช้งานง่าย) ในการบอก CLI ว่าฉันไม่ต้องการรอโปรดให้ฉันตอบกลับทันที และถ้ามันสามารถให้แถบความคืบหน้ากับฉันหรือเพียงแค่สปินเนอร์ยุ่งก็คงจะดี!


3
ดูเพิ่มเติมคุณจะส่งแอพบรรทัดคำสั่งไปยังพื้นหลังได้อย่างไร หากคุณเริ่มคำสั่งแล้วและต้องการส่งไปยังพื้นหลัง
Gilles

คำตอบ:


153

ก่อนเรียกใช้คำสั่งคุณสามารถผนวก&เข้ากับบรรทัดคำสั่งเพื่อทำงานในพื้นหลัง:

long-running-command &

หลังจากเริ่มต้นคำสั่งคุณสามารถกดCtrlZเพื่อระงับคำสั่งและbgวางไว้ในพื้นหลัง:

long-running-command
[Ctrl+Z]
bg

ฉันใช้คำสั่ง "find ~ / a.java &" แต่ฉันไม่ได้ทำงานต่อ นอกจากนี้ฉันลอง cmd + z (สำหรับ mac) .... มันใช้งานไม่ได้
Abhimanyu Aryan

1
@AbhimanyuAryan บางทีคุณอาจต้องการดีบักfind ...คำสั่งของคุณก่อนจากนั้นจึงรันในพื้นหลัง ในกรณีนี้คุณไม่มี-nameตัวเลือก
Alexis Wilke

113

สิ่งนี้เป็นที่ชื่นชอบของทุกคนตั้งแต่การส่งกระบวนการไปยังพื้นหลังคุณไม่ต้องกังวลกับการส่งข้อความสกปรกเทอร์มินัลของคุณ:

nohup command &

สิ่งนี้ไม่เพียง แต่เรียกใช้กระบวนการในพื้นหลัง แต่ยังสร้างบันทึก (เรียกว่าnohup.outในไดเรกทอรีปัจจุบันหากไม่สามารถทำได้ไดเรกทอรีบ้านของคุณ) และถ้าคุณปิด / ล็อกเอาท์เปลือกปัจจุบันกระบวนการจะไม่ถูกฆ่าโดยการป้องกันเด็ก สัญญาณหลักเมื่อถูกฆ่า (เช่นออกจากระบบโดย SIGHUP ไปยังผู้ปกครองหรือปิดเปลือกปัจจุบัน)

มีอีกชื่อหนึ่งที่เรียกว่าdisownแต่นั่นก็เป็นคำตอบอื่น ๆ มากกว่าที่จะเป็นวิธีการในตัวมันเอง:

command & # our program is in background
disown # now it detached itself of the shell, you can do whatever you want

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


4
ดูแลระบบตั้งแต่ '95 ไม่เคยได้ยินใครบอกจนกว่าจะถึงวันนี้ขอบคุณ! มันใช้ไม่ได้กับทุกเชลล์ (bash ที่เลือก, zsh, tcsh. tcsh ไม่ทำงาน)
yoonix

การใช้nohupงานในเชลล์ควบคุมงานนั้นเป็นเรื่องโง่ กระสุนสมัยใหม่ไม่ส่งHUPไปยังกระบวนการพื้นหลัง การเปลี่ยนเส้นทางไปยังชื่อไฟล์ที่ไม่ซ้ำกันคือราคาที่ต้องจ่าย
ลูกไก่

@ แสดงกรณีการใช้ที่นี่เพื่อป้องกัน stderr และ stdout เพื่อสร้างมลพิษให้กับเทอร์มินัลด้วยเครื่องหมายบวกที่สร้างไฟล์บันทึกโดยอัตโนมัติ
Braiam

1
command > file.log 2>&1 & disownยาวกว่านี้เล็กน้อยnohup command &แต่ฉันคิดว่านั่นเป็นสิ่งที่ @ chicks แนะนำ
joeytwiddle

31

นี่อาจเป็นสิ่งที่คุณต้องการ

my_command > output.log 2>&1 &

สิ่งนี้จะเริ่มต้นคำสั่งของคุณโดยเปลี่ยนเส้นทางทั้ง stdout และ stderr ไปยังคำสั่งoutput.logที่คุณสามารถระบุได้ หากคุณไม่ต้องการเก็บเอาท์พุทเลย - คุณสามารถใช้/dev/nullแทนไฟล์จริงได้

&จะดำเนินการคำสั่งในพื้นหลังเพื่อให้คุณสามารถป้อนคำสั่งต่อไปในขณะที่มันกำลังทำงานอยู่ 2>&1เปลี่ยนเส้นทาง stderr ไปยัง stdout เพื่อให้เอาท์พุททั้งหมดถูกจับ

นอกจากนี้เมื่อคุณเรียกใช้คำสั่งเช่นนี้คุณควรได้รับการยืนยันจากเคอร์เนลคล้ายกับสิ่งนี้: [2] 1234 ซึ่งหมายความว่ากระบวนการของคุณกำลังทำงานในพื้นหลังและรหัสคือ1234ดังนั้นคุณสามารถฆ่ามันในภายหลังหากคุณต้องการkill -9 1234


2
ขอบคุณ2>&1เป็นสิ่งสำคัญมากเพราะคำสั่งสามารถล้มเหลวและลองเอาท์พุทข้อผิดพลาดในบางกรณี!
ericn

1
หนึ่งนี้ทำงานเมื่อคำตอบข้างต้นไม่ขอบคุณ
Domagoj

9

มองเข้าไปในหน้าจอหรือtmux ตัวอย่างด้วยtmux:

$ tmux new -d 'longrunningcommand'

ในขณะที่คำตอบอื่น ๆ ที่ใช้ '&' เป็นพื้นหลังจะใช้ได้ แต่คุณต้องเปลี่ยนเส้นทาง stdout (และ stderr!) โดยไม่ต้องทำเช่นนั้นผลลัพธ์จะตรงไปที่เปลือกของคุณผสมกับสิ่งอื่นที่คุณอาจมี

การทำแบ็คกราวน์จะล้มเหลวหากคุณใช้คำสั่งแบบยาวและออกจากระบบหรือตัดการเชื่อมต่อ ระบบจะฆ่างานของคุณ

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

หน้าจอเป็นโปรแกรมที่ทดลองใช้แล้วและเป็นจริง tmux อายุน้อยกว่ามาก แต่ได้เรียนรู้จากหน้าจอที่ผ่านมา


คำตอบนี้พลาดคำตอบจริงและฟังดูเหมือน RTFM
Lloeki

5

(เพื่อความสมบูรณ์ - ตอบแล้ว :) คุณใส่คำสั่งในพื้นหลังโดยเพิ่ม&หลังจากคำสั่ง:

long_command with arguments > redirection &

ฉันกำลังเพิ่มคำตอบนี้เพื่อตอบคำถามส่วนอื่นของคุณ:

ไม่มีเทียบเท่าที่แท้จริงของปินเนอร์สำหรับการแสดงความคืบหน้าในคำสั่งพื้นหลัง แต่คุณสามารถดูสถานะของคำสั่งพื้นหลังโดยการพิมพ์หรือjobs jobs -lมันจะแสดงคำสั่งที่มีพื้นหลังของคุณและไม่ว่าพวกเขาจะทำงานหยุดผ่านสัญญาณ (เช่นกับ^Z) หรือหยุดเป็นครั้งคราวเพราะพวกเขากำลังรอการป้อนข้อมูลแบบโต้ตอบจากคุณ


long_command with arguments &> redirection &เพื่อเปลี่ยนเส้นทางstderrด้วย
Ice-Blaze

3

&คุณสามารถเรียกใช้โปรแกรมในพื้นหลังโดยใช้ ตัวอย่างเช่นหากคุณต้องการเรียกใช้yum install XyZตัวอย่างเช่นคุณสามารถเรียกใช้:

yum install XyZ &

stdoutหรือผลลัพธ์จากโปรแกรมที่สามารถเปลี่ยนเส้นทางไปใช้>ในการเขียนทับไฟล์หรือ>>ผนวกไปยังแฟ้ม ตัวอย่างเช่นหากคุณต้องการเข้าสู่ระบบyumไฟล์yum.log:

yum install XyZ > yum.log &

หรือถ้าคุณต้องการเพิ่มผลลัพธ์ไปยังไฟล์ที่มีอยู่log:

yum install XyZ >> log &

ข้อผิดพลาดถูกพิมพ์ไปstderrและไม่stdoutและสามารถเปลี่ยนเส้นทางไปยังไฟล์ในลักษณะเดียวกัน แต่ใช้2>:

yum install XyZ 2> errors
yum install XyZ 2>> errors

หากคุณต้องการเปลี่ยนเส้นทางทั้งสองstderrและstdoutคุณสามารถใช้&>:

yum install XyZ &> output
yum install XyZ &>> output

2

คุณสามารถเรียกใช้คำสั่งในพื้นหลังเพียงแค่ใส่&เครื่องหมายหลังจากนั้น

ตัวอย่างเช่น:

areallylong_command &

จะทำงานในพื้นหลัง

คุณสามารถเปลี่ยนเส้นทาง stdout / stderr เพิ่มเติมไปยังไฟล์ที่เหมาะสมเพื่อไม่ให้ปรากฏบนเทอร์มินัลของคุณในขณะที่คุณกำลังทำอะไรบางอย่าง

ดูสิ่งนี้สำหรับข้อมูลเพิ่มเติม: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html


0

ลองใช้คำสั่ง 'หน้าจอ' ก่อนที่คุณจะเริ่มงานที่ต้องทำนาน ๆ จากนั้นเมื่อคุณถอดออกคุณสามารถใส่กลับไปที่หน้าจอด้วย 'screen -r -d' เมื่อใดก็ตามที่คุณต้องการอีกครั้ง ฉันพบว่าเมื่อใช้เทอร์มินัลผ่าน ssh หรือการเชื่อมต่อเครือข่ายอื่น ๆ ในบางครั้งพวกเขาอาจจะเสียโดยการเชื่อมต่อที่ไม่ดีไปยังเซิร์ฟเวอร์ เรียกใช้ภายใน 'หน้าจอ' แก้ไขปัญหานี้

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