Bonjour j'ai un tp à faire pour la rentrée, je bloque à un exercice :
J'ai réussi la 1.
#!/bin/sh
if [ $# -ge 1 ]
then
for i
do
ps -C $i
done
else
echo "pas d'argument"
exit 1
fi
exit 0
La 2. je bloque je sais pas comment faire avec les virgules, quand j’exécute j'ai un message d'erreur.
#!/bin/sh
if [ $# -ge 1 ]
then
for i
do
VAR="$VAR$i," <- Le problème est ici
done
ps -C $VAR
else
echo "pas d'argument"
exit 1
fi
exit 0
Pour executer je fait :
./cmd_v1.sh bash geany <- Pas de problème
./cmd_v2.sh bash geany <- erreur ( ERROR: Improper list. )
Merci d'avance
# Débuggage
Posté par chimrod (site web personnel) . Évalué à 4.
Tu devrais rajouter une ligne pour y voir un peu plus clair :
avant la ligne ps -C $VAR
Ça te donnera une idée du problème.
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
J'ai déjà essayer avec echo pour comprendre le problème :
ps -C bash,geany,
C'est la dernière virgule qui gène et je sais pas comment l'enlever
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 4.
Il serait plus simple de ne pas la mettre plutôt que de l’enlever ensuite.
Il y a plusieurs moyens de faire ça, moi a priori je testerais à chaque tour de boucle si
VAR
contient déjà quelque chose (auquel cas on y ajoute une virgule puis l’argument courant) ou non (auquel cas on y ajoute juste l’argument courant).[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Donc je dois essayer avec des conditions (if ..) Ça complique pas la chose ? Il n'y a pas une méthode plus simple ?
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2. Dernière modification le 30 octobre 2014 à 16:20.
man test
En fait la commande test s'appelle aussi "[" (si tu regardes dans /usr/bin tu verras un programme nommé simplement « [ »)
Tiens d'ailleurs c'est marrant je m'attendais à un lien physique… mais passons
Ce n'est pas très compliqué :
qui peut aussi s'écrire :
ou encore :
Le crochet fermant est juste là pour la décoration… Par contre n'oublie pas de laisser un espace à l'intérieur des crochets ;)
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Je suis du même avis que toi. Par curiosité j'ai essayé de faire son exercice et je suis tombé sur un comportement qui me laisse dubitatif :
J'initialise d'abord ma variable VAR comme une chaîne vide
VAR=""
(pour être sûr, en fait au début je ne l'avais pas fait mais j'ai cru que le comportement décrit ci-dessous était lié à ça. Je viens également d'essayerVAR=
c'est la même chose…)Pour le test j'ai le choix entre
! -z $VAR
c'est celui qui me vient en premier,-n $VAR
celui que je trouve dans le man de la commande test à la recherche d'un truc plus propre,$VAR
qui est, toujours d'après le manuel, équivalent au second.Je ne comprends pas pourquoi :
! -z $VAR -> OK
$VAR -> OK
-n $VAR -> NOK (j'ai 'arg1,arg2,argN,' en sortie…)
[^] # Re: Débuggage
Posté par Ubis . Évalué à 0.
Donc finalement tu ne sais pas comment enlever la virgule à la fin ?
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Bin si sauf qu'il y a théoriquement 3 conditions qui sont équivalentes pour tester si $VAR n'est pas vide :
! -z $VAR
$VAR
-n $VAR
Je ne comprends pas pourquoi la dernière ne fonctionne pas.
Et comme cela a été dit, il ne faut pas enlever la virgule mais la mettre seulement si c'est nécessaire (ie : si $VAR n'est pas vide)
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Si j'ai bien compris :
!/bin/sh
if [ $# -ge 1 ]
then
for i
do
if [ $VAR -eq 0 ]
then VAR="$VAR$i"
else VAR="$VAR$i,"
fi
done
ps -C $VAR
else
echo "pas d'argument"
exit 1
fi
exit 0
Mais j'ai toujours le même problème, la virgule à la fin, j'ai fait une erreur dans la condition ?
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2. Dernière modification le 30 octobre 2014 à 17:00.
Tu as fait une erreur dans la condition, $VAR est une chaîne vide, ce n'est pas un entier :
Tu peux retourner lire la page man de test ;) Mais sinon j'ai déjà donné des exemples dans mes autres commentaires…
Mais tu t'y prends aussi mal dans la boucle :
Si VAR n'est PAS VIDE:
VAR=?
sinon:
VAR=?
Je te donne un indice pour trouver les ? : la virgule n'est pas au bon endroit et dans l'un des cas tu n'as pas besoin d'utiliser les deux variables…
C'est plus propre que la méthode donnée plus haut qui consiste à mettre des virgules au mauvais endroit pour ensuite en enlever une ! :p
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Rhaa j'ai le cerveau qui brule, je m'en sors pas avec les conditions :
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2. Dernière modification le 30 octobre 2014 à 17:29.
ça c'est bon, et pas besoin d'enlever une virgule à la fin :)
ça non.
Si tu veux tester si $VAR est vide il ne faut pas utiliser
-eq
, je te laisse chercher toi même (man test) !EDIT : Quoique
-eq ""
fonctionne peut-être, mais il y a mieux.[^] # Re: Débuggage
Posté par Ubis . Évalué à 2.
Je crois que c'est ça
Mais par contre quand j'essaye : ./cmd_v2.sh bash geany
Je n'ai que bash qui s'affiche
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Je crois que c'est bon pour la 2.
J'aurai juste une dernière question pour la 3. qui me dit de reprendre le script 2.
Je dois remplacer les espaces par des virgules or il y a déjà des virgules non ? Ou bien c'est le script 1 que je dois modifier ?
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Ni l'un ni l'autre, à part pour le test du nombre d'arguments…
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Comment je dois m'y prendre alors ? Je comprend pas trop la consigne
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Tu dois faire un script en shell qui s'utilise ainsi :
$ ./script arg1 arg2 arg3
et qui a la même sortie que la commande ps -C arg1,arg2,arg3
en utilisant sed :)
On peut t'aider à voir ce qui ne va pas dans ton code, comme on l'a fait pour l'exercice 2. mais peu de gens vont te donner une réponse toute faite. Ça ne serait pas te rendre service…
man sed ! Non je déconne ça va pas trop t'aider. Cherche plutôt un cours, avec des exemples, sur le web pour te familiariser avec sed.
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
J'ai essayé quelque chose, dites moi si je suis dans la bonne voie :
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Non, tu ne dois pas utiliser de boucle for, c'est dans l'énoncé.
Il faut utiliser le paramètre spécial
$@
qui contient l'ensemble des arguments (et pas$*
qui fait sensiblement la même chose mais pas tout à fait)C'est traité au chapitre « Paramètre spéciaux » du manuel de ton shell.
Chez moi, /bin/sh lance /bin/dash donc
man dash
…Tu fais ce truc sous quel OS ?
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
J'utilise Ubuntu
C'est comme ça pour l'utilisation de sed ? Les espaces ne sont pas remplacés quand je fait ça
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 3.
D’une part, l’expression rationnelle n’est pas bonne : les guillemets n’ont pas de signification pour sed, il va chercher une suite de trois caractères « guillemet – espace – guillemet » au lieu d’un caractère « espace ».
Ensuite, tu ne récupères pas la sortie de sed, alors que c’est ce dont tu as besoin.
Deux pistes :
Avec ça, tu peux construire ta variable
VAR
en une seule ligne.[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Nous n'avons pas encore vu les substitutions en cours :
Je ne vois pas comment récupérer la sortie de sed, j'ai essayer avec des pipes mais j'obtiens que des erreurs. J'ai fait une gaffe dans le script ci dessus ?
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
Finalement j'ai trouvé comment faire avec les substitutions :
Mais par contre n'y a-t-il pas un moyen de faire sans le fichier tmp ? Je sens que mon prof ne va pas aimer
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 3.
Si, avec un tube (« pipe ») : au lieu de rediriger la sortie de
echo
vers un fichier temporaire, tu la rediriges vers l’entrée de sed.[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
J'ai déjà essayé mais sed doit prendre un fichier en entrée non ?
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 2.
Non, comme beaucoup de programmes Unix sed lit son entrée standard s’il ne trouve pas de noms de fichier sur sa ligne de commande.
[^] # Re: Débuggage
Posté par chimrod (site web personnel) . Évalué à 3.
Pas forcément :
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
C'est bon, merci beaucoup !
[^] # Re: Débuggage
Posté par chimrod (site web personnel) . Évalué à 3.
Quitte à prendre de bonnes habitudes, évite cette syntaxe :
au profit de celle-ci :
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
C'est d'ailleurs assez tordu de le faire avec sed… J'y arrive, mais le script ne supporte pas des espaces supplémentaires entre les arguments (alors que les deux premiers scripts si), ça finit en arg1,arg2,,,,arg3 ce que ps -C trouve toute aussi impropre comme liste…
Bon courage !
^^
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 3.
Je ne sais pas comment tu t’y prends, mais en utilisant la variable
$@
, le nombre d’espaces entre les arguments lors de l’invocation du script n’a aucune importance…[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
J'ai utilisé $* parce que je suis idiot.
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Parce que geany n'est pas lancé ? :)
Ton script fonctionne.
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 3. Dernière modification le 30 octobre 2014 à 17:36.
Pour y voir plus clair, plutôt que de sauter des lignes dans ton code, « indente » le. Ce n'est pas parce que ce n'est pas obligatoire, comme en python par exemple, que ce n'est pas nécessaire. On indente toujours le code. Si j'étais prof ce serait direct deux points en moins un code sans indentation :)
[^] # Re: Débuggage
Posté par gouttegd . Évalué à 2.
À noter que je trouverais plus lisible d’écrire le test sur
VAR
et l’affectation subséquente en une seule ligne :Mais ça n’engage que moi.
[^] # Re: Débuggage
Posté par jyes . Évalué à 3.
Un oubli de guillemets non ? -n "$VAR" doit marcher.
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Bien vu.
Si je test $VAR et "$VAR" ou ! -z $VAR et ! -z "$VAR" j'ai le même résultat, par contre -n $VAR et -n "$VAR" ne donne pas le même résultat.
C'est en flagrante contradiction avec le manuel :
J'aime mon shell…
C'est normal ce comportement ?
[^] # Re: Débuggage
Posté par jyes . Évalué à 3. Dernière modification le 30 octobre 2014 à 20:18.
Oui, parce-que sans les guillemets, le programme test ne reçoit aucun second paramètre, ce qui n’est pas une chaîne de longueur nulle. En fait, tous tes tests devraient contenir des guillemets, sinon la condition évaluée par le programme test est tributaire de la substitution faite par le shell en amont, qui remplace une variable vide par rien et non par une chaîne vide. Il se trouve que les autres tests renvoient le même résultat avec une chaîne vide ou un paramètre absent.
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Merci pour ton explication.
C'est tordu, je me demande la raison derrière :/
Oui…
Si ça se trouve le résultat et peut être aléatoire sans guillemets ? Ou bien le test -n se comporte volontairement de manière différente ?
[^] # Re: Débuggage
Posté par Patrick Nicolas . Évalué à 3.
Il existe aussi (du moins en bash) la commande set -x
Lorsque ce mode est activé, bash va afficher toutes les commandes avant de les exécuter.
[^] # Re: Débuggage
Posté par chimrod (site web personnel) . Évalué à 2.
C'est juste, et c'est vrai que je n'y pense pas forcément…
Mais mon message était surtout destiné à orienter sur la piste sans pour autant donner la solution au problème… Avec l'habitude c'est le genre de ligne de code qui allume tout de suite une alerte dans un coin de la tête dès qu'on la lit.
[^] # Re: Débuggage
Posté par fearan . Évalué à 4.
y'en a qui se complique la vie :)
pour une raison que j'ignore mes dollars ont un comportement étrange… il vaut mieux remplacer
echo ...
par l'équivalent qui est dollars parenthèse echo … fermer parenthèseIl ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
En fait je dois reprendre le script d'avant pour continuer l'exercice
[^] # Re: Débuggage
Posté par fearan . Évalué à 3.
rhoooo alors je propose (ça marche pour bash, je ne sais pas pour sh
for i
do
VAR+=,$i
done
ps -C ${i:1}
et hop pas de if tout degeu en début de boucle
sinon tu peux aussi regarder avec shift pour chopper le premier et faire le reste avec le for (attention, je t'invite à tester dans le cas avec un seul paramètre )
sinon avec ton truc de base tu peux aussi jouer avec basename (qui pour le coup marche tout le temps
par exemple VAR=$( basename $VAR ,)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Au moins c'est cool, là on enlève bien une virgule :)
[^] # Re: Débuggage
Posté par Ubis . Évalué à 1.
./cmd_v2.sh bash geany
REPONSE :
./cmd_v2.sh: 14: VAR+=,bash: not found
./cmd_v2.sh: 14: VAR+=,geany: not found
ps -C
./cmd_v2.sh: 14: Bad substitution
J'ai pas réussi avec ce que tu m'as dit
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Poste le code entier. Mais par contre, c'est très important :
1) Saute une ligne
2) Mets trois "backquote" (c'est le caractère sur AltGr+7) suivi de "sh" (sans espace)
3) Colle ton code à partir de la ligne d'après
4) Saute une ligne
5) Mets trois "backquote" et saute une ligne
Sinon ce ne sera pas lisible. C'est expliqué sur le wiki : https://linuxfr.org/wiki/aide-edition#code
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
De toute façon te casses pas :
je viens de tester ça ne fonctionne pas. Mais on peut faire comme ça :
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
J'ai trouvé celui qui lisait pas les énoncés jusqu'au bout ! :) C'est la partie 4. Tu brûles les étapes.
[^] # Re: Débuggage
Posté par fearan . Évalué à 2.
En même temps, j'ai pas l'énoncé
je préfère mon presque oneliner à coup d'IFS :)
J'ai déjà mon diplôme moi, ensuite j'ajouterai que mon onliner a plus de chance de fonctionner avec des commandes ayant des espace, sed remplacera les " " par des , une commande du genre "reboot universe" :)
J'ajouterai qu'utiliser sed pour remplacer un caractère par un autre… tr est là pour ça ;)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2. Dernière modification le 31 octobre 2014 à 11:33.
Tu surf sous elinks et tu n'arrives pas à afficher la nimage dans ton framebuffer ? Tu réponds par mail ? Tu utilises un terminal Braille ?
[^] # Re: Débuggage
Posté par fearan . Évalué à 3.
je navigue en noscript + sans image car on a un quota de quelques centaines de Mo la semaine, et un truc du genre 1 giga l'an, pour éviter d'exploser le quota, j'ai du m'adapter; si la personne avait bien fait son travail elle aurai mit un alt qui va bien ;)
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Tu es en prison ? :) Dans quel pays ?
[^] # Re: Débuggage
Posté par BAud (site web personnel) . Évalué à 2.
cela correspond à la traduction LaTeX, ce qui permet d'écrire des caractères grecs comme ;-)
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 3. Dernière modification le 30 octobre 2014 à 16:47.
`commande`
et$(commande)
ne sont pas équivalents, le premier exécute la commande dans un sous-shell, la deuxième dans le shell courant.C'est peut-être pour ça que tu as un comportement étrange avec
$*
En espérant ne pas dire de conneries.
[^] # Re: Débuggage
Posté par anaseto . Évalué à 2.
La page man de dash dit "sous-shell" dans les deux cas, et celle de ksh aussi, celle de bash ne précise pas, mais dans tous les cas, on ne dirait pas qu'il y ait de différence de ce point de vue entre les deux syntaxes.
[^] # Re: Débuggage
Posté par Marotte ⛧ . Évalué à 2.
Oui. Je ne sais pas d'où je tiens ça…
http://stackoverflow.com/questions/9449778/what-is-the-benefit-of-using-instead-of-backticks-in-shell-scripts
À priori il n'y a pas de différence fonctionnelle mais ils ne s'utilisent pas pareil, certains caractères ne sont pas interprété pareil.
Sur stackoverflow la réponse qui revient pas mal c'est que les $() peuvent être imbriqués, ce à quoi quelqu'un répond qu'on peut aussi imbriquer les
``
mais que c'est assez moche :[^] # Re: Débuggage
Posté par fearan . Évalué à 2.
typiquement :
généralement les $( ) sont plus lisible et plus facile à gérer.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.