Bash: Bagaimana cara mendapatkan kode keluar dari sebuah perintah saat menggunakan spinner?

Aug 19 2020

Dalam skrip bash, saya memiliki perintah yang berjalan lama (katakanlah rsyncmisalnya) yang terkadang tidak menampilkan output untuk sementara waktu, jadi saya ingin melakukan dua hal:

  1. Gunakan spinner pada perintah tersebut untuk menunjukkan bahwa skrip belum dibekukan (yaitu kita hanya menunggu keluaran); dan,

  2. Ambil status keluar dari perintah yang berjalan lama setelah selesai, untuk pengujian lebih lanjut nanti dalam skrip.

Masalahnya adalah, saya tidak memahami penanganan proses pengiriman ke latar belakang dengan baik, dan juga dengan penanganan kode keluar dengan cara ini, jadi saya tidak yakin bagaimana membuat ini berfungsi.

Berikut adalah apa yang saya sejauh, berkat @ David C. Rankin spinner 's:

#!/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"

Dalam contoh ini, sleep 2adalah perintah yang saya tunggu, dan karenanya menggunakan spinner dengan, tetapi bagaimana cara mendapatkan dan memasukkan kode keluarnya ke dalam $exitCodevariabel, sehingga saya dapat mengujinya untuk kondisi tertentu nanti di skrip?

Jawaban

6 CharlesDuffy Aug 19 2020 at 04:41

wait akan memberitahu Anda status keluar apa yang keluar dari PID anak (dengan menyetel status keluar program itu sebagai miliknya), ketika diberikan PID itu sebagai argumen.

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

echo "exitcode: $exitCode"

Perhatikan bahwa menggabungkan beberapa perintah ke dalam satu baris saat mengumpulkan $!atau $?di paruh kedua adalah praktik yang sangat saya sarankan - ini mencegah nilai yang Anda coba kumpulkan agar tidak berubah karena kesalahan (seperti seseorang menambahkan baris log baru ke kode Anda kemudian dan tidak menyadarinya memiliki efek samping).