GNU/Linux >> Belajar Linux >  >> Linux

Shell Script while loop:[ di sekitar saluran pipa yang hilang `]'

Kesalahannya adalah Anda harus menghapus [ terlebih dahulu karena Anda ingin memeriksa status keluar maka gunakan perintah secara langsung.

Halaman Wiki alat Shellcheck memiliki penjelasan untuk ini (masalah SC1014):

[ .. ] bukan bagian dari sintaks shell seperti if pernyataan. Itu tidak setara dengan tanda kurung dalam bahasa mirip-C, if (foo) { bar; } , dan tidak boleh dibungkus dengan perintah untuk diuji.

[ hanyalah perintah biasa, seperti whoami atau grep , tetapi dengan nama yang lucu (lihat ls -l /bin/[ ). Ini adalah singkatan dari test .

Jika Anda ingin memeriksa status keluar dari perintah tertentu, gunakan perintah itu secara langsung.

Jika Anda ingin memeriksa output dari suatu perintah, gunakan "$(..)" untuk mendapatkan hasilnya, lalu gunakan test atau [ /[[ untuk melakukan perbandingan string:

Gunakan juga ps aux | grep -q "[r]elayevent.sh" sehingga Anda akan mendapatkan status keluar secara diam-diam alih-alih mencetak apa pun ke stdout .

Atau Anda dapat menggunakan pgrep dan arahkan keluarannya ke /dev/null .

Gunakan kondisi kedua terlebih dahulu karena akan lebih efisien untuk kasus terakhir.

Jadi skrip terakhir akan seperti:

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh"   ; do

    sleep 3

    let COUNTER+=1

done

Atau

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep  "[r]elayevent.sh" >/dev/null  ; do

    sleep 3

    let COUNTER+=1

done

Anda tidak dapat memiliki pipa di dalam [ ... ] . Juga lebih baik menggunakan pgrep daripada mencoba mengurai keluaran dari ps :

count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
    sleep 3
    count=$(( count + 1 ))
done

Sistem BSD dapat menggunakan pgrep -q ... bukannya pgrep ... >/dev/null untuk membuang output sebenarnya dari pgrep , sama seperti grep biasa (kami hanya tertarik pada status keluar).

Perhatikan bagaimana kita tidak meletakkan pgrep perintah di dalam [ ... ] . Itu karena kami tidak tertarik pada keluarannya, hanya status keluarnya. Dengan [ ... ] Anda biasanya membandingkan string atau angka. [ ... ] akan menghasilkan status keluar yang nol (benar) atau bukan nol (salah), seperti halnya pgrep eksekusi.

Namun, ini tidak memeriksa mekanisme penguncian apa pun, hanya apakah proses tertentu sedang berjalan atau tidak.

Jika Anda mencoba untuk menjalankan hanya satu contoh skrip, lebih baik melakukan sesuatu seperti ini (dengan asumsi EXIT trap dijalankan setiap kali skrip diakhiri dengan tertib):

lockdir=dir.lock

if mkdir "$lockdir"; then
    trap 'rmdir "$lockdir"' EXIT
else
    echo 'Only one instance of this script allowed' >&2
    exit 1
fi

Dengan sejumlah percobaan dan tidur:

lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
    if mkdir "$lockdir"; then
        trap 'rmdir "$lockdir"' EXIT
        break
    else
        echo 'Locked. Sleeping...' >&2
        sleep 3
    fi

    count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
    echo 'Giving up.' >&2
    exit 1
fi

Terkait:

  • Bagaimana cara memastikan hanya satu contoh skrip bash yang berjalan?

Linux
  1. Menentukan Jalur Ke Skrip Shell Bersumber?

  2. Proses Dalam Sesi Dalam Shell Interaktif Vs Dalam Skrip?

  3. Tertangkap Dalam Lingkaran? Awk While, Do While, For Loop, Break, Continue, Exit Contoh

  1. Bagaimana cara mendapatkan kode keluar dari proses pemijahan di skrip Shell yang diharapkan?

  2. Mulai untuk Loop dari elemen kedua - skrip Shell

  3. Saat menggunakan printf bagaimana cara keluar dari karakter khusus dalam skrip shell?

  1. Bagaimana Cara Membuat Variabel Lingkungan "diekspor" Dalam Skrip Shell Tetap Di Sekitar?

  2. Tentukan Shell In Script Selama Runtime?

  3. mengapa bash while loop tidak keluar saat menyalurkan ke subperintah yang diakhiri?