logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 14-01-2021 10:45:36

alpha.centauri
Invité

[RESOLU] bash espaces et guillemets

hello,

y a un truc qui m'échappe :

par exemple, j'ai un fichier qui s'appelle a b  (un espace entre a et b, oui, c'est pas bien mais c'est pas le pb :-) )
je fais un rm b a et j'ai ça :
rm: impossible de supprimer "a": Aucun fichier ou dossier de ce type
rm: impossible de supprimer "b": Aucun fichier ou dossier de ce type
normal...

je fais un rm 'a b'
ça marche, normal

pb : je crée une variable tata = 'a b'
echo $tata
'a b'

je fais un rm $tata et j'ai ça :
rm: impossible de supprimer "'a": Aucun fichier ou dossier de ce type
rm: impossible de supprimer "b'": Aucun fichier ou dossier de ce type

et là, je comprends pas... pourquoi rm considère séparément 'a et b' plutôt que 'a b' ???

Dernière modification par alpha.centauri (16-01-2021 17:52:35)

#2 14-01-2021 11:03:12

jpt
Banni(e)
Distrib. : Debian 10.8
Noyau : Linux 5.7.10 (backports)
(G)UI : LXDE
Inscription : 12-09-2020

Re : [RESOLU] bash espaces et guillemets

Salut,

alpha.centauri a écrit :

pb : je crée une variable tata = 'a b'
echo $tata
'a b'

tu es sûr des simples quotes sur la 3e ligne ? Chez moi, ta manip donne

echo $tata
a b

et donc bien sûr le rm $tata échoue comme chez toi avec les mêmes erreurs.

Par contre, rm "$tata" fonctionne :

$ rm "$tata"
rm: impossible de supprimer « a b »: Aucun fichier ou dossier de ce type
$ touch "$tata"
$ rm "$tata"
rm : supprimer fichier vide « a b » ? y
$


Toujours penser à mettre des doubles quotes aux variables ! wink

Dernière modification par jpt (14-01-2021 11:03:45)


AMD Ryzen3 3200G sur Gigabyte B450M & Make Love Not War

Hors ligne

#3 14-01-2021 16:29:21

raleur
Membre
Inscription : 03-10-2014

Re : [RESOLU] bash espaces et guillemets

alpha.centauri a écrit :

pourquoi rm considère séparément 'a et b' plutôt que 'a b' ?


Parce que les variable du shell ne sont pas traitées comme les variables d'un langage de programmation "classique" mais comme de simples éléments de substitution de texte. Si tu connais le langage C, ça ressemblerait plus à une macro #define (traitée par le préprocesseur) qu'à une variable (traitée par le compilateur)


Il vaut mieux montrer que raconter.

Hors ligne

#4 14-01-2021 16:48:01

alpha.centauri
Invité

Re : [RESOLU] bash espaces et guillemets

@JPT :
j'avais un peu simplifié, mais, en-fait, j'ai créé tata comme ceci :

tata="'a b'"
echo $tata
'a b'

effectivement, j'avais constaté que ton rm "$tata" fonctionnait, mais j'aimerais bien comprendre pourquoi mon rm $tata ne marche pas....

@râleur:
je suis pas très top en C et macro #define ;-), mais justement, si on parle de substitution de texte, pourquoi le rm ne considère-t-il pas le texte 'a b' d'un seul tenant...

Dernière modification par alpha.centauri (14-01-2021 17:13:13)

#5 14-01-2021 20:21:31

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [RESOLU] bash espaces et guillemets

alpha.centauri a écrit :

effectivement, j'avais constaté que ton rm "$tata" fonctionnait, mais j'aimerais bien comprendre pourquoi mon rm $tata ne marche pas....


Parce que bash commence par remplacer la variable par son contenu avant d'exécuter la commande :

rm a b


C'est pour cela qu'il est souvent préférable de mettre les variables entre guillemets :

rm "$ata"

Dernière modification par Beta-Pictoris (14-01-2021 23:02:48)

Hors ligne

#6 14-01-2021 22:23:28

alpha.centauri
Invité

Re : [RESOLU] bash espaces et guillemets

@Beta-Pictoris

je voudrais pas faire mon lourd, mais justement, le contenu de la variable, c'est 'a b' et non a b (echo $tata donne bien 'a b' et non a b)

en plus, il me dit qu'il ne trouve ni 'a, ni b', les guillemets n'ont donc pas été virés purement et simplement...

#7 14-01-2021 23:08:58

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [RESOLU] bash espaces et guillemets

Tu peux le vérifier en mode debug grâce à la commande 'set -x' :

set -x


tata='a b'


+ tata='a b'


echo $tata


+ echo a b
a b


echo "$tata"


+ echo 'a b'
a b


rm $tata


+ rm a b
rm: impossible de supprimer 'a': Aucun fichier ou dossier de ce type
rm: impossible de supprimer 'b': Aucun fichier ou dossier de ce type

Hors ligne

#8 15-01-2021 01:15:51

vv222
Administrateur
Distrib. : Debian Sid
(G)UI : sway
Inscription : 18-11-2013
Site Web

Re : [RESOLU] bash espaces et guillemets

Un rapide exemple qui devrait permettre de comprendre un peu mieux l'expansion des variables en shell :

VAR="'a b'"
for word in "$VAR"; do echo "$word"; done

'a b'

VAR="'a b'"
for word in $VAR; do echo "$word"; done

'a
b'



Ce qui aurait été correct ici est :

VAR='a b'
rm "$VAR"



Pour plus de détails :

man dash


Jouer sous Debian ? Facile !

Ceterum censeo Barum esse delendam

Hors ligne

#9 15-01-2021 02:05:15

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [RESOLU] bash espaces et guillemets

Oui, les apostrophes sont considérées comme des caractères normaux dans les chaînes entre guillemets et ne définissent rien de particulier.

En mode debug, on voit que Bash fait des transformations bizarres en ajoutant des doubles quotes au début et à la fin :


VAR="'a b'"


+ VAR=''\''a b'\'''


Je ne connais pas la raison de ce comportement.

Il pourrait l'écrire de cette façon :

VAR=\''a b'\'


+ VAR=''\''a b'\'''


Ou comme ceci : (avec un anti slash devant l'espace)

VAR=\'a\ b\'

Hors ligne

#10 15-01-2021 13:44:22

vv222
Administrateur
Distrib. : Debian Sid
(G)UI : sway
Inscription : 18-11-2013
Site Web

Re : [RESOLU] bash espaces et guillemets

Beta-Pictoris a écrit :

En mode debug, on voit que Bash fait des transformations bizarres en ajoutant des doubles quotes au début et à la fin :


VAR="'a b'"


+ VAR=''\''a b'\'''


Je ne connais pas la raison de ce comportement.



C'est logique, mais attention, ça va sembler très con big_smile (comme tout ce que fait une machine)

Le premier ' est là pour ouvrir une chaîne de caractères, suivi de '\'' pour ajouter un ' littéral, puis "a b", puis un nouveau '\'', puis un ' final pour acherver la chaîne de caractères.
Ce qui devient un peu contre-intuitif quand on décortique '\'' : le premier ' est là pour fermer la chaîne de caractères en cours, \' pour ajouter un ' littéral, puis ' pour rouvrir la chaîne.

Ce qui donne pour une retranscription :

  • ' → on ouvre une chaîne de caractères

  • ' → on ferme une chaîne de caractères

  • \' → on insère un ' littéral

  • ' → on ouvre une chaîne de caractères

  • a b → on insère la chaîne "a b"

  • ' → on ferme une chaîne de caractères

  • \' → on insère un ' littéral

  • ' → on ouvre une chaîne de caractères

  • ' → on ferme une chaîne de caractères



La lecture de ce décortiquage semble inclure des étapes absurdes pour un humain (ouvrir un truc pour le fermer immédiatement), mais dans le cas d'un traitement systématique par une machine c'est en fait logique du début à la fin.


Jouer sous Debian ? Facile !

Ceterum censeo Barum esse delendam

Hors ligne

#11 15-01-2021 14:16:04

Beta-Pictoris
Membre
Lieu : Angers
Distrib. : Buster
Inscription : 11-08-2015

Re : [RESOLU] bash espaces et guillemets

Effectivement, si bash ne substituait les doubles guillemets que par des simples quotes, on aurait ceci :

VAR=''a b''


+ VAR=a
+ b
+ '[' -x /usr/lib/command-not-found ']'
+ /usr/lib/command-not-found -- b
b : commande introuvable
+ return 127
 


Même problème avec des antislash placés devant les quotes.

Le bash fait donc ceci :

Dans des chaînes entres doubles guillemets, quand il y a 2 quotes ou plus, ils sont remplacés chacun par une chaîne constituée d'un quote, un antislash et de 2 quotes : '\''

Et les doubles guillemets sont remplacées par des quotes :

echo " ' ' "


+ echo ' '\'' '\'' '

Dernière modification par Beta-Pictoris (15-01-2021 15:05:08)

Hors ligne

#12 16-01-2021 17:48:09

alpha.centauri
Invité

Re : [RESOLU] bash espaces et guillemets

merci bien pour vos éclairages ...

même si la logique profonde de la chose me laisse un peu perplexe...:):):)

#13 16-01-2021 18:57:28

David5647
Membre
Distrib. : Debian Sid
Noyau : 5.15.0-2-amd64
(G)UI : i3wm + des bouts de kde
Inscription : 27-08-2017

Re : [RESOLU] bash espaces et guillemets

Avec un texte un peu plus long ,ça parait plus naturel:

var="debian n'est qu'amour"

+ var='debian n'\''est qu'\''amour'



var=debian\ n\'est\ qu\'amour

+ var='debian n'\''est qu'\''amour'



var="debian n"\'"est qu"\'"amour"

+ var='debian n'\''est qu'\''amour'

Hors ligne

Pied de page des forums