# Liste uniquement les sous répertoires d'un répertoire en c

**URL:** <https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965 "2016-02-20T20:56:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/1 "2016-02-20T20:56:07Z")

</div>

Bonjour,  
Le code lsd.c suivant :[code]  
#include \<dirent.h\>  
#include \<stdio.h\>  
#include \<stdlib.h\>  
#include \<string.h\>  
#include \<unistd.h\>  
#include \<sys/stat.h\>

int  
main(int argc, char \*argv[]) {  
int i;  
struct dirent \*dp;  
struct stat s;  
DIR \*dir;

```
if((argc > 1) && !strncmp(argv[1], "-v", 3)) {
	fputs("lsd-"VERSION"\n", stdout);
	exit(EXIT_SUCCESS);
}
for(i = 0; i < argc; i++)
	if((dir = opendir(argv[i]))) {
		fchdir(dirfd(dir));
		do
			if((dp = readdir(dir))
				&& (stat(dp->d_name, &s) != -1)
				&& S_ISDIR (s.st_mode)
				&& !access(dp->d_name, X_OK))
				puts(dp->d_name);
		while(dp);
		closedir(dir);
	}
return 0;

```

}[/code]produit un programme qui, lancé avec le nom d’un répertoire en argument va lister tous ses sous-répertoires comme  
la commande`ls -dU .*/ */`Du moins ce que je crois, or dans le listage les répertoires . et … sont listés deux fois, est-ce que quelqu’un saurait me dire pourquoi?

---

<div class="post-metadata">

**Author:** ![Dixippe](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/5f8ce5/32.png) [@Dixippe](https://www.debian-fr.org/u/Dixippe)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/2 "2016-02-20T20:56:08Z")

</div>

Bonjour Eol,

Je n’ai pas bien compris ton problème peux tu lister la commande et ton résultat?.

pour moi:

`$ lsd .
..
.
tmp`

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/3 "2016-02-20T20:56:08Z")

</div>

Bon en fait, je l’avais pas essayé dans un terminal mais dans un script où la sortie de lsd était renvoyée ailleurs,  
je viens de l’essayer dans un terminal et ça marche nickel, juste à le piper dans sort pour l’avoir dans l’ordre.  
Pourtant le même script avec `ls -dU */ .*/` marchait sans souci …  
le script qui s’appelle lsdsh est :`#!/bin/sh
prompt=Listedir
dir=`lsd $PWD | sort | dmenu -p "$prompt: $PWD" -i`
[-z $dir]
if [$? = 1]; then
  cd $dir && lsdsh ; else 
  actions
fi`  
Dans dmenu j’obtiens`. . .. .. puis la liste de mes répertoires`  
Si je remplace la ligne `dir=`lsd $PWD | sort | dmenu -p "$prompt: $PWD" -i``  
par`dir=`ls -dU */ .*/ | dmenu -p "$prompt: $PWD" -i``j’obtiens`. .. puis la liste de mes répertoires`

edit : Bon apparement, j’ai écrit un peu trop vite`lsd ~`dans un terminal me donne aussi . et … en double, tous les autres sous répertoires ne sont listés qu’une fois.

2ème edit : le problème n’a lieu que dans mon home.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/4 "2016-02-20T20:56:09Z")

</div>

J’ai pas de duplica chez moi (juste une erreur sur le fputs à la compilation).

---

<div class="post-metadata">

**Author:** ![Dixippe](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/5f8ce5/32.png) [@Dixippe](https://www.debian-fr.org/u/Dixippe)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/5 "2016-02-20T20:56:10Z")

</div>

Il me semble voir dans ton script que tu fais un dir=`lsd $PWD … puis  
un cd dans ce qu’il y a dans dir et tu relance lsd dessus.  
Donc si dir = . , cela fais un cd . && lsdsh qui fais un autre lsd de .

il faudrait que tu filtre soit dans ton script soit dans ton C les chemins “.” et “…”  
[par exemple dans C par && ((strchr(argv[1],’.’) == NULL) ].

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/6 "2016-02-20T20:56:10Z")

</div>

[quote=“Dixippe”]il faudrait que tu filtre soit dans ton script soit dans ton C les chemins “.” et “…”  
[par exemple dans C par && ((strchr(argv[1],’.’) == NULL) ].[/quote]  
J’ai pas tout suivi tu veut filtrer tout les dossiers caché ?  
Sinon vaut mieux utiliser !strcmp(chaine, “.”) et !strcmp(chaine, “…”).

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/7 "2016-02-20T20:56:10Z")

</div>

Je ne veux filtrer que les doublons, accessoirement lister les repertoires cachés après les autres mais ça c’est pas prioritaire.

[quote=“Dixippe”]Il faudrait que tu filtre soit dans ton script soit dans ton C les chemins “.” et “…”  
[par exemple dans C par && ((strchr(argv[1],’.’) == NULL) ].[/quote]Ça, je ne le souhaite pas car si mon doigt rippe et m’envoie dans un répertoire non désiré,  
je suis bien content de revenir en arrière avec en tapant … 😉

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/8 "2016-02-20T20:56:10Z")

</div>

> [@](#):
>
> J’ai pas de duplica chez moi (juste une erreur sur le fputs à la compilation).

Chez moi ça compile comme ça :`x@eol:~/sources/lsd$ make clean install
cleaning
lsd build options:
CFLAGS = -Os -I/usr/lib -DVERSION="0.1"
LDFLAGS = -L/usr/lib -lc
CC = cc
CC lsd.c
LD lsd
finished
installing executable file to /home/x/bin`  
Mais j’ai ces #[|]}$%³ de doublons qui reviennent de manière aléatoire.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/9 "2016-02-20T20:56:12Z")

</div>

```auto
J'ai exécuté ça une cinquantaine de fois sur différents dossiers, jamais de duplicat.
```

J’ai exécuté ça une cinquantaine de fois sur différents dossiers, jamais de duplicat.

---

<div class="post-metadata">

**Author:** ![Dixippe](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/5f8ce5/32.png) [@Dixippe](https://www.debian-fr.org/u/Dixippe)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/10 "2016-02-20T20:56:13Z")

</div>

J’ai implanté tes 2 programmes (C et script) et j’ai pas le problème des duplicatas ‘.’ et ‘…’

j’ai juste viré “else actions” du script (j’ai pas compris…).

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/11 "2016-02-20T20:56:13Z")

</div>

Tu as “.” et “…” en doublon quand tu donne plusieurs dossier en paramètres non ?  
Les dossiers “.” et “…” se trouvant dans tout les dossiers c’est normal. -\_-’

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/12 "2016-02-20T20:56:13Z")

</div>

Au passage :

`do
    if((dp = readdir(dir))
      && (stat(dp->d_name, &s) != -1)
      && S_ISDIR (s.st_mode)
      && !access(dp->d_name, X_OK))
    puts(dp->d_name);
while(dp);`  
C’est pas très lisible plutôt que ça :

`while((dp = readdir(dir)) == 0){
    int ret = stat(dp->d_name, &s);
    if(-1 != ret
      && S_ISDIR (s.st_mode)
      && !access(dp->d_name, X_OK)) {
        puts(dp->d_name);
    }
}`  
Le while(){} est plus approprié que le do{}while() ici. L’appel à stat() est plus lisible vu comme une instruction que caché dans une condition. Je pense qu’il faut toujours mettre les {} (dans les if, les for ou les while), sauf dans le cas où on le fait en une ligne par exemple :

```auto

```

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/13 "2016-02-20T20:56:21Z")

</div>

Non, j’ai des doublons en ne donnant qu’un seul répertoire en argument.

[quote=“MisterFreez”]`./ls.c .. | sort | uniq -d`  
J’ai exécuté ça une cinquantaine de fois sur différents dossiers, jamais de duplicat.[/quote]  
Moi non plus en pipant dans sort -u je n’ai pas de doublon 😉 même avec beaucoup de bonne volonté je ne crois pas que ce serait possible.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/14 "2016-02-20T20:56:22Z")

</div>

`man sort
man uniq`  
Désolé de faire du RTFM mais tu n’a pas pris en compte l’option “-d” ça fait toute la différence (et ça t’apprendras à poster trop vite 😉 ).

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:56 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/15 "2016-02-20T20:56:36Z")

</div>

[quote=“MisterFreez”]`man sort
man uniq`  
Désolé de faire du RTFM mais tu n’a pas pris en compte l’option “-d” ça fait toute la différence (et ça t’apprendras à poster trop vite 😉 ).[/quote]OK, j’ai été voir pour l’option -d de uniq et je vois ce que tu veux dire.  
As tu essayé le programme avec ~ ou / en argument?  
Chez moi, piper dans uniq -d me sort aussi les doublons (forcément) mais de manière plus lisible (merci pour l’astuce).

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:57 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/16 "2016-02-20T20:57:10Z")

</div>

Aucun doublon sauf si je liste deux répertoires (ce qui est logique).

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:57 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/17 "2016-02-20T20:57:18Z")

</div>

`x@eol:~/sources/lsd$ lsd /
lib
root
cdrom
bin
dev
sbin
selinux
home
etc
sys
tmp
proc
srv
usr
.
var
mnt
opt
media
..
boot``x@eol:~/sources$ lsd /
.
..
lib
root
cdrom
bin
dev
sbin
selinux
home
etc
sys
tmp
proc
srv
usr
.
var
mnt
opt
media
..
boot`  
La même commande lancée de deux répertoires différents donnant deux résultats différents, ça peut sembler normal dans certains cas, mais là non.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:57 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/18 "2016-02-20T20:57:20Z")

</div>

File nous ton code actuel.

---

<div class="post-metadata">

**Author:** ![eol](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/e/b782af/32.png) [@eol](https://www.debian-fr.org/u/eol)\
**Post date:** [Février 20, 2016, 8:57 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/19 "2016-02-20T20:57:36Z")

</div>

[quote=“MisterFreez”]File nous ton code actuel.[/quote]Bonjour,  
c’est exactement le même qu’au premier post.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 8:57 UTC](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965/20 "2016-02-20T20:57:39Z")

</div>

Repartons de zéro, ça donne quoi chez toi ça ?

[code]#include \<dirent.h\>  
#include \<stdio.h\>  
#include \<stdlib.h\>  
#include \<string.h\>  
#include \<unistd.h\>  
#include \<sys/stat.h\>

int main(int argc, char\*\* argv){  
int i;  
char\* rep;  
DIR\* dossier;  
struct dirent\* fichier;

if(1 == argc){  
fprintf(stderr, “Usage : %s […]\n”, argv[0]);  
return 1;  
}

for(i = 1; i \< argc; ++i){  
rep = argv[i];  
dossier = opendir(rep);  
if(NULL == dossier){  
fprintf(stderr, “Le répertoire %s est inaccessible.\n”, rep);  
continue;  
}  
while(fichier = readdir(dossier)){  
if(DT\_DIR == fichier-\>d\_type){  
printf("%s\n", fichier-\>d\_name);  
}  
}  
}  
return EXIT\_SUCCESS;  
}[/code]

[Page suivante](https://www.debian-fr.org/t/liste-uniquement-les-sous-repertoires-dun-repertoire-en-c/22965.md?page=2)
