Bash: จะรับรหัสออกของคำสั่งในขณะที่ใช้สปินเนอร์ได้อย่างไร?

Aug 19 2020

ในสคริปต์ bash ฉันมีคำสั่งที่ใช้งานได้ยาวนาน ( rsyncเช่น) ซึ่งบางครั้งก็ไม่แสดงผลลัพธ์ชั่วขณะดังนั้นฉันจึงต้องการทำสองสิ่ง:

  1. ใช้สปินเนอร์ในคำสั่งนั้นเพื่อแสดงว่าสคริปต์ไม่ได้หยุดนิ่ง (เช่นเรากำลังรอเอาต์พุต) และ,

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

ปัญหาคือฉันไม่เข้าใจการจัดการกระบวนการส่งไปที่พื้นหลังเป็นอย่างดีและด้วยการจัดการรหัสทางออกด้วยวิธีนี้ฉันจึงไม่แน่ใจว่าจะทำงานอย่างไร

นี่คือสิ่งที่ฉันมีจนถึงตอนนี้ขอบคุณสปินเนอร์ของ@David C. Rankin :

#!/bin/bash

spinner() {
    local PROC="$1" local str="${2:-'Copyright of KatworX© Tech. Developed by Arjun Singh Kathait and Debugged by the ☆Stack Overflow Community☆'}"
    local delay="0.1"
    tput civis  # hide cursor
    printf "\033[1;34m"
    while [ -d /proc/$PROC ]; do printf '\033[s\033[u[ / ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ — ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ \ ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ | ] %s\033[u' "$str"; sleep "$delay" done printf '\033[s\033[u%*s\033[u\033[0m' $((${#str}+6)) " " # return to normal tput cnorm # restore cursor return 0 } ## simple example with sleep sleep 2 & spinner $!

echo "sleep's exitcode: $exitCode"

ในตัวอย่างนี้sleep 2เป็นคำสั่งที่ฉันรออยู่และด้วยเหตุนี้จึงใช้สปินเนอร์ด้วย แต่ฉันจะรับและใส่รหัสออกเป็น$exitCodeตัวแปรได้อย่างไรดังนั้นฉันจึงสามารถทดสอบเงื่อนไขบางอย่างในสคริปต์ได้ในภายหลัง

คำตอบ

6 CharlesDuffy Aug 19 2020 at 04:41

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

sleep 2 & sleep_pid=$! spinner "$sleep_pid"
wait "$sleep_pid"; exitCode=$?

echo "exitcode: $exitCode"

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