Résoudre un exercice en shell, je bloque :s
Fermé
Pierre
-
Modifié le 18 mai 2021 à 16:48
mamiemando Messages postés 33357 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 14 novembre 2024 - 19 mai 2021 à 16:02
mamiemando Messages postés 33357 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 14 novembre 2024 - 19 mai 2021 à 16:02
A voir également:
- Résoudre un exercice en shell, je bloque :s
- Code puk bloqué - Guide
- Uptobox bloqué - Accueil - Guide services en ligne
- Pavé tactile bloqué - Guide
- Compte gmail bloqué - Guide
- Classic shell windows 11 - Télécharger - Personnalisation
4 réponses
mamiemando
Messages postés
33357
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
14 novembre 2024
7 799
18 mai 2021 à 17:58
18 mai 2021 à 17:58
Bonjour,
Mon premier conseil serait de soigner l'indentation pour que ce soit plus lisible. Pense aussi à utiliser les balises de code (4e bouton au dessus de la boîte dans laquelle tu tapes tes messages) pour rendre tes messages plus lisibles.
Il y a d'autres choses qui ne vont pas, qu'on observe quand on lance ton script :
Après ces corrections ça donne :
Mon premier conseil serait de soigner l'indentation pour que ce soit plus lisible. Pense aussi à utiliser les balises de code (4e bouton au dessus de la boîte dans laquelle tu tapes tes messages) pour rendre tes messages plus lisibles.
Il y a d'autres choses qui ne vont pas, qu'on observe quand on lance ton script :
- Il y a un $ en trop devant
echo
- Pour quitter le programme il faut utiliser le mot clé
exit
et pasreturn
- Le code de retour du programme n'est pas toujours précisé (si on rentre dans le
elif
). En pratique, le programme retournera implicitement 0. - Le
case
est un peu bizarre. Il y a des manières plus élégantes en shell de vérifier si une chaîne est inclue dans une autre (voir cette discussion) - Il est fortement recommandé d'encadrer les évaluations de variables par des guillements (afin de traiter correctement les chaînes de caractères contenant des espaces).
- Il est recommandé de mettre en première ligne un shebang qui indique l'interpréteur à utiliser (en particulier, si tu utilises des primitives bash, c'est là qu'il faut indiquer
bash
au lieu desh
).
Après ces corrections ça donne :
#!/bin/sh usage (){ echo "Usage: ./mon_grep chaine fichier... ou: --help|-h Affiche les lignes de fichier... contenant chaine avec leur numéro Ou bien cette aide avec l'argument --help" } ret=0 if [ $# -ne 0 ] && { [ "$1" = --help ] || [ "$1" = -h ]; }; then usage elif [ $# -gt 1 ]; then for f in $@ do cpt=0 if [ "$1" != "$f" ]; then while read ligne do cpt=$(( $cpt + 1 )) if [[ "$line" =~ "$1" ]] then echo "Ligne $cpt de $f : $ligne" fi done < $f fi done ret=0 else echo "erreur: trop d'arguments" usage ret=2 fi exit ret
mamiemando
Messages postés
33357
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
14 novembre 2024
7 799
18 mai 2021 à 16:51
18 mai 2021 à 16:51
Bonjour,
Je t'invite à faire des questions concises et précises quand tu fais appel à un forum, cela augmentera les chances que tu aies une réponse.
J'ai essayé plusieurs fois, mais le
Ce lien te montre comment réaliser une telle construction.
Bonne chance
Je t'invite à faire des questions concises et précises quand tu fais appel à un forum, cela augmentera les chances que tu aies une réponse.
J'ai essayé plusieurs fois, mais le
while read+ redirection me bloque
Ce lien te montre comment réaliser une telle construction.
Bonne chance
Bonjour,
Merci, j'ai avancé, mais j'ai 2-3 questions car je bloque sur certains points, mon script :
Le problème, tout marche mais lorsque je fais (je ne tombe par sur 2 lorsque j'exécute la commande echo $2 et je ne sais pas comment résoudre ce problème) :
Il s'agit du cas où il y'a trop d'arguments, et je dois finir avec un statut de sortie 2 (voir consigne).
\Si tu pouvais m'aider sur ça, ou quelqu'un d'autres, merci beaucoup !
Bonne journée
Merci, j'ai avancé, mais j'ai 2-3 questions car je bloque sur certains points, mon script :
usage (){ echo "Usage: ./mon_grep chaine fichier... ou: --help|-h Affiche les lignes de fichier... contenant chaine avec leur numéro Ou bien cette aide avec l'argument --help" } if [ $# -ne 0 ] && { [ $1 = --help ] || [ $1 = -h ]; }; then usage return 0 elif [ $# -gt 1 ]; then for f in $@ do cpt=0 if [ $1 != $f ]; then while read ligne do cpt=$(( $cpt + 1 )) case $ligne in *$1*) echo "Ligne $cpt de $f : $ligne" ;; esac done < $f fi done else echo "erreur: trop d'arguments" usage return 2 fi
Le problème, tout marche mais lorsque je fais (je ne tombe par sur 2 lorsque j'exécute la commande echo $2 et je ne sais pas comment résoudre ce problème) :
$ ./mon_grep 'physique nucléaire' pirouette.txt poissons.txt escargot.txt
$ echo $?
2
Il s'agit du cas où il y'a trop d'arguments, et je dois finir avec un statut de sortie 2 (voir consigne).
\Si tu pouvais m'aider sur ça, ou quelqu'un d'autres, merci beaucoup !
Bonne journée
mamiemando
Messages postés
33357
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
14 novembre 2024
7 799
>
Pierre
19 mai 2021 à 15:48
19 mai 2021 à 15:48
Bonjour, tu peux contrôler le nombre d'arguments en évaluant
$#.
Merci, j'ai essayé le code mais il y'a un problème, lorsque je tape la commande suivante :
Je tombe sur une erreur :
Je crois que c'est par rapport au
Et en essayant de modifier j'ai fais ça mais le problème c'est que j'ai certes le
Le programme : (j'ai juste remplacé la ligne 21 par ce qui y était avant)
Merci pour l'aide !
./mon_grep etit pirouette.txt poissons.txt escargot.txt
Je tombe sur une erreur :
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 21: ./ttt: [[: not found
./ttt: 34: exit: Illegal number: ret
Je crois que c'est par rapport au
=~, d'ailleurs je n'ai jamais vu cette combinaison.
Et en essayant de modifier j'ai fais ça mais le problème c'est que j'ai certes le
echo $?--> 2 mais si je fais
./mon_grep -hpuis
echo $?, je suis censé avoir 0 mais non je tombe à chaque fois sur 2.
Le programme : (j'ai juste remplacé la ligne 21 par ce qui y était avant)
usage (){ echo "Usage: ./mon_grep chaine fichier... ou: --help|-h Affiche les lignes de fichier... contenant chaine avec leur numéro Ou bien cette aide avec l'argument --help" } ret=0 if [ $# -ne 0 ] && { [ $1 = --help ] || [ $1 = -h ]; }; then usage return 0 elif [ $# -gt 1 ]; then for f in $@ do cpt=0 if [ $1 != $f ]; then while read ligne do cpt=$(( $cpt + 1 )) case $ligne in *$1*) echo "Ligne $cpt de $f : $ligne" ;; esac done < $f fi done ret=0else echo "erreur: trop d'arguments" usage ret=2 fiexit ret
Merci pour l'aide !
mamiemando
Messages postés
33357
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
14 novembre 2024
7 799
19 mai 2021 à 16:02
19 mai 2021 à 16:02
Bonjour,
Tu as cette erreur car ton script est lancé par
Exemple : Soit le fichier
Si tu le lances via
Si tu le lances via
Si tu rends le fichier exécutable, ton shell examinera le shebang (ici
Bonne chance
Tu as cette erreur car ton script est lancé par
shet non par
bash, or
=~est un opérateur bash, comme expliqué ici. L'intérêt du shebang est précisément que le script soit lancé avec le bon interpréteur shell.
Exemple : Soit le fichier
exemple.sh
#!/bin/bash phrase="ceci est une phrase" word="une" if [[ "$phrase" =~ "$word" ]] then echo "'$word' trouvé" else echo "'$word' pas trouvé" fi
Si tu le lances via
sh, tu as une erreur :
(mando@silk) (~) $ sh exemple.sh
toto.sh: 6: [[: not found
'une' pas trouvé
Si tu le lances via
bash, tu n'as pas d'erreur :
(mando@silk) (~) $ bash exemple.sh
'une' trouvé
Si tu rends le fichier exécutable, ton shell examinera le shebang (ici
#!/bin/bash) pour déterminer quel interpréteur shell utiliser :
(mando@silk) (~) $ chmod a+x exemple.sh
(mando@silk) (~) $ ./exemple.sh
'une' trouvé
Bonne chance