Comandi come “ls -l” non in esecuzione in execl, mentre in execvp funziona

Utilizzando il codice riportato di seguito nel execl variante, ls funziona, ma ls -l non funziona, ma nel mio execvp approccio ls e ls-l opere. Il motivo per cui ho adottato il execl approccio è perché il percorso del file binari potrebbero differire mentre execvp non mi forniscono funzionalità. Idealmente voglio execl a lavorare anche su ls -l, ma in questo momento non funziona su ls -l. Ho provato a leggere le pagine man, ma questo non ha aiutato.

void child(int argc, char *argv[MAX_ARGS])
{
        execvp(argv[0], argv);
}


void child(char *argv[], char* path)
{
        execl(path, argv, NULL);
}
InformationsquelleAutor markfiel | 2013-02-22

 

One Reply
  1. 12

    Con execl(), è necessario elencare gli argomenti uno per uno; è utile solo se si sa esattamente cosa si sta andando a eseguire prima del tempo:

    execl("/bin/ls", "ls", "-l", (char *)0);
    execl("/bin/sh", "sh", "-c", "ls -l", (char *)0);
    execl("/bin/ls", "pink elephants", "-l", (char *)0);

    Etc.

    Se non sapete quante discussioni si ha a che fare con, utilizzare execvp() o uno degli altri membri del execv*() famiglia. Si noti inoltre che è necessario specificare il percorso del comando; execvp() fa una ricerca $PATH, ma execl() non.
    Nota anche che si arriva a scegliere il valore passato come argv[0].

    Il motivo per cui ho adottato il execl() approccio è perché il percorso del file binari potrebbero differire mentre execvp() non mi forniscono funzionalità.

    Non sono sicuro di cosa intendi. Con execvp(), è possibile specificare:

    char *argv[] = { "ls", "-l", 0 };
    execvp(argv[0], argv);
    execv("/bin/ls", argv);

    Il execvp() ricerca ls su $PATH e l’esecuzione del primo programma corrispondente. La seconda esecuzione /bin/ls senza guardare $PATH a tutti.

    char *argv[] = { "/bin/ls", "-l", 0 };
    
    execv(argv[0], argv);
    execvp(argv[0], argv);

    Uno di questi funzionerà; la seconda non utilizzare un PERCORSO di ricerca basato su perché il nome del file eseguibile (argv[0]) contiene una barra.


    Quello che mi confonde è che in execvp(argv[0], argv); perché ci si passa l’intera argv come il 2 ° parametro? Quindi suppongo argv[0] era "ls -l", perché dobbiamo passare l’intero argv come il 2 ° parametro?

    Supponendo argv[0] contiene "ls -l", hai un problema. La maggior parte dei sistemi non si dispone di un file “/bin/ls -l” o “/usr/bin/ls -l” (dove il vuoto è parte del nome), ma è quello che si sarebbe cercando di eseguire.

    Il exec*() funzioni sono le funzioni di basso livello per l’esecuzione di processi. Il primo argomento indica il programma da eseguire (normalmente, un binario; a volte uno script con un shebang linea come #!/bin/sh come prima riga). In caso di execv() o execvp() o execve() o execvpe(), il secondo argomento è il vettore di argomenti, proprio come il main() funzione riceve un vettore di parametri (o argomento vettoriale, quindi argv). Questo è un null-terminated elenco degli argomenti del programma. Se si desidera eseguire il ls di comando con l’opzione -l, quindi è necessario specificare nel argv tre(!) valori "ls", "-l" e un puntatore null:

    char argv[] = { "ls", "-l", 0 };

    Con il execl*() funzioni, è necessario specificare il programma da eseguire come primo argomento, e questo è poi seguito dall’argomento vettoriale scritto:

    execl("/bin/ls", "ls", "-l", (char *)0);

    Se si dispone di 10 argomenti, è necessario scrivere 10 argomenti (più il puntatore null).

    In exec*() funzioni, i nomi contengono:

    • l — elenco formato argomenti
    • v — formato vettoriale argomenti
    • p — do PERCORSO di ricerca sul programma (se il nome non contiene una barra)
    • e — prendere un vettore di variabili di ambiente troppo

    Questi si combinano per dare:

    • execl()
    • execv()
    • execlp()
    • execle()
    • execvp()
    • execve()

    Talvolta è un po ‘ fastidiosa che non c’è un execlpe() e execvpe() (ma si veda il Linux estensione execvpe(3)). È anche tradizionale per la man 2 exec pagine di omettere alcuni di questi dalla sinossi, ma parlare di loro nel corpo della pagina di manuale, tradizione/legacy risalente ad almeno 7 ° Edizione UNIX™ nel 1979 (e perpetuata almeno fino a RHEL 5 Linux e Mac OS X 10.7.5; il man 2 execl pagina cita execve() ma non elencare nella Sinossi sezione). L’altro exec*() funzioni possono essere costruiti in cima execve() — che è la funzione fondamentale nella serie (ed è elencato come execve(2) in Linux manuali come risultato).

    • Quello che mi confonde è che in execvp(argv[0], argv); perché ci si passa l’intera argv come il 2 ° parametro? Quindi suppongo argv[0] è stato ls -l, perché dobbiamo passare l’intero argv come il 2 ° parametro? Ho provato a studiare la pagina di man, ma ancora non ha senso per me
    • Se argv[0] era "ls -l", sarebbe un errore, perché non c’è nessun programma chiamato ls -l.

Lascia un commento