Saya mencoba menulis skrip bash yang mengumpulkan btmon untuk koneksi perangkat. Saya punya solusi yang berfungsi, tetapi sangat lambat, dan sepertinya masalahnya adalah grep menjadi sangat lambat untuk keluar setelah menemukan kecocokan (sekitar 25 detik). Apa yang dapat saya lakukan untuk mempercepat grep
atau hindari menggunakannya sama sekali?
#!/bin/bash
COUNTER=0
while :
do
until btmon | grep -m 1 '@ Device Connected'
do :
done
let COUNTER=COUNTER+1
echo on 0 | cec-client RPI -s -d 1
sleep 5
echo as | cec-client RPI -s -d 1
until btmon | grep -m 1 '@ Device Disconnected'
do :
done
let COUNTER=COUNTER-1
if [ $COUNTER -eq 0 ];
then echo standby 0 | cec-client RPI -s -d 1;
fi
done
edit:Untuk memperjelas, btmon
dan merupakan alat pemantauan bluetooth yang merupakan bagian dari rangkaian Bluez, dan cec-client adalah utilitas yang dikemas dengan libCEC untuk mengeluarkan perintah di seluruh bus serial HDMI-CEC (antara lain).
Jawaban yang Diterima:
Dalam:
cmd1 | cmd2
Sebagian besar shell (shell Bourne, (t)csh, serta yash dan beberapa versi AT&T ksh dalam beberapa kondisi menjadi pengecualian penting) menunggu cmd1
dan cmd2
.
Di bash
, Anda akan melihat bahwa
sleep 1 | uname
kembali setelah satu detik.
Dalam:
btmon | grep -m 1 '@ Device Disconnected'
grep
akan keluar segera setelah menemukan satu kemunculan pola, tetapi bash
masih akan menunggu btmon
.
btmon
biasanya akan mati karena SIGPIPE saat berikutnya ia menulis ke pipa setelah grep
telah kembali, tetapi jika tidak pernah menulis apa pun lagi, ia tidak akan pernah menerima sinyal itu.
Anda dapat mengganti #! /bin/bash
dengan #! /bin/ksh93
karena itu adalah shell yang kompatibel dengan bash
dan yang hanya menunggu komponen terakhir dari pipeline. Kemudian di
btmon | grep -m 1 '@ Device Disconnected'
setelah grep
kembali, btmon
akan dibiarkan berjalan di latar belakang dan shell akan melanjutkan skrip lainnya.
Jika Anda ingin membunuh btmon
segera setelah grep
kembali, POSIXly, Anda dapat melakukan sesuatu seperti:
sh -c 'echo "$$"; exec btmon' | (
read pid
grep -m1 '@ Device Disconnected' || exit
kill "$pid" 2> /dev/null
true)