เรียกใช้คำสั่งอีกครั้งอย่างต่อเนื่องเมื่อเสร็จสิ้นใน Bash


62

ฉันกำลังพยายามหาวิธีง่ายๆในการรันคำสั่งอีกครั้งเมื่อใดก็ตามที่มันเสร็จสิ้นไม่ว่าด้วยเหตุผลใด (ข้อผิดพลาดหรืออย่างอื่น)

อะไรจะเป็นวิธีที่ดีที่สุดในการเข้าถึงสิ่งนี้

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

แก้ไข 2:คำตอบเกือบทั้งหมดทำงานได้ดี ฉันคิดว่าคำตอบส่วนใหญ่โดยไม่ตั้งใจจะแยกกระบวนการหรือดำเนินการอีกครั้งเพียงครั้งเดียวซึ่งไม่ต้องการ

linux  bash 

1
คุณยังไม่ชัดเจน มันจะช่วยถ้าคุณพูดถึงโปรแกรมที่คุณกำลังดำเนินการอยู่
Daniel Beck

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

คำตอบ:


39

สิ่งนี้สร้างลูปแบบไม่สิ้นสุดดำเนินการcommandซ้ำแล้วซ้ำอีก

while :
    do
        command
done

โปรดดูการแก้ไขคำถามเดิม ฉันจำเป็นต้องดำเนินการซ้ำแล้วซ้ำอีกไม่ใช่แค่ครั้งเดียว

8
@calcifer คำตอบนี้ใช้ได้ดีทีเดียว มีบางอย่างผิดปกติเกี่ยวกับโปรแกรมของคุณที่ไม่มีผู้ใช้ทั้งสี่คนตอบรับที่คาดการณ์ไว้และคุณไม่ได้พูดถึง
Daniel Beck

@ calcifer นี่เป็นวงวนไม่สิ้นสุด มันยังคงทำซ้ำจนกว่าจะถึงเวลาสิ้นสุด (ดีจนกว่าสคริปต์จะถูกยกเลิกต่อไป)
Nate Koppenhaver

1
ฉันไม่ดีฉันคิดว่านี่ (และคำตอบอื่น ๆ ทั้งหมด) จะแยกกระบวนการหรือดำเนินการอีกครั้งเพียงครั้งเดียวซึ่งไม่ต้องการ ใช่คำตอบนี้ใช้ได้ ขอบคุณ

1
หนึ่งบรรทัดรุ่น: while true; do echo 'Hit CTRL+C'; sleep 1; doneขอบคุณcyberciti.biz/faq/bash-infinite-loop
jk2K

107

watchคำสั่งจะทำซ้ำคำสั่งตลอดไปด้วยช่วงเวลาที่ระบุ:

watch -n0 <command>

การตั้งค่า-nเป็นศูนย์ทำให้ช่วงเวลาไม่มีอะไรเลย (ฉันคิดว่ามันเป็น. 1 วินาทีจริง ๆ )

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

การอ้างอิง: หน้าคนดู :

watch รันคำสั่งซ้ำ ๆ , แสดงผลลัพธ์ (screenfull แรก) สิ่งนี้ช่วยให้คุณสามารถดูผลลัพธ์ของโปรแกรมที่เปลี่ยนแปลงตลอดเวลา โดยค่าเริ่มต้นโปรแกรมจะทำงานทุก 2 วินาที; ใช้ -n หรือ - ช่วงเพื่อระบุช่วงเวลาที่แตกต่างกัน

นาฬิกาจะทำงานจนกว่าจะถูกขัดจังหวะ


โปรดดูการแก้ไขคำถามเดิม

6
คำตอบทั้งหมดทำเช่นนี้รวมถึงคำตอบนี้ ลินุกซ์จะไม่แยกเว้นแต่คุณจะขอเป็นพิเศษ
พอล

ฉันไม่รู้เกี่ยวกับส้อมขอบคุณ

ฉันไม่เห็นผลลัพธ์ใด ๆ โดยใช้วิธีนี้
Raffi Khatchadourian

@RaffiKhatchadourian คุณกำลังพูดว่าถ้าคุณทำwatch lsในไดเรกทอรีที่มีไฟล์คุณจะไม่ได้อะไรเลยหรือ
พอล

17

ทางออกที่ง่ายจะเป็น:

yourcommand; !#

;แยกคำสั่งอนุญาตให้มีหลายคำสั่งในหนึ่งบรรทัด ( Bash: รายการ )

!#บอก bash ให้ "ทำซ้ำทุกสิ่งที่ฉันเขียนจนถึงตอนนี้ในบรรทัดนี้" ( Bash: Event-Designators )


1
ขออภัยฉันไม่ชัดเจนพอ ฉันจำเป็นต้องดำเนินการซ้ำแล้วซ้ำอีกไม่ใช่แค่ครั้งเดียว

ขอบคุณสำหรับสิ่งนี้ฉันกำลังมองหามันโดยเฉพาะอย่างยิ่งเนื่องจากyourcommand; !!ไม่ได้ทำงานกับคำสั่งในบรรทัดเดียวกัน แต่!#ดูเหมือนว่าจะทำ ไชโย!
sdaau

; !#ใช้งานไม่ได้กับ ZSH มันแค่ขยายคำสั่งโดยการโคลนมันไม่ได้กระตุ้น
revelt

7

คุณสามารถวางแผนล่วงหน้าได้ระหว่างการดำเนินการคำสั่ง (หากไม่ใช่แบบโต้ตอบ) และป้อน!!สิ่งที่จะดำเนินการคำสั่งก่อนหน้าอีกครั้ง ping -c 5นี้ทำงานได้เช่นในช่วง


คุณยังสามารถกำหนดฟังก์ชั่นในbash:

function repeat { "$@"; "$@"; }

~/.bashrcยังคงมีอยู่มันเก็บไว้ใน

จากนั้นคุณสามารถเรียกใช้คำสั่งของคุณเช่นนี้:

repeat ping -c5 heise.de

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


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

function repeat { while 1 ; do "$@" ; sleep 1 ; done; }

Ctrl-Zมิฉะนั้นก็ค่อนข้างไม่สะดวกที่จะยกเลิกห่วงอนันต์นี้โดยใช้


โปรดดูการแก้ไขคำถามเดิม

6
@calcifer การดำเนินการเหล่านี้รอจนกว่าการเรียกใช้โปรแกรมจะส่งคืน โปรแกรมของคุณแยกออกจากเชลล์และกลับมาก่อนที่จะหยุดทำงานหรือไม่
Daniel Beck

ฉันไม่ดีฉันคิดว่านี่ (และคำตอบอื่น ๆ ทั้งหมด) จะแยกกระบวนการหรือดำเนินการอีกครั้งเพียงครั้งเดียวซึ่งไม่ต้องการ ใช่คำตอบนี้ใช้ได้ ขอบคุณ

4

ให้whileห่วงสภาพบูลดังกล่าวดังต่อไปนี้:

#!/bin/bash

while true; do

    do_something && wait

done

สิ่งนี้จะดำเนินการซ้ำไปซ้ำมาจนกว่าทุบตีรับสัญญาณเพื่อยุติกระบวนการ ctrl+cมักจะอยู่ในรูปแบบของ

คุณสามารถใช้watchคำสั่งเพื่อเรียกใช้สคริปต์ซ้ำ ๆ ได้เช่นกัน ตัวอย่างเช่นนาฬิกาธรรมดาในเครื่อง bash ที่ใช้watchอาจมีลักษณะดังนี้:

$ watch -t -n1 date +%T

-tตัวเลือกที่บอกwatchจะไม่แสดงชื่อของกระบวนการที่กำลังทำงานอยู่ สิ่งนี้จะให้ผลลัพธ์ที่สะอาดของเฉพาะคำสั่งที่ถูกทำซ้ำ -n1ตัวเลือกที่บอกดูที่จะทำซ้ำทุกnวินาที ในกรณีนี้-n1จะเป็นช่วงเวลา1ที่สอง จากนั้นdate +%Tคำสั่งจะแสดงเวลา ณ เวลาที่คำสั่งเสร็จสิ้น การทำคำสั่งนี้จะให้นาฬิกาที่ใช้งานอยู่ในเครื่องของคุณ

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

do_something() { do_something }; do_something && wait

นี่เป็นหลักเหมือนกับ boolean whileloop โดยใช้การเรียกฟังก์ชันแบบเรียกซ้ำ

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


1
มีwhileตัวอย่างลูป แต่ไม่ได้ใช้trueไวยากรณ์บูลีน มีwatchตัวอย่าง แต่ไม่ได้ให้ประโยชน์กับไวยากรณ์มากมาย ฉันกำลังอธิบายสิ่งเหล่านี้กับใครก็ตามที่อาจช่วยได้ ฉันต้องการให้ประโยชน์ในทางปฏิบัติแก่สิ่งเหล่านี้ whileบูลวงยังสามารถfalseและได้ดำเนินการจนสภาพจริงจะพบ มันค่อนข้างมีประโยชน์

1
@ Spittin'IT เพิ่มวิธีที่ไม่ใช้ในคำตอบอื่น ๆ เพื่อความสะดวกของคุณ

ยุติธรรมเพียงพอและฉันเข้าใจ ... ฉันแค่แสดงความคิดเห็นเพราะฉันผ่านโมดูลการตรวจสอบ แต่การแก้ไขที่ดีและติดตาม !!
Pimp Juice IT

จะifดำเนินการอีกครั้งได้อย่างไร
Kamil Maciorowski

จุดที่ดี Kamil ลืมที่จะทำให้มันซ้ำฮ่า ๆ แก้ไขในการแก้ไขโดยใช้ฟังก์ชั่นเรียกตัวเองในifคำสั่ง

0

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

  1. ป้อนคำสั่งในเทอร์มินัลหนึ่งครั้ง
  2. เลือกคำสั่งรวมถึงอักขระขึ้นบรรทัดใหม่ด้วยเมาส์
  3. คัดลอกส่วนที่เลือกโดยใช้ Ctrl-Insert หรือใช้เมนูบริบท (เข้าถึงได้โดยทั่วไปด้วยการคลิกขวา)
  4. ใช้ Shift-Insert เพื่อวางหลาย ๆ ครั้งตามที่คุณต้องการเรียกใช้คำสั่ง

คุณไม่ต้องรอวางจนกว่าคำสั่งแต่ละคำสั่งจะเสร็จสิ้น คำสั่งที่วางจะเข้าสู่คิวและพวกมันจะดำเนินการทีละคำสั่ง


0

วันนี้ฉันรู้สึกทะลึ่ง

อ่านจากหนึ่งในสตรีมที่ไม่มีที่สิ้นสุดและไปที่ xargs

cat /dev/zero | xargs --null echo hello there

หากคุณต้องการหยุดพักสักเล็กน้อยคุณจะต้องดำเนินการ sh

cat /dev/zero | xargs --null sh -c "echo hello there && sleep 3"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.