Question

Je suis en train d'écrire mon propre coquille en C.Il doit être capable d'afficher les utilisateurs du répertoire courant, exécuter des commandes basées sur le chemin d'accès complet (devez utiliser execv), et permettre à l'utilisateur de changer le répertoire avec le cd.

Ce sont les devoirs.Le professeur nous a donné un aperçu sur C et une très brève squelette sur la façon dont le programme devrait fonctionner.Depuis que je ne suis pas du genre à abandonner facilement, j'ai fait des recherches sur comment faire cela pendant trois jours, mais maintenant, je suis perplexe.

C'est ce que j'ai à ce jour:

  • Affiche le nom d'utilisateur, nom de l'ordinateur, et le répertoire courant (par défaut le répertoire home).
  • Invite l'utilisateur à l'entrée, et se met à l'entrée
  • Divise l'entrée de l'utilisateur par "" dans un tableau d'arguments
  • Divise la variable d'environnement PATH par des ":" dans un tableau de jetons

Je ne suis pas sûr de savoir comment procéder à partir d'ici.Je sais que j'ai eu à utiliser le execv de commande, mais dans mes recherches sur google je n'ai pas vraiment trouvé un exemple, je comprends.Par exemple, si la commande bin/ls, comment ne execv savoir l'affichage de tous les fichiers/dossiers à partir du répertoire de base?Comment puis-je dire au système que j'ai changé le répertoire?

J'ai été en utilisant ce site, beaucoup qui a été utile: http://linuxgazette.net/111/ramankutty.html mais encore une fois, je suis perplexe.

Merci pour votre aide.Permettez-moi de savoir si je doit poster une partie de mon code, je suis ne savais pas si c'était nécessaire.

Était-ce utile?

La solution

Pour mettre en œuvre la commande cd, vous avez juste besoin de l'appel système chdir.

#include <unistd.h>

int chdir(
    const char *path /* the path name */
);

Ainsi, vous pouvez simplement appeler quelque chose comme:

int ret1 = chdir("../foo/bar");

La valeur de retour de chdir est 0 lorsque c'était possible de changer dans ce répertoire et -1 si une erreur s'est produite.Pour l'erreur, vous devez consolider la page de man.

Le répertoire courant peut être contrôlé par n'importe quel programme, donc, si vous exécutez ls sans arguments, puis ls vérifie dans quel répertoire il est en cours d'exécution et utilise ce répertoire que le seul argument.C'est une caractéristique des ls et pas de la execv appel.

Pour la deuxième partie.

#include <unistd.h>
int execv(
     const char *path, /* programm path*/
     char *const argv[]/* argument vector*/
);

execv exécute un fichier exécutable à l' path et avec les arguments donnés dans argv.Donc, si vous voulez exécuter /bin/ls ../foo /bar, vous avez besoin de quelque chose de similaire à

char *cmd_str = "/bin/ls";
char *argv[] = {cmd_str, "../foo", "/bar", NULL };
if (execv(cmd_str, argv) == -1 ){
    /* an error occurred */
}

L'erreur renvoyée par execv est -1.Si vous voulez savoir pourquoi il n'a pas exécuté le système comand consultez les pages man.

L' NULL dans char *argv[] = {cmd_str, "../foo", "/bar", NULL }; il est là pour indiquer qu'il n'y a pas d'autres arguments après la NULL.

La troisième partie.Unix système normalement traiter les commandes avec un / dans les commandes qui peuvent être exécutées directement.Ce qui signifie que vous vérifiez d'abord si il y a une barre oblique dans la chaîne de commande.

int ret_value;
if (strchr(cmd_str, '/')
    if (execv(cmd_str, argv) == -1 ){
        /* an error occurred */
    }

Si il n'y a pas de slash, alors vous devez aller à travers tous les répertoires dans PATH et de vérifier si vous pouvez exécuter la commande.Si la commande est ls ../foo /bar et supposons que la valeur de PATH est ".:/sbin:/bin:/usr/bin".De nous, puis essayez d'exécuter en premier lieu ./ls ../foo /bar alors /usr/bin/ls ../foo /bar et enfin /bin/ls ../foo /bar.

Espérons que cette aide.

Autres conseils

Par exemple, si la commande est bin/ls, comment ne execv savoir l'affichage de tous les fichiers/dossiers à partir du répertoire de base?Comment puis-je dire au système que j'ai changé le répertoire?

Chaque processus dispose d'un répertoire de travail courant, qui peut être modifiée à l'aide de chdir.Les processus enfants hériteront le répertoire de travail de leur parent.Donc, en général, votre shell va gérer son répertoire de travail courant en réponse à cd les commandes entrées par l'utilisateur.Lorsqu'une commande est entrée, qui n'est pas un builtin, alors vous aurez fork pour créer un processus enfant et ensuite appeler execv là pour exécuter le binaire.

Si vous voulez prendre le PATH en compte pour le programme de noms qui ne contiennent pas de répertoire de la partie, alors vous devriez essayer toutes les combinaisons possibles d'un PATH élément et le nom du programme.Vous pouvez vérifier si le nom de fichier ne existe pas, ou tout simplement essayer de l'exécuter et de continuer avec le prochain, si cela échoue.Si tous les execv les appels a échoué, vous devez les appeler _exit afin de terminer le processus de l'enfant.

Notez que la plupart des coquilles à traiter toute commande qui contient un / comme un chemin qui passe à execv directement.Si le chemin d'accès n' démarrer avec un /, puis c'est un chemin relatif, et le système d'exploitation va résoudre en ce qui concerne le répertoire de travail courant.En d'autres termes, l' bin/ls à partir de votre exemple, reportez-vous à la ls binaire dans le bin répertoire qui est un sous-répertoire du répertoire de travail courant.Seules les commandes qui ne contiennent pas de / tous sont soit interprété comme une interface de commande (comme cd) ou le nom de certains binaire situé sur la PATH.

Le premier argument de execv est le chemin que vous avez calculé il.Le premier élément de la argv liste traditionnellement égale le nom tel qu'il a été enetered, c'est à diresans ajouté PATH répertoire.Après ce premier argument, tous les autres paramètres de ligne de commande sont transmis, suivie par un NULL pour mettre fin à la liste.

Je pense que le problème est que vous croyez que la coquille est responsable pour l'exécution des travaux de ls. ls n'est pas vraiment une "partie" de la coque (dans ce cas au moins).La coquille exécute un programme appelé ls.La plupart des commentaires semblent expliquer comment trouver ls, mais je ne crois pas que c'est ce que vous êtes confus au sujet de.

Vous devriez examiner attentivement ce qui est le point de la coque avant de vous écrire.Les commentaires ont indirectement souligné le fait que la coquille "simplement" a "d'appeler" des programmes comme ls et chdir, pas s'acquitter de leurs tâches.

ls sait en soi que, sinon donné aucun argument, il est censé répertorier des fichiers dans le répertoire de travail actuel, comme retourné par getcwd

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top