L'errore è che dovresti rimuovere prima [ perché vuoi controllare lo stato di uscita, quindi usa direttamente il comando.
Le pagine Wiki dello strumento Shellcheck hanno una spiegazione per questo (problema SC1014):
[ .. ]non fa parte della sintassi della shell comeifdichiarazioni. Non è equivalente alle parentesi nei linguaggi simili al C,if (foo) { bar; }, e non dovrebbe essere avvolto intorno ai comandi da testare.
[è solo un normale comando, comewhoamiogrep, ma con un nome buffo (vedils -l /bin/[). È una scorciatoia pertest.Se vuoi controllare lo stato di uscita di un certo comando, usa quel comando direttamente.
Se vuoi controllare l'output di un comando, usa
"$(..)"per ottenere il suo output, quindi usatesto[/[[per fare un confronto tra stringhe:
Usa anche ps aux | grep -q "[r]elayevent.sh" in modo da ottenere lo stato di uscita in silenzio invece di stampare qualsiasi cosa su stdout .
Oppure puoi usare pgrep e indirizza il suo output a /dev/null .
Usa prima la seconda condizione perché sarà più efficiente per l'ultimo caso.
Quindi lo script finale sarà come:
#!/bin/bash
COUNTER=0
while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do
sleep 3
let COUNTER+=1
done
Oppure
#!/bin/bash
COUNTER=0
while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do
sleep 3
let COUNTER+=1
done
Non puoi avere una pipa all'interno di [ ... ] . È anche meglio usare pgrep piuttosto che cercare di analizzare l'output di ps :
count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done
I sistemi BSD potrebbero usare pgrep -q ... invece di pgrep ... >/dev/null per scartare l'output effettivo di pgrep , proprio come con il normale grep (siamo interessati solo allo stato di uscita).
Nota come non inseriamo il pgrep comando all'interno di [ ... ] . Questo perché non siamo interessati al suo output, solo al suo stato di uscita. Con [ ... ] di solito confronti stringhe o numeri. Il [ ... ] risulterà in uno stato di uscita che è zero (vero) o diverso da zero (falso), proprio come il pgrep esecuzione.
Tuttavia, questo non controlla alcun meccanismo di blocco, ma solo se un particolare processo è in esecuzione o meno.
Se stai cercando di eseguire solo una singola istanza di uno script, allora è meglio fare qualcosa del genere (supponendo che EXIT trap viene eseguito ogni volta che lo script termina in modo ordinato):
lockdir=dir.lock
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi
Con una serie di tentativi e dormi:
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
Correlati:
- Come assicurarsi che venga eseguita solo un'istanza di uno script bash?