Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 04/10/2021, à 15:53

Tawal

[Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Hello,

Est-il possible d'éviter l'erreur fatale due à un fichier non-existant passé dans la ligne de commande d'awk ?
J'illustre mon propos :
   - soit les fichiers fich1 et fich3 existants et non-vides contenant le mot "test"
Peut-on faire en sorte qu'awk continue le traitement avec ce genre de commande :

awk '{print}' fich1 fichier_inexistant fich3

et éviter l'erreur suivante :

test
awk: ligne de commande:1: fatal : impossible d'ouvrir le fichier « fichier_inexistant » en lecture : Aucun fichier ou dossier de ce type

On voit que le 1er fichier (fich1) est bien traité, puis survient l'erreur due à l'absence de fichier "fichier_inexistant", puis le traitement s'arrête.
J'aimerais éviter cette erreur et continuer le traitement sur fich3.

Merci

Edit:
J'ai essayé avec PROCINFO["NONFATAL"], PROCINFO["FILENAME", "NONFATAL"] sans succès même dans les sections BEGIN et BEGINFILE.
Je ne parle pas du "2>/dev/null" qui ne fait que pas afficher l'erreur ...

Edit2:
J'utilise gawk en lieu et place d'awk wink
Peut-être devrais-je modifier le titre et le message en conséquence ?

Dernière modification par Tawal (Le 04/10/2021, à 18:22)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#2 Le 04/10/2021, à 16:33

ar barzh paour

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

????? une solution
for f in f1 f2 f3 do if f exist then awk ...


PC          : B760M DS3H DDR4,  12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750  @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )

Hors ligne

#3 Le 04/10/2021, à 16:41

Tawal

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

J'avais pensé à ce genre de solution mais elle ne convient pas.
Mon cas particulier est que j'utilise cette expansion de fichiers dans la ligne de commande d'awk (gawk) :

/proc/[0-9]*/status

Et que lors de l'expansion, un fichier peut exister mais peut aussi avoir disparu au moment du traitement (fin du processus associé).
Cela arrive !

J'ai un contournement déjà en place.
Mais je voulais savoir si on pouvait faire en sorte qu'awk (gawk) ignore un fichier inexistant.

Dernière modification par Tawal (Le 04/10/2021, à 17:09)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#4 Le 04/10/2021, à 16:54

Watael

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

awk tout seul, non.
je passerais par un wrapper bash pour construire un tableau sur la base d'un test dans une boucle for...

Dernière modification par Watael (Le 04/10/2021, à 16:57)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#5 Le 04/10/2021, à 17:06

Tawal

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Merci de ta réponse claire concernant awk.

Ta solution emmènerait le même problème de disparition possible du fichier /proc/xxxxx/status entre la boucle for et son passage à awk.
De plus, je ne peux pas exécuter plusieurs awk sur des fichiers différents car je compile et trie les données de ces fichiers via awk.

Merci tout de même de l'idée wink

Mon contournement consiste à tester le code retour d'awk et à le relancer si il est différent de 0 ... jusqu'à ce qu'il ait le temps de traiter tous les fichiers sans aucune disparition.

Dernière modification par Tawal (Le 04/10/2021, à 17:12)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#6 Le 04/10/2021, à 17:50

Watael

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

cat /proc/[0-9]*/status | awk '...' 

?

il faudrait savoir ce que tu veux récupérer comme infos pour former la commande awk, voire le remplacer par sed...


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#7 Le 04/10/2021, à 18:11

Tawal

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

C'est en rapport avec ce sujet : Processus swapés
Il ne me semble pas que sed soit approprié dans ce cas.

Par contre l'utilisation du pipe avec cat doit régler le problème.
Je n'y avais même pas pensé !
C'est un peu un "Useless use of cat", mais qui cette fois est utile et pertinent.

yes.gif

Edit:
Il faut l'utiliser comme ceci car cat rencontre le même problème de disparition qu'awk

cat /proc/[0-9]*/status 2>/dev/null | awk '....'

Preuve du problème de disparition entre l'expansion et le traitement par cat :

$ cat /proc/[0-9]*/status 1>/dev/null
cat: /proc/2012991/status: Aucun fichier ou dossier de ce type
$

Merci.

Dernière modification par Tawal (Le 04/10/2021, à 18:31)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#8 Le 04/10/2021, à 18:42

Watael

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

C'est un peu un "Useless use of cat", mais qui cette fois est utile et pertinent.

alors, ce n'est pas un UUOC. wink

cat et awk n'ont pas le même problème : l'absence de fichier n'arrête pas cat.
mais il postillonne des messages d'erreurs.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#9 Le 04/10/2021, à 18:51

Tawal

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Watael a écrit :

cat et awk n'ont pas le même problème : l'absence de fichier n'arrête pas cat.
mais il postillonne des messages d'erreurs.

Tout à fait, ce que je voulais souligner, c'est que le problème se situe entre l'expansion et le traitement, que ce soit par cat ou par awk wink

Et oui, dans ce cas, ce n'est pas un "Useless Use Of Cat" smile


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#10 Le 08/10/2021, à 14:04

LeoMajor

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

salut,
..:~$ cat check_args.awk

 
#!/bin/gawk
# gawk -f check_args.awk  ~/Musique/* /tmp/root.txt ~/*.txt /tmp/touch.txt  ~/Documents/

func check_args(){
#exclus dossiers, fichiers vides, filesystem erreurs (not found ...), permissions erreurs
count=ARGC-1
for (i=1;i<ARGC;i++){if((getline line < ARGV[i])<=0){ print "ko",ARGV[i],ERRNO; delete ARGV[i]; d++}else{print "ok",ARGV[i]} }
if(count<=d){print "arguments invalides"; exit}
}

func isbinary(f){cmd="file -b --mime-encoding \""f"\" 2>/dev/null"; cmd|getline tmp; if(tmp~/binary/){return 0}else{return 1}; close(cmd) }

func check2_args(){
#exclus binaires, dossiers, fichiers vides, filesystem erreurs (not found ...), permissions erreurs
count=ARGC-1
for (i=1;i<ARGC;i++){if(((getline line < ARGV[i])<=0)||(isbinary(ARGV[i])==0)){print "ko",ARGV[i]; delete ARGV[i]; d++}else{print "ok",ARGV[i]} }
if(count<=d){print "arguments invalides"; exit}
}

BEGIN { check2_args() }
BEGINFILE {c++; print c,FILENAME}

END { print "ARGV:count,delete,newcount,c"; print ARGC-1,"-",d,"=",count-d,c }

si tu ne veux pas inclure les fichiers vides, genre touch /tmp/touch.txt  ,  tu enlèves (=0)

((getline line < ARGV[i])<0)

Hors ligne

#11 Le 08/10/2021, à 17:37

Watael

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

t'aurais pu faire le ménage : la fonction check_args n'est pas utilisée. smile
et on peut se demander si la fonction check2_args est vraiment utile, puisque tu ne l'utilises qu'une seule fois, sans arguments, dans le BEGIN !
voici ta version à peine retouchée (je n'ai pas encore lu en détail), et indentée :

#!/usr/bin/awk -f

function isbinary(f){
    cmd="file -b --mime-encoding \""f"\" 2>/dev/null";
    cmd|getline tmp;
    if(tmp~/binary/){
        return 0
    }else{
        return 1
    };
    close(cmd)
}

BEGIN {
    #exclus binaires, dossiers, fichiers vides, filesystem erreurs (not found ...), permissions erreurs
    count=ARGC-1
    for (i=1;i<ARGC;i++){
        if(((getline line < ARGV[i])<=0)||(isbinary(ARGV[i])==0)){
            print "ko",ARGV[i];
            delete ARGV[i]; d++
        }else{
            print "ok",ARGV[i]
        }
    }
    if(count<=d){
        print "arguments invalides";
        exit
    }
}
BEGINFILE {
    c++;
    print c,FILENAME
}

END {
    print "ARGV:count,delete,newcount,c";
    print ARGC-1,"-",d,"=",count-d,c
}

et l'appel explicite à awk sur la ligne de commande n'est pas indispensable : modifie le shebang en ajoutant l'option -f, et rend le script exécutable.

PS: je ne trouve pas le mot clé func dans le man.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#12 Le 08/10/2021, à 19:39

Tawal

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Hello,

Le principe est plaisant.
Mais problème :

$ file -b --mime-encoding /proc/1/status
binary

Je crois bien que dans ce cas là, il faut se passer de la fonction "isbinary"
Et il faut initialiser d à 0 dans le BEGIN, sinon pas d'affichage de d s'il n'est pas incrémenté.

PS:
Je rappelle que les fichiers scrutés sont /proc/[0-9]*/status wink

Edit:
Avec les modifications dont je parle : (j'ai appelé le script awk-errors)

$ ./awk-errors /proc/[0-9]*/status
ok /proc/1044/status
ok /proc/1045/status
ok /proc/1046/status
ok /proc/1047/status
ok /proc/1051/status
ok /proc/1052/status
ok /proc/1055/status
ok /proc/1056/status
ok /proc/1057/status
ok /proc/1058/status
ok /proc/1060/status
ok /proc/109135/status
ok /proc/10/status
ok /proc/1100/status
ok /proc/11292/status
ok /proc/11316/status
ok /proc/11367/status
ok /proc/113950/status
ok /proc/113994/status
ok /proc/114723/status
ok /proc/11487/status
ok /proc/11496/status
ok /proc/11501/status
ok /proc/11527/status
ok /proc/1186/status
ok /proc/1190/status
ok /proc/1191/status
ok /proc/11/status
ok /proc/124/status
ok /proc/1258/status
ok /proc/1259/status
ok /proc/1262/status
ok /proc/1263/status
ok /proc/126/status
ok /proc/127/status
ok /proc/128/status
ok /proc/12/status
ok /proc/130405/status
ok /proc/131982/status
ok /proc/132/status
ok /proc/133/status
ok /proc/134/status
ok /proc/135/status
ok /proc/136/status
ok /proc/139/status
ok /proc/13/status
ok /proc/140/status
ok /proc/141/status
ok /proc/142/status
ok /proc/143/status
ok /proc/1440/status
ok /proc/1446/status
ok /proc/144/status
ok /proc/145/status
ok /proc/146/status
ok /proc/147176/status
ok /proc/147/status
ok /proc/148/status
ok /proc/149/status
ok /proc/150/status
ok /proc/151/status
ok /proc/152145/status
ok /proc/152/status
ok /proc/153/status
ok /proc/15429/status
ok /proc/1578/status
ok /proc/159513/status
ok /proc/15/status
ok /proc/1613/status
ok /proc/1625/status
ok /proc/164709/status
ok /proc/169976/status
ok /proc/16/status
ok /proc/170435/status
ok /proc/17045/status
ok /proc/171102/status
ok /proc/174/status
ok /proc/17618/status
ok /proc/177048/status
ok /proc/17852/status
ko /proc/179190/status
ok /proc/179225/status
ok /proc/179226/status
ko /proc/179235/status
ok /proc/17977/status
ok /proc/17/status
ok /proc/186/status
ok /proc/1890/status
ok /proc/1899/status
ok /proc/18/status
ok /proc/1900/status
ok /proc/1919/status
ok /proc/1920/status
ok /proc/1921/status
ok /proc/1939/status
ok /proc/1970/status
ok /proc/1983/status
ok /proc/1993/status
ok /proc/1996/status
ok /proc/1/status
ok /proc/2000/status
ok /proc/2011/status
ok /proc/2016/status
ok /proc/2020/status
ok /proc/2027/status
ok /proc/2035/status
ok /proc/2039/status
ok /proc/2048/status
ok /proc/2061/status
ok /proc/2072/status
ok /proc/2075/status
ok /proc/2080/status
ok /proc/2086/status
ok /proc/2087/status
ok /proc/2088/status
ok /proc/2089/status
ok /proc/2090/status
ok /proc/2108/status
ok /proc/2119/status
ok /proc/2120/status
ok /proc/2121/status
ok /proc/2122/status
ok /proc/2221/status
ok /proc/2222/status
ok /proc/233/status
ok /proc/234/status
ok /proc/2357/status
ok /proc/2385/status
ok /proc/23/status
ok /proc/2426/status
ok /proc/2465/status
ok /proc/2470/status
ok /proc/2478/status
ok /proc/2483/status
ok /proc/24/status
ok /proc/25816/status
ok /proc/25828/status
ok /proc/25/status
ok /proc/26029/status
ok /proc/26/status
ok /proc/273/status
ok /proc/27/status
ok /proc/28432/status
ok /proc/28/status
ok /proc/293/status
ok /proc/29/status
ok /proc/2/status
ok /proc/30/status
ok /proc/319/status
ok /proc/31/status
ok /proc/334/status
ok /proc/3/status
ok /proc/47925/status
ok /proc/4/status
ok /proc/50/status
ok /proc/51/status
ok /proc/52/status
ok /proc/53/status
ok /proc/54/status
ok /proc/56/status
ok /proc/57/status
ok /proc/58/status
ok /proc/60/status
ok /proc/646/status
ok /proc/647/status
ok /proc/69/status
ok /proc/71865/status
ok /proc/73/status
ok /proc/74/status
ok /proc/8/status
ok /proc/92910/status
ok /proc/945/status
ok /proc/952/status
ok /proc/97323/status
ok /proc/976/status
ok /proc/979/status
ok /proc/985/status
ok /proc/9/status
1 /proc/1044/status
2 /proc/1045/status
3 /proc/1046/status
4 /proc/1047/status
5 /proc/1051/status
6 /proc/1052/status
7 /proc/1055/status
8 /proc/1056/status
9 /proc/1057/status
10 /proc/1058/status
11 /proc/1060/status
12 /proc/109135/status
13 /proc/10/status
14 /proc/1100/status
15 /proc/11292/status
16 /proc/11316/status
17 /proc/11367/status
18 /proc/113950/status
19 /proc/113994/status
20 /proc/114723/status
21 /proc/11487/status
22 /proc/11496/status
23 /proc/11501/status
24 /proc/11527/status
25 /proc/1186/status
26 /proc/1190/status
27 /proc/1191/status
28 /proc/11/status
29 /proc/124/status
30 /proc/1258/status
31 /proc/1259/status
32 /proc/1262/status
33 /proc/1263/status
34 /proc/126/status
35 /proc/127/status
36 /proc/128/status
37 /proc/12/status
38 /proc/130405/status
39 /proc/131982/status
40 /proc/132/status
41 /proc/133/status
42 /proc/134/status
43 /proc/135/status
44 /proc/136/status
45 /proc/139/status
46 /proc/13/status
47 /proc/140/status
48 /proc/141/status
49 /proc/142/status
50 /proc/143/status
51 /proc/1440/status
52 /proc/1446/status
53 /proc/144/status
54 /proc/145/status
55 /proc/146/status
56 /proc/147176/status
57 /proc/147/status
58 /proc/148/status
59 /proc/149/status
60 /proc/150/status
61 /proc/151/status
62 /proc/152145/status
63 /proc/152/status
64 /proc/153/status
65 /proc/15429/status
66 /proc/1578/status
67 /proc/159513/status
68 /proc/15/status
69 /proc/1613/status
70 /proc/1625/status
71 /proc/164709/status
72 /proc/169976/status
73 /proc/16/status
74 /proc/170435/status
75 /proc/17045/status
76 /proc/171102/status
77 /proc/174/status
78 /proc/17618/status
79 /proc/177048/status
80 /proc/17852/status
81 /proc/179225/status
82 /proc/179226/status
83 /proc/17977/status
84 /proc/17/status
85 /proc/186/status
86 /proc/1890/status
87 /proc/1899/status
88 /proc/18/status
89 /proc/1900/status
90 /proc/1919/status
91 /proc/1920/status
92 /proc/1921/status
93 /proc/1939/status
94 /proc/1970/status
95 /proc/1983/status
96 /proc/1993/status
97 /proc/1996/status
98 /proc/1/status
99 /proc/2000/status
100 /proc/2011/status
101 /proc/2016/status
102 /proc/2020/status
103 /proc/2027/status
104 /proc/2035/status
105 /proc/2039/status
106 /proc/2048/status
107 /proc/2061/status
108 /proc/2072/status
109 /proc/2075/status
110 /proc/2080/status
111 /proc/2086/status
112 /proc/2087/status
113 /proc/2088/status
114 /proc/2089/status
115 /proc/2090/status
116 /proc/2108/status
117 /proc/2119/status
118 /proc/2120/status
119 /proc/2121/status
120 /proc/2122/status
121 /proc/2221/status
122 /proc/2222/status
123 /proc/233/status
124 /proc/234/status
125 /proc/2357/status
126 /proc/2385/status
127 /proc/23/status
128 /proc/2426/status
129 /proc/2465/status
130 /proc/2470/status
131 /proc/2478/status
132 /proc/2483/status
133 /proc/24/status
134 /proc/25816/status
135 /proc/25828/status
136 /proc/25/status
137 /proc/26029/status
138 /proc/26/status
139 /proc/273/status
140 /proc/27/status
141 /proc/28432/status
142 /proc/28/status
143 /proc/293/status
144 /proc/29/status
145 /proc/2/status
146 /proc/30/status
147 /proc/319/status
148 /proc/31/status
149 /proc/334/status
150 /proc/3/status
151 /proc/47925/status
152 /proc/4/status
153 /proc/50/status
154 /proc/51/status
155 /proc/52/status
156 /proc/53/status
157 /proc/54/status
158 /proc/56/status
159 /proc/57/status
160 /proc/58/status
161 /proc/60/status
162 /proc/646/status
163 /proc/647/status
164 /proc/69/status
165 /proc/71865/status
166 /proc/73/status
167 /proc/74/status
168 /proc/8/status
169 /proc/92910/status
170 /proc/945/status
171 /proc/952/status
172 /proc/97323/status
173 /proc/976/status
174 /proc/979/status
175 /proc/985/status
176 /proc/9/status
ARGV:count,delete,newcount,c
178 - 2 = 176 176

Edit2:
Merci de cette solution wink
Mais j'avoue que la présentation par Watael est bien plus claire et lisible wink

Edit3:
En fait, le fichier peut disparaître entre le BEGIN et le corps du programme awk/gawk et donc ramène quand même l'erreur : Aucun fichier ou dossier de ce type.
Donc la 1ère solution proposée par Watael reste la meilleure dans mon cas précis.

Dernière modification par Tawal (Le 08/10/2021, à 23:26)


Le savoir n'a d’intérêt que si on le transmet.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !

Hors ligne

#13 Le 10/10/2021, à 11:33

LeoMajor

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Intuitivement, j'utiliserai "strings", sur un binaire, souvent plus approprié pour explorer les fichiers systèmes, dont on n'est pas sûr, si la sortie sera exploitable (udevadm, ...).
A toi d'essayer, si cela change quelque chose.
Pour awk, le traitement est déporté sur BEGINFILE. Tu devras utiliser les fonctions internes (split, match, patsplit, switch ...)
Il n'y aura rien dans le corps.

...
func astr(f){
cmd="strings \""f"\" 2>/dev/null"
while (cmd|getline tmp){

if(tmp~/^Name/){split(tmp,p," "); print p[2] }

switch (tmp) {
 case /^chocolat:/:
        ....
  	continue
  case /*/:
 }}
close(cmd)
}
BEGIN {d=0; check_args() }
BEGINFILE {c++; print c,FILENAME; astr(FILENAME) }
....

Hors ligne

#14 Le 10/10/2021, à 13:25

Watael

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

les fichiers status sous /proc/N/, ne sont ni des binaires, ni vides, tels que les identifie file. hmm

man proc a écrit :

/proc/[pid]/status                                                                                                                                                                                                                     
              Provides [...] the information [...] in a format that's easier for humans to parse.

un tel fichier ne peut donc être vide, et illisible pour un humain.

$ file -i /proc/1/status
/proc/1/status: inode/x-empty; charset=binary
$

8O


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#15 Le 10/10/2021, à 14:51

MicP

Re : [Résolu] [awk] Éviter l'erreur due à un fichier inexistant

Bonjour

C'est sans doute lié au fait que /proc est une pseudo-filesystem

Hors ligne