Instance unique de script, mais seulement avec les mêmes arguments

J'ai ce beau petit code ici qui sortira d'un script s'il y a une autre instance en cours d'exécution:

single_instance(){ if pidof -x "${0##*/}" -o %PPID >/dev/null; then exit 0 fi } 

Mais ce que je cherche est une fonction qui ne sortira que si le script a été appelé avec les mêmes arguments .

Je sais que je pourrais pirater mon path avec un cat | grep | awk | cut | sed | tac | sort | uniq cat | grep | awk | cut | sed | tac | sort | uniq cat | grep | awk | cut | sed | tac | sort | uniq , mais je me request s'il existe un moyen simple de le faire avec des utilitaires comme pidof , ps , etc.

Comment vas-tu faire ça?

 fn() { IFS=' '; set -- $(ps -o args= -C "${0##*/}") unset IFS [ $(($(printf $(printf %s\\n "$@" | sort | uniq -c | sort -rn)))) -gt 1 ] && exit 0 } 

Cela quittera exit 0 si au less deux process $0 sont en cours d'exécution et ont été invoqués avec les mêmes arguments.

Vous pouvez faire quelque chose comme ceci:

 #!/bin/bash single_instance() { pid=$(pidof -x "${0##*/}" -o %PPID) if [[ $(xargs -0 < /proc/$pid/cmdline) == $@ ]] then echo QUITTING exit 1 fi } single_instance $(xargs -0 < /proc/$$/cmdline) while : do sleep 10 done 

Je suis venu avec cela après avoir étudié l' man ps et en ajoutant du code de @goldilocks. Il fait du bon travail dans la gestion des arguments avec des espaces, et fonctionne aussi si le script s'appelle bash scriptname :

 single_instance(){ if ps -efww | grep "$(ps -o cmd= -p $$)$" | grep -vq " $$ "; then exit 0 fi } 

Utilisation de / proc :

 single_instance(){ local tl=$(cat /proc/$$/cmdline) local l tl=${tl##*/} for pid in $(pidof -x "${0##*/}" -o %%PPID); do l=$(cat /proc/$pid/cmdline) if [ ${l##*/} = $tl ]; then echo "already running..." exit 0 fi done } 

Il fait une comparaison exacte entre les lignes de command sans le path de lancement (comme vous l'avez fait dans votre script). Les valeurs /proc/*/cmdline ne contiennent aucun espace, vous pouvez donc les comparer directement. Si l'ordre des parameters change cependant, il ne le remarquera pas.