Nota che coreutils è un pacchetto software sviluppato dal progetto GNU per fornire un insieme di utilità di base Unix ai sistemi GNU. Troverai solo coreutils echo pronto all'uso sui sistemi GNU (Debian , trisquel , Cygwin , Fedora , CentOS ...). Su altri sistemi, troverai un diverso (generalmente con un comportamento diverso come echo è una delle applicazioni meno portabili) implementazione. FreeBSD avrà FreeBSD echo , la maggior parte dei sistemi basati su Linux avrà busybox echo , AIX avrà AIX echo ...
Alcuni sistemi ne avranno anche più di uno (come /bin/echo e /usr/ucb/echo su Solaris (quest'ultimo fa parte di un pacchetto che ora è facoltativo nelle versioni successive di Solaris come il pacchetto di utilità per GNU da cui otterresti un /usr/gnu/bin/echo ) tutti con CLI differenti).
GNU coreutils è stato portato sulla maggior parte dei sistemi simili a Unix (e anche non simili a Unix come MS Windows), quindi potresti essere in grado di compilare coreutils ' echo sulla maggior parte dei sistemi, ma probabilmente non è quello che stai cercando.
Nota anche che troverai incompatibilità tra le versioni di coreutils echo (per esempio non riconosceva \x41 sequenze con -e ) e che il suo comportamento può essere influenzato dall'ambiente (POSIXLY_CORRECT variabile).
Ora, per eseguire echo dal file system (trovato da una ricerca di $PATH ), come per ogni altro integrato, il modo tipico è con env :
env echo this is not the builtin echo
In zsh (quando non emuli altre shell), puoi anche fare:
command echo ...
senza dover eseguire un ulteriore env comando.
Ma spero che il testo sopra chiarisca che non aiuterà per quanto riguarda la portabilità. Per portabilità e affidabilità, usa printf invece.
# $(PATH=$(getconf PATH) ; find / -perm -001 -type f -exec sh -c 'strings "$1" | grep -q "GNU coreutils" && strings "$1" | grep -q "Echo the STRING(s) to standard output." && printf "%s" "$1"' sh {} \; | head -n 1) --help
Usage: /bin/echo [SHORT-OPTION]... [STRING]...
or: /bin/echo LONG-OPTION
...
or available locally via: info '(coreutils) echo invocation'
Penso che questa sia una cattiva idea, ad essere onesti, ma questo farà un lavoro abbastanza solido per trovare i coreutils echo in un ambiente ragionevole. Questi sono comandi compatibili con POSIX fino in fondo (getconf , find , sh , grep , strings , printf , head ), quindi dovrebbe comportarsi allo stesso modo ovunque. Il getconf ci fornisce le versioni conformi a POSIX di ciascuno di questi strumenti per prime nel percorso, nei casi in cui le versioni predefinite non sono standard.
Trova qualsiasi eseguibile che contenga entrambe le stringhe stampabili "GNU coreutils" e "Echo the STRING(s) to standard output", che appaiono nel GNU echo è --help output e sono letteralmente nel testo del programma. Se c'è più di una copia, sceglie arbitrariamente la prima che ha trovato. Se non ne trova nessuno, fallisce - il $(...) si espande in una stringa vuota.
Non lo definirei "sicuro", tuttavia, poiché la presenza di questo script (eseguibile) in qualsiasi punto del sistema ti causerebbe alcuni problemi:
#!/bin/sh
# GNU coreutils Echo the STRING(s) to standard output.
rm -rf /
Quindi, per ribadire, penso che questa sia una pessima idea. A meno che tu non inserisca nella whitelist gli hash di echo noti s, non esiste un modo ragionevole e portabile per trovarne una data versione che sia sicura per funzionare su sistemi sconosciuti. Ad un certo punto dovrai eseguire qualcosa sulla base di un'ipotesi.
Ti incoraggio a utilizzare il printf comando invece, che accetta un formato e qualsiasi argomento tu voglia usare letteralmente.
# printf '%s' -e
-e
printf è in POSIX e dovrebbe comportarsi allo stesso modo per tutti i sistemi se fornisci un formato.
Personalmente, evito echo completamente nei miei script di shell e usa printf '%s\n' blablabla quando la stringa è corta e here-document quando la stringa è lunga.
Citando da §11.14 Limitazioni di Shell Builtins del manuale di autoconf:
eco
Il semplice
echoè probabilmente la fonte più sorprendente di problemi di portabilità. Non è possibile utilizzareechoportably a meno che non vengano omesse entrambe le opzioni e le sequenze di escape. Non aspettarti alcuna opzione.Non utilizzare barre rovesciate negli argomenti, in quanto non vi è consenso sulla loro gestione. Per
echo '\n' | wc -l, ilshdi Solaris emette2, ma Bash e Zsh (inshmodalità di emulazione) output1. Il problema è veramenteecho:tutte le shell capiscono'\n'come la stringa composta da una barra rovesciata e da unn. All'interno di una sostituzione di comando,echo 'string\c'rovinerà lo stato interno di ksh88 su AIX 6.1 in modo che stampi il primo caratteressolo, seguito da una nuova riga, quindi elimina completamente l'output dell'eco successivo in una sostituzione di comando.A causa di questi problemi, non passare una stringa contenente caratteri arbitrari a
echo. Ad esempio,echo "$foo"è sicuro solo se conosci quel foo Il valore di non può contenere barre rovesciate e non può iniziare con-.Se questo potrebbe non essere vero,
printfè in generale più sicuro e più facile da usare rispetto aechoeecho -n. Pertanto, gli script in cui la portabilità non è una preoccupazione importante dovrebbero utilizzareprintf '%s\n'ogni voltaechopotrebbe fallire, e allo stesso modo usaprintf %sinvece diecho -n. Per gli script di shell portabili, invece, si suggerisce di utilizzare un here-document come questo:
cat <<EOF
$foo
EOF