Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[bash] grep

8 réponses
Avatar
hugolino
Bonsoir

Dans un petit script, je veux tester la sortie de la commande mailq pour
tester la présence de mails à envoyés.
Je sais que cette commande me retourne (entre autres) une ligne vide par
mail en partance, mais je n'arrive pas à compter ces lignes blanches.
Je cherche à utiliser grep mais je dois mal m'y prendre (et la page de
man ne m'est pas d'un grand secours).
D'ailleurs, est-ce grap qu'il faut utiliser ?

Bref, comment faire ?

--
« C'est l'histoire d'un gars qui veut la machine la plus puissante du
monde sous Windows 95 en émulation sous Wine qui tourne sur une station
FreeBSD avec bibliotheque de compatibilité Linux. »
-+- ST in Guide du linuxien pervers : "A quoi sert Unix ?" -+-

8 réponses

Avatar
Nicolas Le Scouarnec
Je sais que cette commande me retourne (entre autres) une ligne vide par
mail en partance, mais je n'arrive pas à compter ces lignes blanches.


Essaye de compter toutes les lignes qui sont vides ou contiennent des
espaces:

mailq| grep '^ *$' | wc -l



--
Nicolas Le Scouarnec
http://nlsn.free.fr (Slrnfr, Docs Linux/BSD, La grippe, ... )

Avatar
Stephane Chazelas
Compter les lignes vides :

grep -cv .

ou
grep -cv '[^[:blank:]]'
pour compter les lignes blanches.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]
Avatar
Jean-Yves LENHOF
On Mon, 12 Jan 2004 21:23:50 +0100, Hugolino wrote:

Bonsoir

Dans un petit script, je veux tester la sortie de la commande mailq pour
tester la présence de mails à envoyés.
Je sais que cette commande me retourne (entre autres) une ligne vide par
mail en partance, mais je n'arrive pas à compter ces lignes blanches.
Je cherche à utiliser grep mais je dois mal m'y prendre (et la page de
man ne m'est pas d'un grand secours).
D'ailleurs, est-ce grap qu'il faut utiliser ?

Bref, comment faire ?


Pourquoi ne pas regarder ds le rep /var/spool/mqueue directement ?

Jean-Yves

Avatar
hugolino
Le Mon, 12 Jan 2004 23:04:50 +0100, Jean-Yves LENHOF a écrit:
On Mon, 12 Jan 2004 21:23:50 +0100, Hugolino wrote:

Dans un petit script, je veux tester la sortie de la commande mailq pour
tester la présence de mails à envoyés.
Bref, comment faire ?


Pourquoi ne pas regarder ds le rep /var/spool/mqueue directement ?


Merci de me répondre.

Tout simplement par ce que j'utilise Postfix et qu'il créé, un peu au
hasard, deux fichiers pour chaque mail en partance dans une
arborescence sous /var/spool/postfix/ qui contient seulement 699
répertoires :/


--
Hugo NPN -<°o))
Il [e2fsck] a bien démarré, mais il m'a rendu la main aussitot en me
disant "houlala, c'est pas beau à voir votre truc, je préfèrerai que
vous teniez vous meme la tronçonneuse" -+- NC in GLP -+-



Avatar
hugolino
Le Mon, 12 Jan 2004 22:46:15 +0100, Stephane Chazelas a écrit:
Compter les lignes vides :

grep -cv .


-c : Ne pas afficher les résultats normaux...

OK je comprends, je ne veux pas un ensemble lignes blanches, je veux le
nombre de ses lignes blanches.


-v : Inverser la mise en corespondance, pour sélectionner les lignes ne
correspondant pas au motif...

Là je ne comprends plus, pourquoi inverser la mise en correpondance ? Ou
alors c'est le motif que je ne comprends pas.

A froid je dirais que ^[:blank:] est un motif correspondant à la classe
blank trouvée au début de chaîne, sauf si le signe ^ (d'après ce que
j'ai compris de la page man de bash) signifie qu'on inverse la
sélection, puis qu'on réencadre le tout avec des crochets pour créer une
nouvelle classe pour finalement faire évaluer le tout par bash avec ''
(pourquoi pas ``, d'ailleurs ?).

Mais alors on inverse deux fois la chose, une fois avec bash puis une
deuxième fois avec grep, pour finalement retomber sur nos pattes. Bref
ça m'interpelle...



ou
grep -cv '[^[:blank:]]'
pour compter les lignes blanches.


Pourquoi mailq > grep -sv '[^[:blank:]]' ne jette-t-il avec un "mailq:
fatal: display queue mode requires no recipient" alors que avec un "|",
ça fonctionne ?
Jusqu'à présent je croyais que tout était fichier sous unix, mais je
m'aperçois que la première commande essayée impose de passer par un
fichier réel ("mailq > TestMail" puis "grep -cv '[^[:blank:]]' TestMail"
marche bien).

Bref je croyais que stdin, stdout et stderr étaient des fichiers...



Merci de l'aide que vous m'apportez.

--
les débilos qui ont décrété qu'il fallait tout éteindre pendant le w.e.!!
define(`Y2K_Auto_Purge_Queue',`True')dnl

define(`Y2K_Auto_Murge_Admin',`True')dnl
-+- fyr in Guide de l'admin pervers - "Ne pas gâcher son nouvel an" -+-

Avatar
Stephane Chazelas
2004-01-14, 00:32(+01), Hugolino:
Le Mon, 12 Jan 2004 22:46:15 +0100, Stephane Chazelas a écrit:
Compter les lignes vides :

grep -cv .


-c : Ne pas afficher les résultats normaux...


-c
Write only a count of selected lines to standard
output.


-v : Inverser la mise en corespondance, pour sélectionner les lignes ne
correspondant pas au motif...


".", c'est un caractère. Tu veux les lignes qui *ne*
contiennent *pas* le moindre caractère.

A froid je dirais que ^[:blank:] est un motif correspondant à la classe
blank trouvée au début de chaîne, sauf si le signe ^ (d'après ce que
j'ai compris de la page man de bash) signifie qu'on inverse la
sélection, puis qu'on réencadre le tout avec des crochets pour créer une
nouvelle classe pour finalement faire évaluer le tout par bash avec ''
(pourquoi pas ``, d'ailleurs ?).o


[:blank:], c'est une "POSIX class", c'est équivalent à 4010
(space et tab), ce qui est confusing, c'est les [] comme dans
les "range" [a-z] mais ça n'a rien à voir (par contre, on
n'utilise les "class" qu'à l'intérieur des "range expression".
Faut voir que les délimiteurs d'une "character class" sont "[:"
et ":]".

[^abc], c'est n'importe quel caractère sauf a ou b ou c.
[^[:blank:]], c'est n'importe quel caractère sauf ceux de
"class" "blank".

grep -cv '[^[:blank:]]'
ça compte donc les lignes qui ne contiennent pas le moindre
charactère qui ne soit pas de "class" blank (donc qui ne
contiennent que des blancs).


Mais alors on inverse deux fois la chose, une fois avec bash puis une
deuxième fois avec grep, pour finalement retomber sur nos pattes. Bref
ça m'interpelle...


Ya pas de bash là-dedans. Tu confonds avec les [a-z] de la
filename generation ou de "case". Ici, on a mis des '...' autour
de l'argument pour éviter que le shell ne fasse d'interpretation
sur ces caractères. Si on n'avait pas mis de '...', le shell
aurait cherché dans le répertoire courant les fichiers dont le
nom est composé d'un seul caractère non blanc, et aurait donc
lancé la commande grep avec des paramètres comme "A", "a",
"1"... au lieu du paramètre intact "[^[:blank:]]".

ou
grep -cv '[^[:blank:]]'
pour compter les lignes blanches.


Pourquoi mailq > grep -sv '[^[:blank:]]' ne jette-t-il avec un "mailq:
fatal: display queue mode requires no recipient" alors que avec un "|",
ça fonctionne ?


Parce que ça lance la commande "mailq -sv '[^[:blank:]]'" avec
sa sortie standard redirigée vers le fichier "grep" créé dans
le répertoire courant (la place du "> fichier" est indifférente
dans une ligne de commande).

Jusqu'à présent je croyais que tout était fichier sous unix, mais je
m'aperçois que la première commande essayée impose de passer par un
fichier réel ("mailq > TestMail" puis "grep -cv '[^[:blank:]]' TestMail"
marche bien).

Bref je croyais que stdin, stdout et stderr étaient des fichiers...


Oui, et ?

Dans:

cmd1 | cmd2

stdout de cmd1 est un "unnamed pipe" qui peut si tu veux être
considéré comme un fichier. Mais il faut bien voir qu'on a là
deux commandes lancées en parallèle avec un pipe entre elles
deux, ce qui est très différent d'un "cmd > fichier" qui
n'implique qu'une commande. La lancement d'une commande n'est
pas un fichier, si c'est ça que tu veux dire. Le lancement d'une
commande est le lancement d'un appel système execve (quand il
s'agit d'une commande externe). execve prend en paramètre un
fichier, certes. Mais le système ne fait que le charger en
mémoire et exécuter le code qui s'y trouve (avec
l'environnement (fichiers ouverts, "environnement" (par
convention)) qu'avait le processus avant (qu'il a hérité de son
père s'il y a eu un fork).

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]


Avatar
hugolino
Le Wed, 14 Jan 2004 09:32:27 +0100, Stephane Chazelas a écrit:
2004-01-14, 00:32(+01), Hugolino:
Le Mon, 12 Jan 2004 22:46:15 +0100, Stephane Chazelas a écrit:

grep -cv .


-c : Ne pas afficher les résultats normaux...


-c
Write only a count of selected lines to standard
output.


Un moment j'ai cru qu'on n'avait pas la même page de man, mais tu as
raison (et ma page est bonne), je l'ai simplement lu trop vite.
Donc pardon pour la question.


[:blank:], c'est une "POSIX class", ... <cut>


OK, pigé.


Ya pas de bash là-dedans... <cut>


OK, pigé.


Pourquoi mailq > grep -sv '[^[:blank:]]' me jette-t-il avec un "mailq:
fatal: display queue mode requires no recipient" alors que avec un "|",
ça fonctionne ?


Parce que ça lance la commande "mailq -sv '[^[:blank:]]'" avec
sa sortie standard redirigée vers le fichier "grep" créé dans
le répertoire courant (la place du "> fichier" est indifférente
dans une ligne de commande).


Tu as raison, je viens de trouver un fichier "grep" dans mon home... qui
contient le résultat de la commande, c'est à dire qu'il est vide.


Jusqu'à présent je croyais que tout était fichier sous unix, mais je
m'aperçois que la première commande essayée impose de passer par un
fichier réel ("mailq > TestMail" puis "grep -cv '[^[:blank:]]' TestMail"
marche bien).

Bref je croyais que stdin, stdout et stderr étaient des fichiers...


Oui, et ?


Bin... euh... ;-)


Dans:
cmd1 | cmd2

stdout de cmd1 est un "unnamed pipe" qui peut si tu veux être
considéré comme un fichier. Mais il faut bien voir qu'on a là
deux commandes lancées en parallèle...


"parallèle", cela signifie-t-il bien que les deux commandes s'exécutent
en même temps ? Ou plus exactement que Bash évalue cette ligne de
commande et décide de l'ordre d'exécution.

...avec un pipe entre elles
deux, ce qui est très différent d'un "cmd > fichier" qui
n'implique qu'une commande. La lancement d'une commande n'est
pas un fichier, si c'est ça que tu veux dire. Le lancement d'une
commande est le lancement d'un appel système execve (quand il
s'agit d'une commande externe). execve prend en paramètre un
fichier, certes. Mais le système ne fait que le charger en
mémoire et exécuter le code qui s'y trouve (avec
l'environnement (fichiers ouverts, "environnement" (par
convention)) qu'avait le processus avant (qu'il a hérité de son
père s'il y a eu un fork).



Je te remercie du temps que tu as pris pour me répondre. Pour l'instant
j'essaye de lire plus souvent ce groupe que je n'y poste, et ça
m'apprend plein de choses grâce à la qualité de ses contributeurs.
(J'ai déjà plusieurs threads de fcou sauvé sur mon dur).


--
On va peut-être savoir si un FreeBSDiste peut se reproduire avec un
linuxien.
Ah ! C'est ça HURD ?

-+- fyr in Guide du linuxien pervers - "Linux transgenique" -+-



Avatar
Stephane Chazelas
2004-01-16, 04:24(+01), Hugolino:
[...]
Dans:
cmd1 | cmd2

stdout de cmd1 est un "unnamed pipe" qui peut si tu veux être
considéré comme un fichier. Mais il faut bien voir qu'on a là
deux commandes lancées en parallèle...


"parallèle", cela signifie-t-il bien que les deux commandes s'exécutent
en même temps ? Ou plus exactement que Bash évalue cette ligne de
commande et décide de l'ordre d'exécution.
[...]


Bash ne décide pas grand chose là dedans. Il faut bien voir
qu'un "|" n'est pas un opérateur de redirection. Quand il y a un
pipe, le shell :

cree un pipe (par l'appel systeme pipe(2)), qui est un tuyau, un
buffer en mémoire du système, en FIFO, avec un file descriptor
pour l'entree et un file descriptor pour la sortie de tuyau.

crée ensuite deux fils (au moyen de l'appel système fork). (en
fait, c'est fork, pipe puis fork dans le fils).

Dans le premier fils, redirige la sortie standard sur l'entree du pipe
(dup2(entree_du_pipe_fd, 1)) et execute la commande de gauche du
"|" et dans l'autre redirige l'entree standard depuis la sortie
du pipe (dup2(sortie_du_pipe_fd, 0)) et execute la commande de
droite.

Le père attend la terminaison des deux fils qui ont leur
exécution propre et indépendante (si ce n'est ce tuyau sur
lequel ils ont chacun un fd d'ouvert).

un "|" implique donc deux commandes lancées en même temps en
parallèle reliées entre elles par un pipe.

--
Stéphane ["Stephane.Chazelas" arobase "free.fr"]