Domanda

Sto scrivendo il mio shell in C. È necessario essere in grado di visualizzare la directory corrente degli utenti, eseguire comandi in base al percorso completo ( deve utilizzare EXECV ) e consentire all'utente di Cambia la directory con CD.

Questo è il lavoro. L'insegnante ci ha dato solo un primer di base su C e uno scheletro molto breve su come il programma dovrebbe funzionare. Dal momento che non sono uno da rinunciare facilmente ho cercato come fare questo per tre giorni, ma ora sono scatenato.

Questo è ciò che ho finora:

    .
  • Visualizza il nome utente, il computerername e la directory corrente dell'utente (default nella directory home).
  • richiede l'utente per l'input e riceve l'ingresso
  • Divide l'ingresso dell'utente da "" in una serie di argomenti
  • Divide il percorso variabile dell'ambiente da ":" in una serie di token

    Non sono sicuro di come procedere da qui. So che devo usare il comando ECECV ma nella mia ricerca su Google non ho davvero trovato un esempio che capisco. Ad esempio, se il comando è BIN / LS, come viene conosciuto Execv visualizzati tutti i file / cartelle dalla directory home? Come posso dire al sistema Ho cambiato la directory?

    Ho usato molto questo sito che è stato utile: http://linuxgazette.net/ 111 / RAMANKUTTY.HTML Ma di nuovo, sono scatenato.

    Grazie per il tuo aiuto. Fammi sapere se dovrei pubblicare alcuni del mio codice esistente, non sono sicuro che fosse necessario però.

È stato utile?

Soluzione

Per implementare il comando CD è sufficiente per la chiamata di sistema chdir.

#include <unistd.h>

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

Quindi puoi chiamare qualcosa come:

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

Il valore di ritorno del chdir è 0 quando è stato possibile modificare in quella directory e -1 se si è verificato un errore. Per l'errore dovresti consolidare la pagina Man.

La directory corrente può essere controllata da qualsiasi programma, quindi se si esegue ls senza alcun argomento, quindi LS controlla in quale directory è in esecuzione e utilizza questa directory come unico argomento. Questa è una caratteristica di LS e non della chiamata execv.

per la seconda parte.

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

execv Esegue un file eseguibile presso il path indicato e con gli argomenti forniti in argv. Quindi, se vuoi eseguire /bin/ls ../foo /bar, hai bisogno di qualcosa di simile a

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

L'errore restituito da execv è -1. Se vuoi sapere perché non ha eseguito il Comando controlla le pagine dell'uomo.

Il NULL in char *argv[] = {cmd_str, "../foo", "/bar", NULL }; è lì per indicare che non ci sono altri argomenti dopo il NULL.

la terza parte. Il sistema basato su Unix tratta normalmente i comandi con A / in AS come comandi che possono essere eseguiti direttamente. Il che significa che hai prima verificare se c'è una barra nella stringa di comando data.

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

Se non c'è una barra, è necessario passare attraverso tutte le directory in PATH e controllare se è possibile eseguire il comando. Quindi il comando specificato è ls ../foo /bar e consente di assumere il valore di PATH è ".:/sbin:/bin:/usr/bin". Ci proveremmo quindi a eseguire prima di eseguire ./ls ../foo /bar quindi /usr/bin/ls ../foo /bar e all'ultimo /bin/ls ../foo /bar.

Spero che questo aiuti.

Altri suggerimenti

.

Ad esempio, se il comando è bin/ls, come funziona execv conosci il display Tutti i file / cartelle dalla directory home? Come posso dire al sistema Ho cambiato la directory?

Ogni processo ha una directory di lavoro corrente, che può essere modificata utilizzando chdir . I processi figlio erediteranno la directory di lavoro dal loro genitore. Quindi in generale la tua shell gestirà la sua corrente di lavoro corrente in risposta ai comandi cd inseriti dall'utente. Quando viene inserito un comando quale non è un integratore, allora fork per creare a Processo infantile e quindi chiamare execv lì per eseguire il binario.

Se si è una formulazione di prendere il PATH in conto per i nomi dei programmi che non contengono alcuna parte della directory, è necessario provare tutte le possibili combinazioni di un elemento PATH e il nome del programma. È possibile verificare se il file denominato esiste, o semplicemente provare ad eseguirlo e continuare con il successivo se non riesce. Se tutte le chiamate execv non sono riuscite, dovrai chiamare _exit per terminare il processo figlio .

Nota che la maggior parte delle shell tratterà qualsiasi comando che contiene un / come percorso che viene passato a execv direttamente. Se il percorso non START con un /, quindi è un percorso relativo e il sistema operativo lo risolverà rispetto alla directory di lavoro corrente. In altre parole, il bin/ls dal tuo esempio si riferirebbe al binario ls nella directory bin che è una sottodirectory della directory di lavoro corrente. Solo i comandi che non contengono affatto / sono interpretati come un comando incorporato (come cd) o il nome di alcuni Binari situati sul PATH.

Il primo argomento a execv è il percorso come l'hai calcolato. Il primo elemento dell'elenco argv è tradizionalmente uguale al nome poiché è stato emedito, cioè senza una directory PATH aggiunta. Dopo quel primo argomento, vengono superati tutti i parametri della riga di comando aggiuntivi, seguiti da un NULL per terminare l'elenco.

Penso che il problema sia che ritieni che il guscio sia responsabile di fare il lavoro di ls.ls non è davvero una "parte" del guscio (almeno in questo caso almeno).La shell esegue un programma chiamato ls.La maggior parte dei commenti sembra spiegare come trovare ls, ma non credo che sia ciò che sei confuso.

Dovresti considerare attentamente quale sia il punto del guscio prima di scriverlo.I commenti hanno indirettamente sottolineato il fatto che la shell "semplicemente" deve "chiamare" programmi come ls e chdir, non eseguire le loro attività.

ls conosce da solo che, se non fornito alcun argomento, è supposto elencando i file nella directory di lavoro corrente come restituito da getcwd

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top