Perché echo è una shell integrata nel comando?


34
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

Perché non è un programma di utilità eco indipendente come ls, ps, catecc? Perché è specifico per la shell? Qualche buona ragione?


5
Ricorda che questo è specifico per shell. ZSH lo integra, BASH no.
tsvallender,

21
@tsv: echosicuramente è un builtin di Bash. In effetti, è incorporato in ogni grande shell moderna.
In pausa fino a nuovo avviso.

Risposte:


71

Esistono due classi di builtin:

  1. Alcuni comandi devono essere integrati nel programma shell stesso perché non possono funzionare se sono esterni.

    cdè uno di questi poiché, se fosse esterno, potrebbe solo cambiare la propria directory; non ha potuto influenzare l'attuale directory di lavoro della shell. (Vedi anche: Perché cdnon è un programma? )

  2. L'altra classe di comandi è integrata nella shell esclusivamente per motivi di efficienza.

    La pagina man ha una sezione comandi incorporati che cita , e come esempi di comandi in questa classe.dash printfechotest

I sistemi Unix hanno sempre incluso eseguibili separati per i comandi in quella seconda classe. Questi eseguibili separati sono ancora disponibili su tutti i sistemi Unixy che ho usato, anche se sono anche integrati in ogni shell che probabilmente utilizzerai. ( POSIX richiede effettivamente la presenza di questi eseguibili.)

Credo che sia echostato integrato nella shell in AT&T Unix System V Release 3.1. Baso questo sul confronto di due diverse edizioni di manuali per sistemi Unix serie AT & Ts 3B1 . Qualcuno ha gentilmente scannerizzato le edizioni del 1986 di questi manuali e li ha messi online ; questi corrispondono alla versione originale di SVR3. Puoi vedere che echonon è nell'elenco a pagina 523 del Manuale dell'utente di UNIX System V, Volume II , dove ti aspetteresti se il comando fosse incorporato nella shell. Nella mia copia cartacea locale dei manuali SVR3.1 del 1987, echo è elencato in questa sezione del manuale.

Sono abbastanza sicuro che questa non sia un'innovazione Berkeley CSRG che AT&T ha riportato a casa. 4.3BSD è uscito lo stesso anno di SVR3, 1986, ma se si guarda la manpage sh.1 di 4.3BSD , si vede che echonon si trova nell'elenco dei comandi integrati nella sezione "Comandi speciali". Se CSRG ha fatto questo, questo ci lascia desiderare una fonte documentata per dimostrarlo.

A questo punto, potresti echochiederti se è stato incorporato nella shell prima di SVR3.1 e che questo fatto semplicemente non è stato documentato fino ad allora. Il più recente codice sorgente Unix AT&T pre-SVR3 disponibile per me è nel tarball PDP-11 System III , dove troverai il codice sorgente della shell Bourne. Non troverai echonella tabella dei comandi incorporata, che è in /usr/src/cmd/sh/msg.c. Basato sui timestamp in quel file, ciò dimostra che echocertamente non era nella shell nel 1980.


banalità

La stessa directory contiene anche un file chiamato builtin.cche non contiene nulla di preciso per questa domanda, ma troviamo questo interessante commento:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      

Nella pagina 385 della messaggistica unificata SysV, Vol II che hai citato, c'è il printcomando incorporato per ksh che si dice si comporti come echo. Questo comando è presente in qualcosa come AT&T Unix SVR4 2.1 i386 anche da ISC. print "\012"produce lo stesso risultato che farebbe eco. Ti chiedi perché ksh avesse la stampa e non l'eco integrato? Comunque davvero interessante.

Quante gemme di alcuni anni fa sono state portate via in attesa di essere portate alla luce da una modifica nel 2016? +1
iruvar

+1. Grazie. Potresti fornire le fonti (riferimenti) allo scopo di creare un comando incorporato, per la mia lettura / apprendimento (sistematica)?
Tim

Voglio trovare qualche riferimento, manuale o standard per leggere o imparare sistematicamente. Ho provato a cercarlo nel manuale di riferimento di bash e nelle specifiche POSIX. Ma non riesco a trovarlo. Non sono sicuro se mi mancano.
Tim

@Tim: come spiegano questa e altre risposte, alcuni comandi devono essere integrati nella shell o non possono fare il loro lavoro. Tutti gli altri sono puramente opzionali . Questo è essenzialmente ciò che il mio frammento di origine della shell Bourne dice sopra, in effetti. Dal momento che la creazione di tali comandi nella shell è facoltativa, una logica autorevole potrebbe dare solo l'opinione di un implementatore.
Warren Young

19

C'è un terzo motivo per cui alcuni comandi devono essere integrati: possono essere usati quando è possibile eseguire comandi esterni.

A volte un sistema diventa così rotto che il lscomando non funziona. In alcuni casi, una echo *volontà funzionerà ancora.

Un altro (più importante!) Esempio è kill: se un sistema esaurisce i PID gratuiti, non è possibile eseguirlo /bin/kill(perché ha bisogno di un PID :-), ma il built-in killfunzionerà.

A proposito, whichè un comando esterno (almeno non è interno in bash), quindi non può elencare i comandi interni. Per esempio:

$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo

Non dimenticare che quasi tutti gli eseguibili esterni si basano su file di libreria. A volte si verificano catastrofi e tali librerie non possono essere caricate (avviso: MAI emettere a ldconfigmeno che non si sappia ESATTAMENTE cosa si sta facendo). Inoltre, cosa succede se fai saltare il tuo / bin, o peggio, la tua partizione / sbin, ma hai ancora una shell caricata?
LawrenceC,

Se esaurisci i PID, può essere difficile scoprire quale PID vuoi uccidere. Non è possibile eseguire un pscomando, quindi è necessario trovare manualmente i PID /proc.
Kasperd,

Anche se su (almeno) CentOS whichè un alias bash che viene eseguito in alias | /usr/bin/which --read-alias ...modo che l'esterno which possa identificare gli alias (ma non è ancora incorporato). Non riesco a decidere se considerare questo brillante o perverso.
dave_thompson_085,

Nel momento in cui il comando ls non funziona più, penso che dovresti montare il drive come slave invece di boot / master e sistemare la struttura del file in quel modo. Non sono sicuro di come risolvere l'entità della corruzione del sistema con echo a meno che tu non sia echo> in un file e che richiederebbe molto tempo per la correzione. Concesso che potresti scrivere uno script bash che doveva riparare la struttura del sistema.
jonnyjandles il

13

Secondo il Manuale di riferimento di Bash , si tratta di convenienza.

Le shell forniscono anche un piccolo set di comandi integrati (incorporati) che implementano funzionalità impossibili o scomode da ottenere tramite utility separate. Ad esempio, cd, break, continue ed exec) non possono essere implementati al di fuori della shell perché manipolano direttamente la shell stessa. La cronologia, getopts, kill o built-in pwd, tra gli altri, potrebbero essere implementati in utility separate, ma sono più convenienti da usare come comandi integrati. Tutti i builtin della shell sono descritti nelle sezioni successive.

La Guida agli script avanzati di Bash ha una spiegazione più dettagliata:

"Un builtin è un comando contenuto nel set di strumenti di Bash, letteralmente incorporato. Questo è per motivi di prestazioni - i builtin vengono eseguiti più velocemente dei comandi esterni, che di solito richiedono il fork 1 di un processo separato - o perché un particolare builtin ha bisogno di diretto accesso agli interni della shell ".

Si noti inoltre che echoesiste come utility autonoma su alcuni sistemi. Ecco cosa ho sul mio sistema Darwin (MacOSX 10.5.8 - Leopard)

$ uname -a
Darwin host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echoè anche disponibile come built-in, ma a quanto pare i miei script usano / bin / echo sul mio Mac e usano un Bash incorporato sulla maggior parte dei miei sistemi Linux e FreeBSD. Ma questo non sembra importare, perché gli script funzionano ancora bene ovunque.


3
A proposito di built-in della shell, dovresti usare "type" anziché "which".
Teddy,

Grazie @Teddy. Ho iniziato a farlo, quando ricordo. La vita è molto meglio grazie a type.
Stefan Lasiewski,

6

Per completare la risposta di bhm, supponiamo che sia /binstata accidentalmente rimossa dalla tua PATH. Vorresti essere in grado di echo $PATHscoprirlo, giusto?


2

Sebbene la maggior parte delle shell includa un built-in al echogiorno d' oggi, GNU CoreUtils include anche un'implementazione autonoma di esso:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

Sembra che tu non abbia GNU Coreutils installato (la maggior parte dei sistemi operativi desktop e server basati su Linux lo hanno installato per impostazione predefinita, ma incorporando Linux o altri UNIX potrebbe invece utilizzare raccolte alternative di utilità di shell).

A proposito: se guardi Busybox , lo vedrai ls, pse ci catsono anche comandi integrati lì (o almeno possono essere; è usato per i sistemi incorporati e tutto ciò che non è necessario può essere lasciato fuori).


3
I test del poster originale non supportano l'ipotesi che /bin/echonon esiste. Mostrano solo che il builtin ha la precedenza su qualsiasi echoprogramma nel PERCORSO.
Warren Young,

1

Ecco il vero motivo per cui echodovrebbe essere incorporato un shell:

Supponiamo di avere una password in $PASSWORD. Come lo scrivi in ​​un file ./password? Naturalmente la maggior parte dei programmatori scriverebbe:

echo "$PASSWORD" >./password

Tuttavia, se echonon fosse un built-in della shell, la password perderebbe a tutti gli utenti attraverso le psinformazioni.

Ovviamente, se vuoi essere intelligente, puoi trovare un modo per archiviare una password senza echo, forse sfruttando qualche altra funzionalità della shell:

cat >./password <<EOF
${PASSWORD}
EOF

Tuttavia, avere echocome incorporato è una cintura di sicurezza importante poiché dovrebbe funzionare anche il modo più ovvio per salvare una password in un file.


3
Mentre un utile effetto collaterale trovo fortemente dubbio che questa sia la ragione.
lavaggio:

@DepressedDaniel: che cosa ti sostiene? Dov'è il riferimento che hai usato per supportare la tua risposta?
burlone
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.