OVH Cloud OVH Cloud

awk: badly formed pattern

17 réponses
Avatar
Hugolino
Bonjour,

Je fais à nouveau appel aux lumières du forum (ma route vers la
connaissance de awk et sed ne dispose pas d'éclairage nocturne :)

Je cherche à réparer une debian/etch dont le root était monté sur une
autre machine dans /mnt/Cassis et depuis laquelle j'ai malheureusement
exécuté un rm -rf /mnt/Cassis/$PZD.

J'ai réussi à recopier les fichiers du package libc6 qui avaient
dégagés, ainsi que toutes les librairies qui provoquait un message
"error while loading shared libraries"
et j'ai fini par pouvoir exécuter:

dpkg --get-selections > pkg-k6

pour avoir la liste de tous les packages du système cassé.
Ce fichier est de la forme:
adduser install
afterstep install
...

J'arrive à faire:

for pkg in $(awk '/lib/ {print $1}' pkg-k6); do echo -n " "$pkg ; done

qui me renvoie bien sur une seule ligne de 2359 octets les 200 packages
de lib à réinstaller.

mais quand je pipe cette commande sur

| aptitude reinstall -

le système
répond "E: Badly formed pattern"

J'ai essayé de bidouiller avec la variable IFS, mais j'ai continué à
avoir la même erreur.


Que dois-je corriger dans ma ligne de commande ?

Plus généralement, n'y aurait-il pas eu plus simple, parce que elle sent
un peu le "Useless Use Of Echo" ?


Evidement puisque je travaille sur un système cassé (dieu merci un ssh
était resté ouvert), on pourra me dire que mon erreur vient de là.

Merci de votre aide


--
Windows: Microsoft's tax on computer illiterates.
Hugo (né il y a 1 367 938 034 secondes)

7 réponses

1 2
Avatar
Hugolino
Le Sun, 02 Sep 2007 18:27:15 +0200, Thierry PINELLI a écrit:
Hugolino wrote:

C'est sous quelle licence ? :)


<007 ON>

License to kill

<007 OFF>


Aaahhhh !!! Un revenant !


--
Tu as lu les docs. Tu es devenu un informaticien. Que tu le veuilles ou non.
Lire la doc, c'est le Premier et Unique Commandement de l'informaticien.
Hugo (né il y a 1 368 246 372 secondes)


Avatar
Hugolino
On 1 sep, 10:51, Stephane Dupille wrote:

Un argument est ce qui désigne les données que l'utilisateur peut
fournir au programme.


En quelque sorte, oui. Les arguments sont des « mots » qu'on donne à
un programme. C'est ce que tu tapes après le nom de la commande.

Si on est en CLI ce peut être un mot qu'on ajoute quand on appelle
le programme (dont le nom est un d'ailleurs un argument du shell).
Une option est un argument. Un paramètre est un argument.


Là, non.


Un paramètre ou une option n'est pas une donnée fournie par
l'utilisateur ?

On peut voir l'entrée standard comme un fichier virtuel.
Techniquement, c'est un flux, en fait. C'est un fichier qui est
ouvert par défaut à un programme, et qui sert à lui passer des
données, ou pas.

Un programme a toujours trois fichiers de ce type :
- l'entrée standard (stdin), ouvert en lecture seule ;
- la sortie standard (stdout), ouvert en écriture seule ;
- la sortie d'erreur standard (stderr), ouvert en écriture seule.


Oui.

un programme n'affiche pas son résultat à l'écran, mais toujours sur
sa sortie standard qui peut être branchée vers l'écran (techniquement,
le terminal), ou pas.


OK

Il est possible de rediriger le flux de la sortie standard avec
l'entrée standard d'un autre programme.

Par exemple : cat va écrire sur la sortie standard le contenu d'un
fichier.
[...]

Grep est une commande qui permet de filtrer ce qu'on lui donne sur son
entrée standard. Par exemple, on peut dire à grep de ne sortir que ce
qui contient « ba » :

$ cat fic | grep ba
bar
foobar
baz
$

Ici, grep ne voit jamais le fichier fic, elle ne sait même pas qu'il
existe. La preuve, en utilisant l'option « -l » de grep, qui permet de
forcer l'affichage du nom du fichier, au lieu d'afficher le résultat
de la recherche :

$ cat fic | grep -l ba
(standard input)

Il est aussi possible de demander à grep de chercher dans un fichier,
en lui fournissant son nom :

$ grep -l ba fic
grep -l ba fic
fic

La différence, c'est qu'ici on a fournit à grep un « mot », juste
une chaine de caractères. Grep a été programmé pour prendre ça comme
un nom de fichier, donc il va ouvrir le fichier, et chercher dedans.
Ici, grep manipule le fichier.

Alors que quand on lui envoie fic par l'entrée standard, c'est
directement le contenu qu'on lui envoie. Pas le contenu lui même.
^^^^^^^^^^ ^^^^^^^^^^^^^^

Plait-il ?

Par exemple, nous pouvons chainer les grep :


Oui.

[...]

Sinon, pour la température du système, ce n'est pas lu sur l'entrée
standard (le premier grep au dessus n'envoie pas la température au
second), mais effectuée par une autre méthode : un appel système. En
gros, le programme va cogner à la porte du système et hurler « file
moi la température ! », le système, couard comme pas deux, va lui
filer en tremblotant.


Les appels systèmes n'utilisent pas les flux ? Pourquoi ?



--
On obtient plus en étant poli et armé qu'en étant juste poli.
Hugo (né il y a 1 368 246 977 secondes)


Avatar
Stephane Dupille
Si on est en CLI ce peut être un mot qu'on ajoute quand on appelle
le programme (dont le nom est un d'ailleurs un argument du shell).
Une option est un argument. Un paramètre est un argument.
Là, non.

Un paramètre ou une option n'est pas une donnée fournie par

l'utilisateur ?


Pb de copier/coller, pardon. En fait, je répondais à :
L'entrée standard (stdin) désigne toutes les données que le programme
lit en entrée. Exemple, la date du système, la température du proc ou
whatever.

Alors que quand on lui envoie fic par l'entrée standard, c'est
directement le contenu qu'on lui envoie. Pas le contenu lui même.
^^^^^^^^^^ ^^^^^^^^^^^^^^

Plait-il ?


C'est directement le contenu qu'on lui envoit, pas le fichier lui
même.


Sinon, pour la température du système, ce n'est pas lu sur l'entrée
standard (le premier grep au dessus n'envoie pas la température au
second), mais effectuée par une autre méthode : un appel système. En
gros, le programme va cogner à la porte du système et hurler « file
moi la température ! », le système, couard comme pas deux, va lui
filer en tremblotant.
Les appels systèmes n'utilisent pas les flux ? Pourquoi ?



Non, les appels systèmes fonctionnent autrement. Les flux stdin,
stdout et stderr servent aux processus pour communiquer entre eux (via
des pipes par exemple), ou pour communiquer avec son environnement
(terminal, ou autre chose). Les appels systèmes passent par un autre
mécanisme.

Pourquoi ? Parce que communiquer avec le terminal pour envoyer le
résultat de la commande n'est pas du tout la même chose que faire
des appels systèmes. Pour savoir comment marche un appel système :
man 2 syscall



Avatar
Thierry B.
--{ Stephane Dupille a plopé ceci: }--

Pourquoi ? Parce que communiquer avec le terminal pour envoyer le
résultat de la commande n'est pas du tout la même chose que faire
des appels systèmes. Pour savoir comment marche un appel système :
man 2 syscall


Donc quand mon programme écrit son blabla dans le terminal,
il n'utilise pas d'appel système ?



Dans ce cas, write() c'est quoi ? De la magie noire ?


--
"Tu vas voir avec internet à l'école, les petits ils vont se faire la
tête qui enfle et se barrer à la ville, et nous, on ira crever à
l'hospice avec des tuyaux dans la bouche. Allez, ressers-nous la
tournée, internet, ça me donne la transpiration."

Avatar
Stephane Dupille
Pourquoi ? Parce que communiquer avec le terminal pour envoyer le
résultat de la commande n'est pas du tout la même chose que faire
des appels systèmes. Pour savoir comment marche un appel système :
man 2 syscall
Donc quand mon programme écrit son blabla dans le terminal,

il n'utilise pas d'appel système ?


Ce n'est pas ce que j'ai dit, et ce n'était pas la discussion. Ce
qui a été dit, c'est que les appels systèmes et stdout sont deux
choses différentes. Ce n'est pas parce que l'un utilise l'autre qu'on
peut les mélanger.

Relis l'enfilade.

Dans ce cas, write() c'est quoi ? De la magie noire ?


et sbrk, ça permet d'écrire sur le terminal ?


Avatar
Thierry B.
--{ Stephane Dupille a plopé ceci: }--

Ce n'est pas ce que j'ai dit, et ce n'était pas la discussion. Ce
qui a été dit, c'est que les appels systèmes et stdout sont deux
choses différentes. Ce n'est pas parce que l'un utilise l'autre qu'on
peut les mélanger.

Non, stdout est un canal d'entrée/sortie auquel on accède par

l'appel système write, éventuellement "surchargé" par printf
et sa famille.

Relis l'enfilade.


J'ai relu.

Dans ce cas, write() c'est quoi ? De la magie noire ?


et sbrk, ça permet d'écrire sur le terminal ?


Non, sbrk c'est encore un autre appel système.


--
On ne peur pas connaître d'avance la taille de STDIN? Il n'y a
pas de sizeof(stdin)?
--{ JP: le C n'est pas omniscient ? }--


Avatar
Stephane Dupille
Non, stdout est un canal d'entrée/sortie auquel on accède par
l'appel système write, éventuellement "surchargé" par printf
et sa famille.


Bien, donc stdout est un canal d'entrée/sortie (en fait, de sortie
seulement), et n'est donc pas un appel système. Nous sommes donc
finalement d'accord.

Relis l'enfilade.
J'ai relu.



Et le rapport est, mis à part couper les cheveux en quatre ?
L'objectif de mon message était de clarifier la différence entre les
arguments d'une commande et stdin, pas perdre le débutant dans les
subtilités des appels systèmes.

Dans ce cas, write() c'est quoi ? De la magie noire ?
et sbrk, ça permet d'écrire sur le terminal ?

Non, sbrk c'est encore un autre appel système.



Dingue, lui aussi permet d'écrire dans stdout ? Incroyable !



1 2