Prévenir grep retourner une erreur lors de la saisie ne correspond pas à
Je veux écrire dans un script bash un morceau de code qui vérifie si un programme est déjà en cours d'exécution.
J'ai le texte suivant dans le but de rechercher si la barre est en cours d'exécution
foo=`ps -ef | grep bar | grep -v grep`
La
grep -v grep
partie est de veiller à ce que le "grep bar" n'est pas pris en compte en ps des résultats
Lorsque la barre n'est pas en cours d'exécution, foo est bien vide. Mais mon problème réside dans le fait que le script a
set -e
qui est un indicateur de terminer le script si certains de commande retourne une erreur.
Il s'avère que lorsque la barre n'est pas en cours d'exécution, "grep -v grep" ne correspond pas avec n'importe quoi et grep renvoie une erreur. J'ai essayé d'utiliser -q ou -s, mais en vain.
Est qu'il ya une solution pour cela? Thx
- Notez que
set -e
n'est pas bash-spécifique, mais plutôt s'applique à tout compatible POSIX shell (sh
etc.)
Vous devez vous connecter pour publier un commentaire.
Sûr:
Ou encore:
grep
retourne 1 pour ne pas avoir de matchs, mais qu'advient-il si il renvoie 2 (par exemple, erreur)?grep $options || true
ignore les erreurs réelles! J'ai proposé une nouvelle réponse: stackoverflow.com/a/49627999/307637Un bon truc pour éviter
grep -v grep
est-ce:Cette expression régulière seulement correspond à la chaîne "bar". Toutefois, dans le
ps
de sortie, la chaîne "bar" n'apparaît pas avec la commande grep processus.Dans les jours avant, j'ai appris
pgrep
, j'ai écrit cette fonction pour automatiser la commande ci-dessus:Puis,
se transforme en
grep [b]ar
et le expression régulière[b]ar
ne peut pas correspondre à la string[b]ar
-- la regex va correspondre exactement à 3 caractères, tandis que la chaîne de caractères contient 5 caractèresPourquoi demander
ps
de fournir des quantités massives de sortie avec-ef
si vous n'allez jeter 99% de celui-ci?ps
et surtout la version GNU est un couteau suisse de la pratique de la fonctionnalité. Essayez ceci:Je précise
-o pid=
ici tout simplement parce que, mais en fait c'est inutile puisqu'on jette tout de stdout de toute façon. Il serait utile si vous avez voulu savoir sur la vie réelle PID, si.ps
automatiquement sera de retour avec un zéro existe pas de statut si-C
ne correspondent à rien et avec zéro si elle correspond. Donc, vous pouvez tout simplement dire ceOu
N'est-ce pas plus simple? Pas besoin de grep, et pas deux ou même une seule fois.
grep
qui peut être utilisé avec n'importe quelle entrée, non seulement deps
.Réponse courte
Écrire
si vous utilisez
set -e
.Si vous utilisez bash est
pipefail
option (set -o pipefail
), n'oubliez pas d'appliquer la gestion des exceptions (||test
) à chaquegrep
dans le pipeline:Dans scripts shell je vous suggérons d'utiliser le ”catch-1-grep“ (c1grep) la fonction d'utilité:
Expliqué
grep
's statut de sortie est 0, 1 ou 2: [1]0
signifie une ligne est sélectionnée1
signifie pas de lignes ont été sélectionnés2
signifie qu'une erreur s'est produitegrep
peut également renvoyer à d'autres codes, si il est interrompu par un signal (par exemple,130
pour SIGINT).Puisque nous voulons ignorer statut de sortie
1
, nous utilisonstest
de supprimer cette spécifique statut de sortie.grep
retourne0
,test
n'est pas exécutée.grep
retourne1
,test
est exécuté et retourne0
.grep
retourne toute autre valeur,test
est exécuté et retourne1
.Dans le dernier cas, le script se terminera immédiatement en raison de l'
set -e
ouset -o pipefail
. Toutefois, si vous n'avez pas de soins surgrep
erreurs à tous, vous pouvez bien sûr écrirecomme suggéré par Sean.
[autres] utilisation dans des scripts shell
Dans les scripts shell, si vous utilisez
grep
beaucoup, je vous suggère de définir une fonction d'utilité:De cette façon, votre tuyau d'obtenir à court & plus simple encore, sans perdre les caractéristiques de
set -e
etset -o pipefail
:FYI:
c1grep
à souligner c'est tout simplement la capture de statut de sortie1
, rien d'autre.grep
à la place (grep() { env grep "$@" ...; }
), mais je préfère moins à confusion et nom plus explicite,c1grep
.[1]
grep
page de manuelEssayer de faire en sorte:
chat retourne toujours 0 et ignore le code de sortie grep
not found
un. Cette solution permettra également échoue dans le cas de modes causé par leset -e
ouset -o pipefail
commandes.