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

Probl=c3=a8me "basique" de scripting...

11 réponses
Avatar
David BERCOT
Bonjour,

Je viens de ré-installer mon système suite à un plantage et,
bizarrement, un script tout simple ne fonctionne plus correctement.
Malgré divers tests et recherches, j'avoue que  je ne comprends pas bien...

Le voici :
#!/bin/bash

if [ -e "/etc/apt/sources.list.d/*" ]
then
    rm /etc/apt/sources.list.d/*
fi

En doublant les crochets, ça ne change rien.
En supprimant les quotes, j'ai l'erreur suivante : ligne 3 : [: trop
d'arguments (que je ne comprends pas non plus d'ailleurs)...
J'ai bien des fichiers dans /etc/apt/sources.lists.d/ [je coupe court à
tout commentaire sur le sujet : ce n'est pas le problème ;-)] mais il
fait comme si ce n'était pas le cas.

Auriez-vous une piste ?

Merci d'avance.

David.

10 réponses

1 2
Avatar
raphael.poitevin
David BERCOT writes:
#!/bin/bash
if [ -e "/etc/apt/sources.list.d/*" ]
then

il manque un ; après le ]
    rm /etc/apt/sources.list.d/*
fi

--
Raphaël
Hypra S.A.S.
Avatar
Francois Lafont
Hello,
On 09/08/2017 11:57 AM, David BERCOT wrote:
if [ -e "/etc/apt/sources.list.d/*" ]
then
rm /etc/apt/sources.list.d/*
fi

Je ne suis pas sûr d'avoir compris comment était
ton code à l'origine mais je pense qu'il n'était
pas correct (ce qui ne l'a pas empêché de marcher
pendant un certain temps semble-t-il).
Avec les doubles quotes, tu demandes à bash de
tester si un fichier qui s'appelle * (avec vraiment
comme nom juste le caractère *) existe dans le
répertoire /etc/apt/sources.list.d/. Et on imagine
bien que ce n'est pas ce que tu veux demander à
bash.
Sans les doubles quotes, là le caractère * devient
spécial et bash le développe en fonction de ce qu'il
y a dans ton répertoire.
Par exemple si dans /etc/apt/sources.list.d/, tu as
titi.list et toto.list (et c'est tout) alors tout
va se passer comme si tu avais écris :
[ -e /etc/apt/sources.list.d/titi.list /etc/apt/sources.list.d/toto.list ]
et là tu as fort logiquement une erreur vu que -e
n'accepte _qu'un seul_ argument, pas plus. D'où le
message d'erreur que tu obtiens.
Si le répertoire ne contenait qu'un seul fichier, là
ça marcherait. En fait, sans les "...", le code marche
mais juste pour 0 ou 1 fichier dans le répertoire, pas
plus. :)
Perso, si je peux éviter les * dans un script, je le
fais, surtout pour du rm. À ta place je ferais plutôt ceci :
find /etc/apt/sources.list.d/ -maxdepth 1 -mindepth 1 -type f -delete
voire, tant qu'on y ait :
find /etc/apt/sources.list.d/ -maxdepth 1 -mindepth 1 -type f -name '*.list' -delete
J'espère que c'est plus clair pour toi maintenant.
À+
--
François Lafont
Avatar
Francois Lafont
On 09/08/2017 12:07 PM, Raphaël POITEVIN wrote:
il manque un ; après le ]

Je ne pense pas.
On peut écrire :
if [ -e "$fichier" ]
then
...
Le « ; » est nécessaire si on met le then sur la
même ligne :
if [ -e "$fichier" ]; then
...
Perso, j'utilise toujours la première forme.
--
François Lafont
Avatar
JF Straeten
Hello,
On Fri, Sep 08, 2017 at 11:57:50AM +0200, David BERCOT wrote:
[...]
Le voici :
#!/bin/bash
if [ -e "/etc/apt/sources.list.d/*" ]
then
    rm /etc/apt/sources.list.d/*
fi

[...]
Auriez-vous une piste ?

Ça s'exécute forcément en root, je suppose ?
Essaye un peu de coder le path de 'rm' en dur, sans reposer sur
$PATH. Donc :
[...]
/bin/rm /etc/apt/sources.list.d/*
Qu'est-ce que ça donne ?
A+
--
JFS.
Avatar
Marc Chantreux
salut,
si tu mets ton * dans une chaine (""), c'est pour dire que tu cherches
un fichier qui s'appelle litteralement *.
ce que tu cherches a faire c'est
test /etc/apt/sources.list.d/* &&
rm /etc/apt/sources.list.d/*
autre approche (intéressante si beaucoup de fichiers)
find /etc/apt/sources.list.d -prune -maxdepth 1 -print0 |
xargs -0 rm
cordialement,
marc
Avatar
Francois Lafont
On 09/08/2017 01:01 PM, Marc Chantreux wrote:
ce que tu cherches a faire c'est
test /etc/apt/sources.list.d/* &&
rm /etc/apt/sources.list.d/*

:~# ls /etc/apt/sources.list.d/
titi.list toto.list
:~# test /etc/apt/sources.list.d/*
-bash: test: /etc/apt/sources.list.d/docker.list: unary operator expected
--
François Lafont
Avatar
Marc Chantreux
On Fri, Sep 08, 2017 at 01:42:47PM +0200, Francois Lafont wrote:
ce que tu cherches a faire c'est
test /etc/apt/sources.list.d/* &&
rm /etc/apt/sources.list.d/*

:~# test /etc/apt/sources.list.d/*
-bash: test: /etc/apt/sources.list.d/docker.list: unary operator expected

oops ... effectivement :) utilise find !
Avatar
David BERCOT
Re-bonjour,
C'est tout à fait ça ;-)
Il ne marchait pas avant mais je ne m'en rendais pas compte vu qu'il n'y
a plus eu aucun fichier ajouté dans le répertoire...
Le find est effectivement une solution plus adaptée...
Merci à tous pour vos réponses.
David.
Le 08/09/2017 à 12:14, Francois Lafont a écrit :
Hello,
On 09/08/2017 11:57 AM, David BERCOT wrote:
if [ -e "/etc/apt/sources.list.d/*" ]
then
rm /etc/apt/sources.list.d/*
fi

Je ne suis pas sûr d'avoir compris comment était
ton code à l'origine mais je pense qu'il n'était
pas correct (ce qui ne l'a pas empêché de marcher
pendant un certain temps semble-t-il).
Avec les doubles quotes, tu demandes à bash de
tester si un fichier qui s'appelle * (avec vraiment
comme nom juste le caractère *) existe dans le
répertoire /etc/apt/sources.list.d/. Et on imagine
bien que ce n'est pas ce que tu veux demander à
bash.
Sans les doubles quotes, là le caractère * devient
spécial et bash le développe en fonction de ce qu'il
y a dans ton répertoire.
Par exemple si dans /etc/apt/sources.list.d/, tu as
titi.list et toto.list (et c'est tout) alors tout
va se passer comme si tu avais écris :
[ -e /etc/apt/sources.list.d/titi.list /etc/apt/sources.list.d/toto.list ]
et là tu as fort logiquement une erreur vu que -e
n'accepte _qu'un seul_ argument, pas plus. D'où le
message d'erreur que tu obtiens.
Si le répertoire ne contenait qu'un seul fichier, là
ça marcherait. En fait, sans les "...", le code marche
mais juste pour 0 ou 1 fichier dans le répertoire, pas
plus. :)
Perso, si je peux éviter les * dans un script, je le
fais, surtout pour du rm. À ta place je ferais plutôt ceci :
find /etc/apt/sources.list.d/ -maxdepth 1 -mindepth 1 -type f -delete
voire, tant qu'on y ait :
find /etc/apt/sources.list.d/ -maxdepth 1 -mindepth 1 -type f -name '*.list' -delete
J'espère que c'est plus clair pour toi maintenant.
À+
--
François Lafont
Avatar
Francois Lafont
On 09/08/2017 06:41 PM, Gilles Mocellin wrote:
rm -f /etc/apt/source.list.d/*
Et c'est tout...
S'il n'y a pas de fichier, il ne fait rien, et ne sort pas d'erreur grace à
l'option -f.

... sauf si le répertoire /etc/apt/source.list.d/ contient un
sous répertoire.
Bon ok, je pinaille. :p
--
François Lafont
Avatar
=c3
On 09/08/2017 08:58 PM, Francois Lafont wrote:
On 09/08/2017 06:41 PM, Gilles Mocellin wrote:
rm -f /etc/apt/source.list.d/*
Et c'est tout...
S'il n'y a pas de fichier, il ne fait rien, et ne sort pas d'erreur grace à
l'option -f.

... sauf si le répertoire /etc/apt/source.list.d/ contient un
sous répertoire.
Bon ok, je pinaille. :p

Bonsoir François,
Vous pinaillez, oui et non,
Si en-tête, le script a un `set -e` pour arrêter les frais en cas
d'erreur, la présence d'un répertoire va stopper la procédure.
J'aurais plutôt commis une purge dans le répertoire de sources de
la manière suivante. Si on force récursivement l'effacement du
répertoire "/etc/apt/sources.list.d" tout entier, pas de risque
de piège avec les astérisques puisqu'il n'y en a pas. ;)
Cette solution me semble sérieusement légitime, donc si quelqu'un
y voit une énormité, qu'il n'hésite pas à le signaler, faut pas
blaguer avec `rm`, même le vendredi.
Votre solution à base de `find` était très bien, j'aurais raffiné
encore un peu en ajoutant les fichiers .sources et en prenant en
compte la majorité des types de fichiers, dès fois qu'un petit
malin trouve le moyen de positionner un lien symbolique ou
(soyons fous) une socket avec potentiellement de tout dedans :
find /etc/apt/sources.list.d/
-maxdepth 1 -mindepth 1
-not -type d
-name '*.list' -or -name '*.sources'
-delete
À plus,
--
Étienne Mollier
1 2