[shell script] Compter des repertoires

Compter des repertoires [shell script] - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 02-03-2009 à 15:25:40    

Bonjour.  
 
J'ai un shell script à faire, mais je bloque sur une partie. Il s'agit de compter le nombre de répertoire d'un dossier donné. Voila ce que j'ai fait :
 
find #monRepertoire# -maxdepth 1 -type d | wc -l,  
 
soit en gros : je trouve, je compte les lignes. Problème : le find me donne aussi les fichiers cachés (/.config par exemple), et je n'en veut pas !
 
De plus, je voudrais comperer ce que je trouve à 0 ou 1, j'ai donc fait  
 
 if ((nbRep == 0) || (nbRep == 1)) then  
 
mais ça ne marche pas (nbRep ne doit pas être de type int)
 
Merci de me dire comment faire !


Message édité par Namoureux le 02-03-2009 à 15:27:17
Reply

Marsh Posté le 02-03-2009 à 15:25:40   

Reply

Marsh Posté le 02-03-2009 à 17:02:02    

nbrep=`ls -l | grep -c ^d`
if [ $nbrep = '0' ] || [ $nbrep = '1' ]
then
    ...
fi

Reply

Marsh Posté le 03-03-2009 à 20:27:03    

Je ne vous conseille pas ls + traitements, ce n'est pas fiable. Cela dépend trop de la distrib. ( même si cela fonctionne, c'est pas optimum )
 
Je propose en bash :  

Code :
  1. REPS=( */ )
  2. [[ ${REPS[@]} == '*/' ]] && echo "Pas de répertoires..." || echo "Il y a au moins un répertoire"


 
je n'utilise que des builtins bash... Cela nécessite que "shopt -s nullglob" ne soit pas activé.
Pour vérifier c'est très simple : shopt | grep nullglob.
Si il est actif, il suffit de remplacer le test du dessus par [[ ${REPS[@]} ]]
 
++

Message cité 1 fois
Message édité par sputnick le 04-03-2009 à 17:45:31
Reply

Marsh Posté le 03-03-2009 à 23:08:02    

sputnick a écrit :

Je ne vous conseille pas ls + traitements, ce n'est pas fiable


:heink:
Faudra m'expliquer pourquoi.

Reply

Marsh Posté le 04-03-2009 à 00:21:56    

Greybot de #bash sur irc.freenode.org  va te l'expliquer :

Citation :

<greybot> Please NEVER parse, pipe, grep, capture, read, or loop over the output of 'ls'. Unlike popular belief, 'ls' is NOT designed to enumerate files or parse their statistics. Using 'ls' for this is dangerous (word splitting) and there's always a better way; eg. globs: files=(*).


 
#bash est un channel tres actif ou on pratique un bash moderne en évitant les eceuils. Il y a là de vrais gurus du shell. On essaye de trouver des solutions les plus portable possible la plupart du temps. ( Oui je participe assez souvent même si je ne suis pas encore un guru  :p  ).

Reply

Marsh Posté le 04-03-2009 à 09:10:59    

Certes mais là on ne regarde que la première lettre de la ligne. Il n'y a donc aucun danger, et c'est parfaitement portable (au contraire des globs).
 
Faire du bash moderne c'est bien, faire du shell portable c'est souvent mieux.

Reply

Marsh Posté le 04-03-2009 à 10:35:16    

find #monRepertoire# -maxdepth 1 -type d ! -name ".*" | wc -l  
 
Ca marche aussi, c'est moins propre que le bash mais plus que le ls.


---------------
Il y a trois sortes de mensonges : les mensonges, les gros mensonges et les statistiques !
Reply

Marsh Posté le 04-03-2009 à 15:38:14    

Mais -maxdepth n'est pas portable.

Reply

Marsh Posté le 04-03-2009 à 17:33:15    

matafan a écrit :

Certes mais là on ne regarde que la première lettre de la ligne. Il n'y a donc aucun danger, et c'est parfaitement portable (au contraire des globs).
 
Faire du bash moderne c'est bien, faire du shell portable c'est souvent mieux.


 
Peux-tu me citer une distro/plate forme ou les globs bash ne sont pas portables ?

Reply

Marsh Posté le 04-03-2009 à 17:45:09    

J'avait oublié un caractere dans mon code, c'est rectifié ( '*' changé en '*/' )

Reply

Marsh Posté le 04-03-2009 à 17:45:09   

Reply

Marsh Posté le 04-03-2009 à 19:10:54    

sputnick a écrit :


 
Peux-tu me citer une distro/plate forme ou les globs bash ne sont pas portables ?


 
Solaris8, j'en ai encore une 15aine en prod.


Message édité par Hrolf le 04-03-2009 à 19:11:10

---------------
Il y a trois sortes de mensonges : les mensonges, les gros mensonges et les statistiques !
Reply

Marsh Posté le 04-03-2009 à 19:25:23    

hrolf, peux tu faire cela et mettre le resultat ici ?

Code :
  1. cd /; bash -c 'echo *'


 
De toutes façons pour du code portable *vraiment portable* il faut utiliser perl.
Avec le shell il y aura toujours à batailler.
Mais pour des GNU/Linux il n'y a en général aucun souci.

Reply

Marsh Posté le 04-03-2009 à 23:03:53    

bash : "file not found" ?
 
Sur Solaris8 y'a pas bash :D
Et il est totalement hors de question que j'installe des packages de ce genre sur de vielles bouses dont personne n'est capable de me dire exactement comment elles sont installé et configuré, j'ai soulevé assé de tapis comme ça pas envi de trouver d'autres cadavres :p
 
Oui ça parrait con, mais les Linux ne sont pas les seul OSA, y'a les Unix dans le tas et dans beaucoup d'Unix bash n'est pas installé de base, voir pas installable du tout.
Y'en a même qui ont csh comme shell de base :o


---------------
Il y a trois sortes de mensonges : les mensonges, les gros mensonges et les statistiques !
Reply

Marsh Posté le 04-03-2009 à 23:31:33    

vous dont hrolf, noterez que j'ai bien précisé  
"Je propose en bash : " et pas "je propose en shell : " donc je persiste à dire que si bash est installé, cela est portable.  :wahoo:  
 
Pour des shells plus "rustiques", essayez ça :
 

Citation :

 
    cd foo || exit 1
    if test "`printf '%s %s %s' .* */`" = '. .. *' && test ! -f '*/'
    then
        echo "there's no dirs here"
    else
        echo "there's dir(s) here"
    fi


 
adaptation depuis : http://mywiki.wooledge.org/BashFAQ/004


Message édité par sputnick le 04-03-2009 à 23:40:13
Reply

Marsh Posté le 09-03-2009 à 11:31:48    

En fait, voila ce que je fais, et voila aussi ce qui ne marche pas.
je fais donc mon petit ls -d */, qui marche très bien (si, si!)
ls -d */ >& /dev/null
if ($status == 0) then
          set nbRep = `ls -d */ | wc -l` et je sors nbRep
else
        echo "le répertoire ne contient pas de répertoire" (en gros)
endif
 
Voila mon soucis : le ls -d */ >& /dev/null fait des trucs bizarres... De manière générale, je n'arrive pas à voir la valeur de status...
J'ai bien essayé echo $status dans le terminal, mais ça me renvoie une ligne désespérément vide (que j'ai ou non entré un comme valide auparavant)... Ou cela coince t'il ?
Merci d'avance !
 
 
edit : ah zut je viens de voir que mon message avec le "merci, mais je crois que je vais utiliser ls -d */ qui me semble simple" n'est pas passé... Alors merci à tous pour vos precedentes réponses !


Message édité par Namoureux le 09-03-2009 à 11:33:53
Reply

Marsh Posté le 09-03-2009 à 12:53:55    

C'est sensé être quoi "$status" ? Tu veux dire "$?" ?

Reply

Marsh Posté le 09-03-2009 à 13:53:08    

:hello:
 
normalement $status correspond a la valeur de ta variable associée
ds le script de Namoureux, on ne voit pas son affectation..
au pif,  
status=`ls -d */ > /dev/null`
echo $status donnerai la resultat de la cmde par exemple
 
sauf gourance de ma part

Reply

Marsh Posté le 09-03-2009 à 14:02:44    

namoueux, tu est faché avec les solutions propres ? On t'a donné le code, tu a juste à recopier et éventuellement adapter.
Qu'est-ce qui ne te convient pas ? Peux-etre n'a tu pas compris les réponses, dans ce cas demande !
On ne connait pas ta distribution. Peux tu la préciser ?
Ls j'ai pas dit que ça marchait pas mais juste c'est crade.

Reply

Marsh Posté le 10-03-2009 à 16:14:26    

Bonjour à tous !
 
Tout d'abord, non, je ne suis pas faché avec les solutions propres, mais je suis étudiant, et ces solutions font appel à des notion que je n'ai pas vu, et donc que je n'ai pas le droit d'utiliser (hé oui, c'est pour un dm).
En fait, la variable status contient le code de sortie du dernier programme exécuté. Donc, si le programme a bien tourné, status renvoie 0, sinon la variable est non nulle. Je dois m'en servir, mais ça ne fonctionne pas (quand je fait echo $status après une commande, qu'elle se soir ou non bien exécutée, ça ne me renvoie rien)
 
Voila mes soucis, peut on m'aider à ce niveau ?
Merci en tout cas de prendre le temps de m'aider !

Reply

Marsh Posté le 10-03-2009 à 16:24:14    

Oula, je vais me faire taper : cette variable marche en tcsh, et j'étais en bash... L'air bien bête que je viens de me taper...

Reply

Marsh Posté le 10-03-2009 à 22:06:59    

En shell (sh) c'est $?

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed