Qual è la differenza tra un comando incorporato e uno che non lo è?


72

C'è qualche differenza intrinseca tra un comando incorporato e un altro comando che può nominalmente fare la stessa cosa?

per esempio. I builtin ottengono un trattamento "speciale"? ... c'è meno spese generali di gestione? .. o sono semplicemente semplicemente "integrati"; come il cruscotto della tua auto?

... ed esiste un elenco (attuale) definitivo di questi builtin?

Risposte:


90

Dai tuoi commenti, sembri essere confuso su cosa sia esattamente una shell . Il kernel è responsabile della gestione del sistema. È la parte che carica ed esegue effettivamente i programmi, accede ai file, alloca la memoria, ecc. Ma il kernel non ha un'interfaccia utente; puoi comunicare con esso solo usando un altro programma come intermediario.

Una shell è un programma che stampa un prompt, legge una riga di input da te e quindi la interpreta come uno o più comandi per manipolare i file o eseguire altri programmi. Prima dell'invenzione della GUI, la shell era l'interfaccia utente principale di un sistema operativo. Su MS-DOS, è stata chiamata la shell command.come poche persone hanno mai provato a usarne una diversa. Su Unix, tuttavia, ci sono state a lungo più shell da cui gli utenti potevano scegliere.

Possono essere divisi in 3 tipi. Le shell compatibili con Bourne usano la sintassi derivata dalla shell Bourne originale . Le shell C usano la sintassi della shell C originale . Quindi ci sono shell non tradizionali che inventano la propria sintassi o ne prendono in prestito uno da un linguaggio di programmazione e sono generalmente molto meno popolari dei primi due tipi.

Un comando integrato è semplicemente un comando che la shell esegue se stesso, invece di interpretarlo come una richiesta per caricare ed eseguire altri programmi. Questo ha due effetti principali. Innanzitutto, di solito è più veloce, perché caricare ed eseguire un programma richiede tempo. Naturalmente, più tempo impiega il comando a eseguire, meno significativo è il tempo di caricamento rispetto al tempo di esecuzione complessivo (poiché il tempo di caricamento è abbastanza costante).

In secondo luogo, un comando integrato può influire sullo stato interno della shell. Ecco perché comandi come cd devono essere integrati, perché un programma esterno non può cambiare la directory corrente della shell. Altri comandi, come echo, potrebbero essere integrati per efficienza, ma non c'è motivo intrinseco che non possano essere comandi esterni.

Quali comandi sono integrati dipende dalla shell che stai usando. Dovrai consultare la sua documentazione per un elenco (ad esempio, bashi comandi integrati sono elencati nel Capitolo 4 del suo manuale ). Il typecomando può dire se un comando è incorporato (se la shell è compatibile con POSIX), poiché POSIX richiede che typesia incorporato. Se whichnon è un built-in nella tua shell, probabilmente non conoscerà i built-in della tua shell, ma cercherà solo programmi esterni.


Le applicazioni comunicano con il kernel emettendo interruzioni, in realtà.
Nathan Osman,

11
@George: le applicazioni comunicano con il kernel emettendo syscall, che a seconda del sistema operativo e dell'architettura possono o meno utilizzare gli interrupt. Gli utenti, di regola, non rilasciano interruzioni.
Gilles 'SO- smetti di essere malvagio' il

2
@cjm: Sembra così semplice quando lo spieghi così:) ... hai sicuramente aiutato a liberare la nebbia ... solo una leggera nebbia ora .. (in realtà è proprio così che tempo fa qui, stamattina. .. piacevolmente nebbioso;) ... grazie
Peter.O

@Gilles: Davvero? Ho pensato che tutti i programmi in modalità utente comunicassero con il kernel tramite gli interrupt (su certe architetture, ovviamente).
Nathan Osman,

2
@cjm Risposta molto approfondita e istruttiva. Ho imparato molto leggendolo. :)
ankush981,

37

Esistono tre livelli di utilità integrate:

  • Alcune utility fanno davvero parte della shell come linguaggio di programmazione, anche se non sono parole riservate . Essi sono utilità controllo di flusso ( ., :, break, continue, return, trap, exit, exec, eval), utilità parametri relative ( set, unset, shift, export, readonly, local¹, typeset¹), alias utenze ( alias², unalias²) e times³. Questi speciali incorporati ricevono un trattamento speciale:

    • Se si passano gli argomenti sbagliati a uno speciale incorporato, la shell stessa potrebbe interrompersi, anziché saltare al comando successivo dopo aver visualizzato un messaggio di errore.
    • La sintassi di pre-assegnazione foo=bar utilityha un significato diverso: è una normale assegnazione di parametri (ovvero equivalente a foo=bar; utility), invece di assegnare all'ambiente solo per la durata dell'utilità.
  • Alcune utility devono essere implementate all'interno della shell perché agiscono sulle impostazioni interne della shell. Ciò comprende:

    • utilità che agiscono sulla directory corrente della shell come cd, dirs, pushd, popd;
    • utilità di controllo lavoro quali bg, disown, fg, jobs, wait;
    • utilità che leggono o manipolano altri attributi shell quali builtin, command, hash, read, type, ulimit, umask;
    • utilità relative alle funzioni interattive, quando sei presente, ad esempio fc, history, bind.
  • Alcune utility sono in genere implementati come built-in per puro spettacolo : echo, printf, test, true, false.

Le shell avanzate come bash , ksh e zsh in genere hanno più built-in, spesso per implementare funzionalità non standard (di solito per l'interazione). Il manuale di ogni shell ti dirà quali comandi sono integrati, anche se alcune shell ( almeno zsh ) supportano moduli caricabili dinamicamente che possono fornire più built-in.

¹ Sconosciuto su POSIX, ma speciale in ksh e molte altre shell.
² Ordinario in POSIX, ma speciale in ksh e molte altre shell.
³ In ksh, timesè un wrapper attorno alla timeparola chiave: è un alias per { { time;} 2>&1;}. Si noti che POSIX consente timedi essere un'utilità esterna con analisi ordinaria o una parola chiave che si applica a un'intera pipeline (che è in ksh, bash in zsh).


3
Queste distinzioni sono davvero importanti.
dmckee,

Domanda veloce, quindi cosa significa "ordinaria parametrizzazione" quando lo facciamo while IFS= read -r line?
Sergiy Kolodyazhnyy,

@SergiyKolodyazhnyy readnon è un builtin speciale, quindi IFS=readimposta la variabile solo per la durata del comando.
Gilles 'SO- smetti di essere malvagio' il

10

Un builtin è un comando fornito dalla shell, piuttosto che da un programma esterno. Ecco gli elenchi bashdei built-in (sono anche elencati nella pagina man di bash) e zshdei built-in . kshfornisce un elenco eseguendo builtin.

Per sapere se un determinato comando è incorporato, è possibile eseguire type command. Provare type fore type lsvedere questo.


typesembra fare il trucco; grazie per quello ... ma mi chiedo ancora cosa significhi "fornito dalla shell" ... Forse ho bisogno di capire più a fondo come la shell si collega al kernel .... ma non alle 2 del mattino .. Verrò torniamo a questo domani
Peter.O

1

Ogni distro e shell ha una raccolta diversa di comandi rispetto alle funzioni di shell integrate. Generalmente l'idea è che le shell incorporino le funzioni più comuni e semplici per risparmiare tempo, velocità e integrare la volontà con il resto del loro set di funzionalità. Il sovraccarico è molto più basso poiché non è necessario avviare un altro processo di sistema. Tuttavia è possibile mescolare e abbinare. Potresti eseguire una shell che ha un buildin per qualcosa, ma hai anche quel comando sul tuo sistema. Di solito l'integrato avrebbe la priorità, ma potresti controllarlo.

Puoi facilmente scoprire se un comando specifico è incorporato o meno eseguendolo type mycommand. La maggior parte delle pagine man della shell hanno anche un elenco dei loro builtin.

Modifica: utilizzare typeper scoprire se un comando è incorporato e, in caso contrario, whichper sapere da dove verrà eseguito.


@Caleb: grazie per il tuo commento, ma mi viene da chiedermi cosa sia esattamente un "processo di sistema" .. Continuo a vedere riferimenti a quel momento ma non capisco dove sia la distinzione .... (a proposito non posso vedere come 'quale' è un indicatore assoluto) .. es. 'quale =>"/bin/echo" and tipo di eco echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" e type dd=> "dd is / bin / dd" ... quindi, sono in parte lì ....
Peter.O

"Processi di sistema" significa solo che viene avviato come un'applicazione indipendente gestita dal kernel. L'alternativa nel caso dei builtin è semplicemente l'esecuzione di una sotto-funzione nel codice già in esecuzione della shell. Nell'esempio che dai, typeè l'indicatore migliore di ciò che viene eseguito, ma noti che echoè sia un built-in che un'applicazione con quel nome. Se la tua shell non avesse un builtin nel sistema, ne verrebbe eseguito uno.
Caleb,

2
whichnon è necessariamente un comando integrato e, in caso contrario, non sarà a conoscenza dei built-in della shell. POSIX richiede che si typetratti di un comando integrato, quindi è sempre a conoscenza degli incorporati.
cjm

Molti sistemi di nave con un alias di whichper typeo qualche set di opzioni per esempio alias which='type -path'- questo potrebbe essere fonte di confusione.
Casuale 832

1
Non posso votare questo fino a quando non whichviene sostituito da type. Ho usato che, ancora e ancora, non sapevo typeed era molto stupito da lern, che whichè giusto, se decidessi tra i programmi.
utente sconosciuto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.