Je suis confronté à un petit soucis concernant les espaces dans une
boucle for. Je m'explique :
david@abeille ~/tmp $ echo $SHELL
/bin/zsh
david@abeille ~/tmp $ a="1 2 3"
david@abeille ~/tmp $ for i in $a ; do echo "[$i]" ; done
[1 2 3]
david@abeille ~/tmp $ /bin/sh
sh-2.04$ a="1 2 3"
sh-2.04$ for i in $a ; do echo "[$i]" ; done
[1]
[2]
[3]
Comment puis-je reproduire cette interprétation correcte de zsh dans sh
(ou ksh) ?
Je suis en fait face au problème des noms de fichiers contenant des
espaces. Et même en protégeant l'espace par un \, l'interprétation reste
la même. J'ai aussi essayé avec les quotes, mais sans succès.
Par exemple :
$ fichiers="
f1
fichier n2
'fichier numéro 3'
"
Merci de répondre à cette question un peu triviale, mais là je sèche :-).
C'est une option de zsh (shwordsplit), je ne suis pas sûr qu'elle soit bien correcte.
Qui, par défaut, est désactivée.
Sur le fait que ce soit correct ou pas, voir http://zsh.sunsite.dk/FAQ/zshfaq03.html#l17
-- Stéphane
Laurent Wacrenier
Stephane CHAZELAS écrit:
C'est une option de zsh (shwordsplit), je ne suis pas sûr qu'elle soit bien correcte.
Qui, par défaut, est désactivée.
Sur le fait que ce soit correct ou pas, voir http://zsh.sunsite.dk/FAQ/zshfaq03.html#l17
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre "". Il n'y a pas trop d'interêt à forcer cette interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de découper. Celà est de plus incompatible avec les shells connus.
C'est une option de zsh (shwordsplit), je ne suis pas sûr qu'elle soit
bien correcte.
Qui, par défaut, est désactivée.
Sur le fait que ce soit correct ou pas,
voir http://zsh.sunsite.dk/FAQ/zshfaq03.html#l17
Le fait est que sur sh on peut se débarasser du découpage en mettant
la variable entre "". Il n'y a pas trop d'interêt à forcer cette
interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de
découper. Celà est de plus incompatible avec les shells connus.
C'est une option de zsh (shwordsplit), je ne suis pas sûr qu'elle soit bien correcte.
Qui, par défaut, est désactivée.
Sur le fait que ce soit correct ou pas, voir http://zsh.sunsite.dk/FAQ/zshfaq03.html#l17
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre "". Il n'y a pas trop d'interêt à forcer cette interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de découper. Celà est de plus incompatible avec les shells connus.
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Les nouveaux (1988!) shells comme bash, ksh, zsh ont les tableaux, il n'est donc quasiment plus jamais nécessaire aujourd'hui de recourir au "word splitting".
zsh a un typage cohérent ; l'expansion d'un "array", d'un "scalar" d'un "integer" est toujours cohérent.
En zsh, on fait
scalar="multi word value" cmd $scalar
array=($=var) array2=(multiple words) for iterator in $array; do ...; done ou encore: for iterator ($=var) { ... }
Je ne vous mets pas l'équivalent ksh, par déscence
Il n'y a pas trop d'interêt à forcer cette interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de découper.
mettre des guillemets autour de toutes les variables est à mon sens beaucoup plus lourd, ainsi que le "${array[@]}" des bash et ksh.
Le fait est que sur sh on peut se débarasser du découpage en mettant
la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
gens oublient quasi-systematiquement de mettre des double
quotes autour des variables (quand il ne doit pas y avoir de
découpage ou de génération de noms de fichiers) et les problèmes
ne surviennent alors pas toujours immédiatement.
Les nouveaux (1988!) shells comme bash, ksh, zsh ont les
tableaux, il n'est donc quasiment plus jamais nécessaire
aujourd'hui de recourir au "word splitting".
zsh a un typage cohérent ; l'expansion d'un "array", d'un
"scalar" d'un "integer" est toujours cohérent.
En zsh, on fait
scalar="multi word value"
cmd $scalar
array=($=var) array2=(multiple words)
for iterator in $array; do ...; done
ou encore:
for iterator ($=var) { ... }
Je ne vous mets pas l'équivalent ksh, par déscence
Il n'y a pas trop d'interêt à forcer cette
interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de
découper.
mettre des guillemets autour de toutes les variables est à mon
sens beaucoup plus lourd, ainsi que le "${array[@]}" des bash et
ksh.
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Les nouveaux (1988!) shells comme bash, ksh, zsh ont les tableaux, il n'est donc quasiment plus jamais nécessaire aujourd'hui de recourir au "word splitting".
zsh a un typage cohérent ; l'expansion d'un "array", d'un "scalar" d'un "integer" est toujours cohérent.
En zsh, on fait
scalar="multi word value" cmd $scalar
array=($=var) array2=(multiple words) for iterator in $array; do ...; done ou encore: for iterator ($=var) { ... }
Je ne vous mets pas l'équivalent ksh, par déscence
Il n'y a pas trop d'interêt à forcer cette interprétation et en alourdissant la syntaxe lorsque qu'on a besoin de découper.
mettre des guillemets autour de toutes les variables est à mon sens beaucoup plus lourd, ainsi que le "${array[@]}" des bash et ksh.
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour qu'on detecte le plus rapidement possible qu'il est mal fait.
Le fait est que sur sh on peut se débarasser du découpage en mettant
la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise
fréquement des listes et j'aime bien pouvoir naviguer dedans.
gens oublient quasi-systematiquement de mettre des double
quotes autour des variables (quand il ne doit pas y avoir de
découpage ou de génération de noms de fichiers) et les problèmes
ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour
qu'on detecte le plus rapidement possible qu'il est mal fait.
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour qu'on detecte le plus rapidement possible qu'il est mal fait.
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes en utilisant le "word splitting", il y a de grandes chances que tes programmes soient buggués. Perso, je ne navigue pas dans des listes en sh. Si j'en viens à ce degré de complexité, j'utilise awk, perl ou C.
gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour qu'on detecte le plus rapidement possible qu'il est mal fait.
Mauvaise foi detected.
Dans un *langage* bien fait, les erreurs apparaissent le plus tot possible. Exemple, Ada est un langage bien fait, ksh93 est un langage mal fait. Il est plus difficile d'écrire un programme mal fait avec un langage bien fait, la discussion ne portait pas sur les pratiques des utilisateur mais sur la qualité des langages/interpreteurs..
Exemple:
cmd -?
marchera très longtemps avec bash ou ksh... jusqu'au jour où il y aura un fichier "-p" dans le répertoire courant. (un script avec une telle erreur écrit par David Korn himself: http://www.research.att.com/~dgk/ksh/script/env) Avec zsh, à moins qu'il y ait un fichier qui matche "-?" dans le répertoire courant, on aura immédiatement: zsh: no matches found: -? l'erreur est détectée très tot (c'est une autre incompatibilité de zsh)
cd $1 Marchera très longtemps, jusqu'à ce qu'un jour le répertoire s'appelle "foo bar" ou "***"... Avec zsh, tant qu'on ne fait pas « cd $~=1 » à la place, on n'a pas ce genre de problème. Note qu'en l'occurrence, pour etre tranquille, il aurait fallu écrire: cd -- "$1", combien de fois as-tu vu ce genre de précaution prise dans un script ?
Avec les shells bourne, les variables sont de type "string" sauf parfois où elles sont considérées comme des listes voire comme des patterns de fichiers. Le shell rc est plus cohérent, toute les variables sont des listes, il faut explicitement faire $^var pour joindre les éléments de la liste en une chaine de caractères.
C'est avec ksh (et bash) qu'on arrive au summum: les variables sont des tableaux, qui sont parfois considérées comme des chaines, parfois comme des listes (mais qui ne comprennent pas les éléments du tableau) parfois comme des patterns de fichiers, parfois comme des brace expressions.
Exemple (ksh93): a="{*,t}" ou a=("{*,t}") ou a[0]="{*,t}" a est un tableau à 1 élément d'indice 0 mais dans echo $a $a sera substitué par une liste d'arguments : la liste des fichiers dans le répertoire courant suivi de "t", alors que ${#a[@]} donne "1". (et encore, "$a" ne contient aucun caractère d'IFS). echo "$a": "$a" substitué par "{*,t}"
Dans b[1]=* b est un tableau à un élément ou une chaine vide echo $b ne donne rien, echo "${b[@]}" renvoie "*", ${b[@]} une liste de fichiers
a=() est en fait équivalent à "unset a", qui le sait ?
Le fait est que sur sh on peut se débarasser du découpage en mettant
la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise
fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes
en utilisant le "word splitting", il y a de grandes chances que
tes programmes soient buggués. Perso, je ne navigue pas dans des
listes en sh. Si j'en viens à ce degré de complexité, j'utilise
awk, perl ou C.
gens oublient quasi-systematiquement de mettre des double
quotes autour des variables (quand il ne doit pas y avoir de
découpage ou de génération de noms de fichiers) et les problèmes
ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour
qu'on detecte le plus rapidement possible qu'il est mal fait.
Mauvaise foi detected.
Dans un *langage* bien fait, les erreurs apparaissent le plus
tot possible. Exemple, Ada est un langage bien fait, ksh93 est
un langage mal fait. Il est plus difficile d'écrire un programme
mal fait avec un langage bien fait, la discussion ne portait pas
sur les pratiques des utilisateur mais sur la qualité des
langages/interpreteurs..
Exemple:
cmd -?
marchera très longtemps avec bash ou ksh... jusqu'au jour où il
y aura un fichier "-p" dans le répertoire courant.
(un script avec une telle erreur écrit par David Korn himself:
http://www.research.att.com/~dgk/ksh/script/env)
Avec zsh, à moins qu'il y ait un fichier qui matche "-?" dans le
répertoire courant, on aura immédiatement:
zsh: no matches found: -?
l'erreur est détectée très tot (c'est une autre incompatibilité
de zsh)
cd $1
Marchera très longtemps, jusqu'à ce qu'un jour le répertoire
s'appelle "foo bar" ou "***"...
Avec zsh, tant qu'on ne fait pas « cd $~=1 » à la place, on n'a
pas ce genre de problème.
Note qu'en l'occurrence, pour etre tranquille, il aurait fallu
écrire: cd -- "$1", combien de fois as-tu vu ce genre de
précaution prise dans un script ?
Avec les shells bourne, les variables sont de type "string" sauf
parfois où elles sont considérées comme des listes voire comme
des patterns de fichiers. Le shell rc est plus cohérent, toute
les variables sont des listes, il faut explicitement faire $^var
pour joindre les éléments de la liste en une chaine de
caractères.
C'est avec ksh (et bash) qu'on arrive au summum: les variables
sont des tableaux, qui sont parfois considérées comme des
chaines, parfois comme des listes (mais qui ne comprennent pas
les éléments du tableau) parfois comme des patterns de fichiers,
parfois comme des brace expressions.
Exemple (ksh93):
a="{*,t}" ou a=("{*,t}") ou a[0]="{*,t}"
a est un tableau à 1 élément d'indice 0 mais dans
echo $a
$a sera substitué par une liste d'arguments : la liste des
fichiers dans le répertoire courant suivi de "t", alors que
${#a[@]} donne "1". (et encore, "$a" ne contient aucun caractère
d'IFS).
echo "$a": "$a" substitué par "{*,t}"
Dans b[1]=*
b est un tableau à un élément ou une chaine vide
echo $b ne donne rien,
echo "${b[@]}" renvoie "*", ${b[@]} une liste de fichiers
a=() est en fait équivalent à "unset a", qui le sait ?
Le fait est que sur sh on peut se débarasser du découpage en mettant la variable entre ""
On n'a quasi jamais besoin du découpage. D'un autre coté, les
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes en utilisant le "word splitting", il y a de grandes chances que tes programmes soient buggués. Perso, je ne navigue pas dans des listes en sh. Si j'en viens à ce degré de complexité, j'utilise awk, perl ou C.
gens oublient quasi-systematiquement de mettre des double quotes autour des variables (quand il ne doit pas y avoir de découpage ou de génération de noms de fichiers) et les problèmes ne surviennent alors pas toujours immédiatement.
Un programme mal fait doit avoir le plus d'erreurs possibles pour qu'on detecte le plus rapidement possible qu'il est mal fait.
Mauvaise foi detected.
Dans un *langage* bien fait, les erreurs apparaissent le plus tot possible. Exemple, Ada est un langage bien fait, ksh93 est un langage mal fait. Il est plus difficile d'écrire un programme mal fait avec un langage bien fait, la discussion ne portait pas sur les pratiques des utilisateur mais sur la qualité des langages/interpreteurs..
Exemple:
cmd -?
marchera très longtemps avec bash ou ksh... jusqu'au jour où il y aura un fichier "-p" dans le répertoire courant. (un script avec une telle erreur écrit par David Korn himself: http://www.research.att.com/~dgk/ksh/script/env) Avec zsh, à moins qu'il y ait un fichier qui matche "-?" dans le répertoire courant, on aura immédiatement: zsh: no matches found: -? l'erreur est détectée très tot (c'est une autre incompatibilité de zsh)
cd $1 Marchera très longtemps, jusqu'à ce qu'un jour le répertoire s'appelle "foo bar" ou "***"... Avec zsh, tant qu'on ne fait pas « cd $~=1 » à la place, on n'a pas ce genre de problème. Note qu'en l'occurrence, pour etre tranquille, il aurait fallu écrire: cd -- "$1", combien de fois as-tu vu ce genre de précaution prise dans un script ?
Avec les shells bourne, les variables sont de type "string" sauf parfois où elles sont considérées comme des listes voire comme des patterns de fichiers. Le shell rc est plus cohérent, toute les variables sont des listes, il faut explicitement faire $^var pour joindre les éléments de la liste en une chaine de caractères.
C'est avec ksh (et bash) qu'on arrive au summum: les variables sont des tableaux, qui sont parfois considérées comme des chaines, parfois comme des listes (mais qui ne comprennent pas les éléments du tableau) parfois comme des patterns de fichiers, parfois comme des brace expressions.
Exemple (ksh93): a="{*,t}" ou a=("{*,t}") ou a[0]="{*,t}" a est un tableau à 1 élément d'indice 0 mais dans echo $a $a sera substitué par une liste d'arguments : la liste des fichiers dans le répertoire courant suivi de "t", alors que ${#a[@]} donne "1". (et encore, "$a" ne contient aucun caractère d'IFS). echo "$a": "$a" substitué par "{*,t}"
Dans b[1]=* b est un tableau à un élément ou une chaine vide echo $b ne donne rien, echo "${b[@]}" renvoie "*", ${b[@]} une liste de fichiers
a=() est en fait équivalent à "unset a", qui le sait ?
-- Stéphane
Laurent Wacrenier
Stephane CHAZELAS écrit:
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes en utilisant le "word splitting", il y a de grandes chances que tes programmes soient buggués. Perso, je ne navigue pas dans des listes en sh. Si j'en viens à ce degré de complexité, j'utilise awk, perl ou C.
Je ne vois pas le mal à déclarer une liste au début d'un programme, afin de pouvoir la faire évoluer avec les besoins puis de faire le traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire do faire $truc done
On ne doit pas faire les mêmes programmes, parce que j'utilise
fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes
en utilisant le "word splitting", il y a de grandes chances que
tes programmes soient buggués. Perso, je ne navigue pas dans des
listes en sh. Si j'en viens à ce degré de complexité, j'utilise
awk, perl ou C.
Je ne vois pas le mal à déclarer une liste au début d'un programme,
afin de pouvoir la faire évoluer avec les besoins puis de faire le
traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire
do
faire $truc
done
On ne doit pas faire les mêmes programmes, parce que j'utilise fréquement des listes et j'aime bien pouvoir naviguer dedans.
Quelle rapport avec les listes? Si tu navigues avec des listes en utilisant le "word splitting", il y a de grandes chances que tes programmes soient buggués. Perso, je ne navigue pas dans des listes en sh. Si j'en viens à ce degré de complexité, j'utilise awk, perl ou C.
Je ne vois pas le mal à déclarer une liste au début d'un programme, afin de pouvoir la faire évoluer avec les besoins puis de faire le traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire do faire $truc done
Stephane CHAZELAS
Le Wed, 1 Oct 2003 09:03:46 +0000 (UTC), Laurent Wacrenier écrivait : [...]
Je ne vois pas le mal à déclarer une liste au début d'un programme, afin de pouvoir la faire évoluer avec les besoins puis de faire le traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire do faire $truc done
Moi non-plus. Note que tu vas etre embeté, le jour où tu voudras des " ", "*", "?", "{" dans les items. Ya toujours moyen de contourner, mais c'est quand-meme beaucoup plus facile avec des variables de *type* liste. Seul zsh a ce typage. Pour ksh/bash, c'est de la sale bidouille pour garder une compatibilité.
-- Stéphane
Le Wed, 1 Oct 2003 09:03:46 +0000 (UTC), Laurent Wacrenier <lwa@teaser> écrivait :
[...]
Je ne vois pas le mal à déclarer une liste au début d'un programme,
afin de pouvoir la faire évoluer avec les besoins puis de faire le
traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire
do
faire $truc
done
Moi non-plus. Note que tu vas etre embeté, le jour où tu voudras
des " ", "*", "?", "{" dans les items. Ya toujours moyen de
contourner, mais c'est quand-meme beaucoup plus facile avec des
variables de *type* liste. Seul zsh a ce typage. Pour ksh/bash,
c'est de la sale bidouille pour garder une compatibilité.
Le Wed, 1 Oct 2003 09:03:46 +0000 (UTC), Laurent Wacrenier écrivait : [...]
Je ne vois pas le mal à déclarer une liste au début d'un programme, afin de pouvoir la faire évoluer avec les besoins puis de faire le traitement dans le corp du programme.
liste_de_trucs_a_faire="truc1 truc2 truc3"
...
for truc in $liste_de_trucs_a_faire do faire $truc done
Moi non-plus. Note que tu vas etre embeté, le jour où tu voudras des " ", "*", "?", "{" dans les items. Ya toujours moyen de contourner, mais c'est quand-meme beaucoup plus facile avec des variables de *type* liste. Seul zsh a ce typage. Pour ksh/bash, c'est de la sale bidouille pour garder une compatibilité.