2009-02-04 8 views
5

Supponiamo che ci sia qualche funzionalità necessaria per un'applicazione in sviluppo che potrebbe essere ottenuta effettuando una chiamata di sistema a un programma a riga di comando o utilizzando una libreria. Supponendo che l'efficienza non sia un problema, è una cattiva pratica semplicemente effettuare una chiamata di sistema a un programma invece di utilizzare una libreria? Quali sono gli svantaggi di fare questo?È una cattiva pratica usare la funzione system() quando invece potrebbero essere utilizzate le funzioni di libreria? Perché?

Per rendere le cose più concrete, un esempio di questo scenario sarebbe un'applicazione che deve scaricare un file da un server Web, per il quale potrebbe essere utilizzato il programma cURL o la libreria libcURL.

risposta

10

A meno che non si stia scrivendo il codice per un solo sistema operativo, non è possibile sapere se la chiamata di sistema funzionerà. Cosa succede quando c'è un aggiornamento di sistema o un aggiornamento del SO?
Mai utilizzare una chiamata di sistema se esiste una libreria per eseguire la stessa funzione.

+2

Proprio questo sera ho passato un paio di piccoli programmi di utilità Perl e ho sostituito usando una chiamata di sistema al comando copia con File :: Copia - la nuova versione è più breve e funziona su tutte le mie piattaforme invece che su Windows. – Sol

2

La sicurezza è una preoccupazione. Un CURL dannoso potrebbe causare il caos nel tuo programma. Dipende se questo è un programma personale in cui la velocità di codifica è il tuo obiettivo principale, o un'applicazione commerciale in cui cose come la sicurezza giocano un ruolo.

3

Preferisco le librerie a causa del problema delle dipendenze, ovvero l'eseguibile potrebbe non essere presente quando viene chiamato, ma la libreria sarà (presupponendo che i riferimenti alle librerie esterne vengano risolti quando il processo inizia sulla piattaforma). In altre parole, l'utilizzo di librerie sembrerebbe garantire un risultato prevedibile più stabile in più ambienti rispetto alle chiamate di sistema.

3

Ci sono diversi fattori da tenere in considerazione. Uno dei punti chiave è l'affidabilità della presenza del programma esterno su tutti i sistemi in cui è installato il software. Se c'è una possibilità che manchi, allora forse è meglio farlo all'interno del tuo programma.

Ponderando ciò, è possibile che il codice aggiuntivo caricato nel programma sia proibitivo: non è necessario il codice gonfiato per una parte della propria applicazione utilizzata in modo raro.

La funzione system() è comoda, ma pericolosa, non da ultimo perché invoca una shell, di solito. Potrebbe essere meglio chiamare il programma più direttamente - su Unix, tramite le chiamate di sistema fork() ed exec(). [Si noti che una chiamata di sistema è molto diversa dal chiamare la funzione system(), incidentalmente!] OTOH, potrebbe essere necessario preoccuparsi di garantire che tutti i descrittori di file aperti nel programma siano chiusi, specialmente se il programma è una sorta di demone in esecuzione per conto di altri utenti; questo è meno un problema se non si stanno usando privilegi speciali, ma è comunque una buona idea non dare al programma invocato l'accesso a tutto ciò che non si intende. Potrebbe essere necessario controllare la chiamata di sistema fcntl() e il flag FD_CLOEXEC.

In genere, è più facile mantenere il controllo delle cose se si crea la funzionalità nel programma, ma non è una decisione banale.

1

Le chiamate di sistema sono molto più difficili da eseguire in sicurezza.

Tutti i tipi di caratteri divertenti devono essere codificati correttamente per passare gli argomenti e i tipi di codifica possono variare a seconda della piattaforma o della versione del comando. Pertanto, effettuare una chiamata di sistema che contenga tutti i dati dell'utente richiede molto controllo della sanità mentale ed è facile commettere un errore.

1

Sì, come già detto, tenere presente la differenza tra le chiamate di sistema (come le chiamate fcntl() e open()) e system().:)

Nelle prime fasi della prototipazione di un programma c, faccio spesso chiamate esterne a programmi come grep e sed per la manipolazione di file tramite popen(). Non è sicuro, non è sicuro, e certamente non è portatile. Ma ti può permettere di andare rapidamente. Questo è prezioso per me. Mi consente di concentrarmi sul nucleo molto importante del programma, di solito il motivo per cui ho usato c in primo luogo.

Nei linguaggi di alto livello, è meglio avere una buona ragione. :)

0

Invece di fare entrambi, farei Unix e costruire un framework di script intorno alla tua app, usando gli argomenti della riga di comando e lo stdin.

0

Altri hanno menzionato punti positivi (affidabilità, sicurezza, sicurezza, portabilità, ecc.), Ma ne butto fuori un altro. Prestazione. In genere è molto più veloce chiamare una funzione di libreria o anche generare un nuovo thread, quindi è necessario avviare un intero processo (e quindi è ancora necessario verificarne/verificarne l'esecuzione e analizzare l'output!)