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 sepertiif
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, sepertiwhoami
ataugrep
, tetapi dengan nama yang lucu (lihatls -l /bin/[
). Ini adalah singkatan daritest
.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 gunakantest
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?