Покажу сразу очень наглядный пример:
# echo --version--version# /usr/bin/echo --versionecho (GNU coreutils) 9.1В первом случае ключ не сработал, а во втором сработал, хотя запускал вроде бы одно и то же. А на самом деле нет. В первом примере я запустил echo из состава оболочки bash, а во втором случае - это бинарник в файловой системе. Это по факту разные программы. У них даже ключи разные.
Узнать, что конкретно мы запускаем, проще всего через type:
# type echoecho is a shell builtin# type /usr/bin/echo/usr/bin/echo is /usr/bin/echoВ первом случае прямо указано, что echo - встроена в оболочку.
И ещё один очень характерный пример:
# type lsls is aliased to `ls --color=auto'Очень часто ls это не утилита ls, а алиас с дополнительными параметрами.
Когда вы вводите команду в терминал, происходит следующее:
1️⃣ Проверяются алиасы. Если команда будет там найдена, то поиск остановится и она исполнится.
2️⃣ Далее команда проверяется, встроена в ли она в оболочку, или нет. Если встроена, то выполнится именно она.
3️⃣ Только теперь идёт поиск бинарника в директориях, определённых в
$PATH.У последнего варианта тоже есть свои нюансы. У вас может быть несколько исполняемых файлов в разных директориях с одинаковым именем. Ситуация нередкая. Можно столкнуться при наличии разных версий python или php в системе. Поиск бинарника ведётся по порядку следования этих директорий в переменной слева направо.
# echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binЧто раньше будет найдено в директориях, определённых в этой строке, то и будет исполнено.
И ещё важный нюанс по этой теме. Есть привычные команды из оболочки, которых нет в бинарниках. Например, cd.
# type cdcd is a shell builtin# which cdВ выводе последней команды пусто, то есть бинарника
cd нет. Если вы будете использовать cd в скриптах, то проблем у вас не будет, так как там обычно в шебанге указан интерпретатор. Обычно это bash или sh, и там cd присутствует.А вот если вы cd используете в юните systemd, то ничего не заработает:
ExecStart=cd /var/www/ ....... && .........Вот так работать не будет. Systemd не будет запускать автоматом оболочку. Надо это явно указать:
ExecStart=/usr/bin/bash -с "cd /var/www/ ......."То есть либо явно указывайте bash, либо запускайте скрипт, где bash будет прописан в шебанге.
❗️В связи с этим могу дать совет, который вам сэкономит кучу времени на отладке. Всегда и везде в скриптах, в кронах, в юнитах systemd и т.д. пишите полные пути до бинарников. Команда, в зависимости от пользователя, прав доступа и многих других условий, может быть запущена в разных оболочках и окружениях. Чтобы не было неожиданностей, пишите явно, что вы хотите запустить.
#bash #terminal
