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é
echo
je pravděpodobně nejpřekvapivějším zdrojem problémů s přenositelností. Není možné použítecho
př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
,sh
společnosti Solaris výstupy2
, ale Bash a Zsh (vsh
rež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í znaks
pouze 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,
printf
je obecně bezpečnější a jednodušší na použití nežecho
aecho -n
. Proto skripty, kde přenositelnost není hlavním problémem, by měly používatprintf '%s\n'
kdykoliecho
může selhat a podobně použijteprintf %s
místoecho -n
. Pro přenosné skripty shellu se místo toho doporučuje použít dokument zde:
cat <<EOF
$foo
EOF