Utiliser Enterprise Linux 5/6, Bash 4.x Je veux ce type de logique:
# IF temp file exists, exit because we are restarting already find /tmp/restarting_server -mmin -10 -exec exit 1 lsof -i TCP:1234 || declare Server_is_down=TRUE if ! [ -z $Server_is_down ]; then restart_server fi # Restart Server Function restart_server() { touch /tmp/restarting_server service server restart rm -f /tmp/restarting_server }
Le problème est de find -exec n'aime pas les builtins il semble. Je sais que je peux faire une déclaration si pour vérifier le file et quitter, mais je veux savoir comment faire cela dans une search -exec (ou je me contenterais d'une bonne solution xargs).
while [ -f /tmp/restarting_server ] ; do { [ $((i=i+1)) -ge 10 ] && exit 1 sleep 1 } ; done
Vous n'avez pas besoin de find
si vous connaissez déjà le nom de file, le nom de path et les conditions dans lesquelles un file doit être trouvé de façon acceptable.
Donc, l'autre problème – sortir votre script de votre déclaration -exec
– n'est peut-être pas le problème que vous considérez comme étant. find
ne construit pas d'option pour kill
son shell parent car le shell le fournit déjà.
find … -exec sh -c kill\ $$ \;
Considérez aussi que vous pouvez utiliser cette construction pour la signalisation basée sur des paths existants même si vous n'êtes pas sûr d'avance où ils seront:
trap 'stuff to do' USR1 … #later… find … -exec sh -c kill\ -USR1\ $$ \;
Et cela ouvre beaucoup d'autres options à vous aussi:
find … -exec sh -c exec…
MODIFIER:
Je viens de penser à d'autres options impliquant l' parameter expansion
pour faire sortir votre shell sans find
-exec
du tout qui pourrait être utilisé d'autres façons:
hold_file="$(find . -name file)" ${hold_file:+false} : || exit 1
ou
N= ; hold_file="$(find . -name file)" ${hold_file:+${N:?lock file remains, exiting...}}
Ces deux ne provoquent une sortie que si la variable à laquelle vous assignez stdout
n'est ni null
ni désactivée. Et bien sûr, si vous souhaitez échouer sur la base d'une search vide, vous pouvez faire la même chose avec :-
au lieu de :+
et en omettant complètement la variable valeur $N
.
Ou juste pour modifier le statut de sortie de find
:
$(find . -name file -exec echo false \; ) : || exit 1
Vous pouvez vérifier si le résultat est returnné:
[ -z "$(find /tmp/restarting_server -prune -mmin -10)" ] || exit 1
Vous pouvez simplement faire ceci:
if [ "$(find /tmp -maxdepth 1 -mindepth 1 -name restarting_server -mmin -10)" = '/tmp/restarting_server' ] then exit 1 fi
Cela fonctionne même si vous utilisez set -o errexit
(que vous devriez).
find
est un programme qui lui est propre. L'argument de -exec
est une autre command. Quand une command comme find … -exec foo {} \;
est exécuté, le shell find
un sous-process, et chaque instance de foo
est un sous-process de find
. La command exit
n'existe que comme shell embedded, pas comme une command indépendante; un programme de exit
serait impossible puisqu'il devrait faire sortir son process parent.
La solution à votre problème immédiat est donc de faire en sorte que find
signale s'il a trouvé un file ou non, et de faire sortir le shell s'il y avait une correspondance. Vous ne pouvez pas utiliser le statut de return de find
, car il considère l'absence de correspondance comme une raison de succès. Au lieu de cela, testez la sortie.
if [ -n "$(find /tmp/restarting_server -mmin -10)" ]; then exit; fi
Ici, le file devrait être un file normal s'il existe du tout. Cependant, en général, le file pourrait être un directory, auquel cas find
le traverserait. Alors dites à find
à s'arrêter quand il trouve un match.
if [ -n "$(find /tmp/restarting_server -mmin -10 -prune)" ]; then exit; fi
Cependant, le script résultant n'est pas fiable. Vous n'appliquez pas un verrou correctement. Si deux instances du script commencent presque au même moment, il est possible d'avoir, par exemple:
restarting_server
et se poursuit joyeusement. restarting_server
et se poursuit joyeusement. /tmp/restarting_server
. /tmp/restarting_server
. service server restart
. service server restart
. /tmp/restarting_server
. rm -f /tmp/restarting_server
qui ne fait rien. Appelez le flock
pour mettre en œuvre le locking approprié.
( lsof -i TCP:1234 >/dev/null || service server restart ) 3>/var/lock/maybe_restarting_server
Vous n'avez pas besoin d'un timeout d'attente pour invalider le locking lors du redémarrage, car le locking est conservé en memory.