Bonjour à tous,
Peut-on récupérer le nom d'un fichier redirigé en stdin sans utiliser argv?
monexe < nomdufichier.txt
:calim2:
Version imprimable
Bonjour à tous,
Peut-on récupérer le nom d'un fichier redirigé en stdin sans utiliser argv?
monexe < nomdufichier.txt
:calim2:
Sous Unix/Linux, j'ai bien peur que non.
C'est le shell depuis lequel tu tapes cette ligne de commande qui voit "<nomdufichier.txt", ouvre le fichier et écrit son contenu sur l'entrée standard de "monexe" (qu'il lance au préalable).
"monexe" n'a aucune connaissance du (nom du) fichier utilisé (argc vaut 1 et argv[0], "monexe"). Avec la banalisation des fichiers sous Unix/Linux, "monexe" n'a aucun moyen de faire la différence entre la redirection que tu utilises et des "choses" que tu taperais au clavier (jusqu'à un CTRL-D qui marque la fin de fichier).
Sous un Windows récent, il doit y avoir moyen de tricher, mais c'est le genre de chose que tu n'es pas censé faire.
Quel est ton problème exactement?
Bonjour,
Sous linux, le répertoire /proc/numero_du_process peut donner ce genre d'informations.
Tu ne peux pas à moins de tricher. C'est le rôle du shell que de mettre le contenu du fichier dans le flux stdin.
et imagine une commande genre :
Tu vas récupérer quoi ?Code:monexe < `cat fichier.txt | grep "toto"`
Est-ce que ce que tu risques de récupérer (peut être) aura un sens ?
Non, à partir du signe <, c'est géré par le shell et donc cela ne va pas au programme appelé. Exemple :
pourCode:
1
2
3
4
5
6
7 #include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { const wchar_t *cmd = GetCommandLine(); _tprintf(L"Command = [%s]\n", cmd); return 0; }
cela donne:Citation:
console.exe < fichier_qui_existe.txt
Je pense qu'il n'y a pas moyen de récupérer la commande complète dans ce cas là (sauf à tricher avec le système)Code:Command = [console ]
En fait, je pensais plutôt à GetFileInformationByHandle() sur le handle de l'entrée standard...
Oui je sais. Ce dont je n'étais pas sûr c'est si GetCommandLine retournait la ligne de commande telle que tapée dans le shell ou la "vraie ligne de commandes" (chemin de l'exe + arguments). Maintenant, nous savons que c'est la seconde ;).Citation:
Envoyé par ram-0000
Pour Linux, mabu m'a filé le doute avec le pseudo file system /proc mais ce que j'avançais et ce que ram-0000 confirmait n'est pas mis en défaut.
J'ai écrit quelques lignes de code, autant vous en faire profiter :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(int argc,char *argv[]) { char commande[128]; char cmdname[64]; char *ptr = commande; FILE *cmdfp; pid_t pid = getpid(); int i; sprintf(cmdname,"/proc/%lu/cmdline",(unsigned long)pid); cmdfp = fopen(cmdname,"r"); fgets(commande,128,cmdfp); fclose(cmdfp); /************************* resultat (partiel) de "man proc" /proc/[number]/cmdline This holds the complete command line for the process, unless the process is a zombie. In the latter case, there is nothing in this file: that is, a read on this file will return 0 charac‐ ters. The command-line arguments appear in this file as a set of null-separated strings, with a further null byte ('\0') after the last string. **************************/ for (i=0;;i++) { printf("arg %d : %s\n",i,ptr); ptr = strchr(ptr,'\0'); if (ptr[1] == '\0') break; else ptr++; } }
Voici différents résultats, sous Ubuntu (mon exe s'appelle "stdin") :
On ne récupère pas plus de choses en allant chercher sous /proc qu'en examinant argc/argv.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 plx@sony:~$ ./stdin un 2 trois 4 arg 0 : ./stdin arg 1 : un arg 2 : 2 arg 3 : trois arg 4 : 4 plx@sony:~$ ./stdin 1 deux 3 quatre < stdin.c arg 0 : ./stdin arg 1 : 1 arg 2 : deux arg 3 : 3 arg 4 : quatre
Pour continuer sur ce sujet, ce n'est pas seulement les redirections qui ne sont pas vues par l'exécutable mais aussi tous les "wild-cards" (*, ?, etc...) qui sont traités par le "shell interactif" et c'est pour cela que sous DOS, il y a bien longtemps (je n'ai pas réessayé depuis), un "del *.*" demandait confirmation ("del" voyait le "*.*") et que, sous Linux/Unix, 'un "rm *" ne POUVAIT pas faire la différence entre "rm *" et "rm" suivi de tous les fichiers du répertoire courant.