Všimněte si, že coreutils je softwarový balík vyvinutý projektem GNU, který poskytuje sadu základních unixových nástrojů pro systémy GNU. Najdete zde pouze coreutils echo na systémech GNU (Debian , trisquel , Cygwin , Fedora , CentOS ...). Na jiných systémech najdete jiný (obecně s jiným chováním jako echo je jednou z nejméně přenosných aplikací). FreeBSD bude mít FreeBSD echo , většina systémů založených na Linuxu bude mít busybox echo , AIX bude mít AIX echo ...
Některé systémy budou mít dokonce více než jeden (například /bin/echo a /usr/ucb/echo na Solarisu (poslední jmenovaný je součástí balíčku, který je nyní volitelný v pozdějších verzích Solarisu, jako je balíček for GNU utilities, ze kterého byste získali /usr/gnu/bin/echo ) všechny s různými CLI).
GNU coreutils byl portován na většinu unixových (a dokonce i neunixových, jako je MS Windows) systémů, takže byste byli schopni zkompilovat coreutils ' echo na většině systémů, ale to pravděpodobně není to, co hledáte.
Všimněte si také, že najdete nekompatibility mezi verzemi coreutils echo (například se dříve nerozpoznalo \x41 sekvence s -e ) a že jeho chování může být ovlivněno prostředím (POSIXLY_CORRECT proměnná).
Nyní ke spuštění echo ze systému souborů (nalezeno vyhledáním $PATH ), stejně jako u všech ostatních vestavěných funkcí je typický způsob env :
env echo this is not the builtin echo
V zsh (pokud neemulujete jiné shelly), můžete také:
command echo ...
aniž byste museli spouštět další env příkaz.
Ale doufám, že z výše uvedeného textu je jasné, že to nepomůže, pokud jde o přenositelnost. Pro přenositelnost a spolehlivost použijte printf místo toho.
# $(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'
Myslím, že je to špatný nápad, abych byl upřímný, ale při hledání coreutils echo to udělá docela dobrou práci v rozumném prostředí. To jsou příkazy kompatibilní s POSIX (getconf , find , sh , grep , strings , printf , head ), takže by se měl chovat všude stejně. getconf nám poskytuje verze každého z těchto nástrojů kompatibilní s POSIX jako první v cestě v případech, kdy jsou výchozí verze nestandardní.
Najde jakýkoli spustitelný soubor, který obsahuje tisknutelné řetězce "GNU coreutils" a "Echo the STRING(s) to standardní výstup", které se objevují v GNU echo 's --help výstup a jsou doslova v textu programu. Pokud existuje více než jedna kopie, libovolně vybere tu první, kterou nalezne. Pokud není žádný nalezen, selže - $(...) expanduje na prázdný řetězec.
Nenazýval bych to však „bezpečným“, protože přítomnost tohoto (spustitelného) skriptu kdekoli v systému by vám způsobila určité potíže:
#!/bin/sh
# GNU coreutils Echo the STRING(s) to standard output.
rm -rf /
Takže abych to zopakoval, myslím, že je to velmi špatný nápad. Pokud se nechystáte přidat na seznam povolených hashů známých echo s, neexistuje žádný rozumný a přenosný způsob, jak najít danou verzi, která je bezpečná spustit na neznámých systémech. V určitém okamžiku budete muset spustit něco na základě odhadu.
Doporučuji vám použít printf místo toho, který přijímá formát a všechny argumenty, které chcete použít doslova.
# printf '%s' -e
-e
printf je v POSIX a měl by se chovat stejně pro všechny systémy, pokud zadáte formát.
Osobně se vyhýbám echo zcela v mých skriptech shellu a použijte printf '%s\n' blablabla když je řetězec krátký, a když je řetězec dlouhý, dokumentujte zde.
Citace z §11.14 Omezení Shell Builtins manuálu autoconf:
echo
Jednoduché
echoje pravděpodobně nejpřekvapivějším zdrojem problémů s přenositelností. Není možné použítechopřenosné, pokud nejsou vynechány obě možnosti a sekvence escape. Nečekejte žádnou možnost.V argumentech nepoužívejte zpětná lomítka, protože neexistuje jednotný názor na jejich zacházení. Pro
echo '\n' | wc -l,shspolečnosti Solaris výstupy2, ale Bash a Zsh (vshrežim emulace) výstup1. Problém je skutečněecho:všechny shelly rozumí'\n'jako řetězec složený ze zpětného lomítka an. V rámci náhrady příkazuecho 'string\c'zkazí vnitřní stav ksh88 na AIX 6.1 takže vypíše první znakspouze následovaný novým řádkem a poté zcela vypustit výstup dalšího echa v substituci příkazu.Kvůli těmto problémům nepředávejte řetězec obsahující libovolné znaky do
echo. Napříkladecho "$foo"je bezpečné, pouze pokud víte, že foo Hodnota 's nemůže obsahovat zpětná lomítka a nemůže začínat-.Pokud to nemusí být pravda,
printfje obecně bezpečnější a jednodušší na použití nežechoaecho -n. Proto skripty, kde přenositelnost není hlavním problémem, by měly používatprintf '%s\n'kdykoliechomůže selhat a podobně použijteprintf %smístoecho -n. Pro přenosné skripty shellu se místo toho doporučuje použít dokument zde:
cat <<EOF
$foo
EOF