Вопрос или проблема
Таким образом
$(cat /etc/passwd)
это приводит к сообщению “Нет такого файла или директории”
и
"$(whereis cat)"
это приводит к сообщению “команда не найдена”
Почему подстановка команд не работает так, как ожидалось?
Кратко: Возможно, вы используете подстановку команд неправильно.
Хотя вы не предоставляете полного текста ошибки, очень вероятно, что подстановка команд работает именно так, как и задумано.
Подстановка команд означает, что вывод команды помещается в место, где указана подстановка команд. Это значит, что если у вас есть скрипт с строкой
$(cat /etc/passwd)
скрипт попытается выполнить содержимое файла /etc/passwd
, как оно выводится командой cat
, которое состоит из полей, разделенных :
, таких как
root:x:0:0:root:/root:/bin/ash
что, конечно, не является действительной командой.
Аналогично, если у вас есть строка
$(whereis cat)
в вашем скрипте, она попытается выполнить “команду”
cat: /bin/cat /usr/share/man/man1/cat.1.gz
(или подобное, в зависимости от вашего дистрибутива), которая завершится неудачей, потому что на вашей системе нет команды cat:
. Это усугубляется вашим использованием кавычек " ... "
– обычно это правильное решение – что заставляет оболочку считать всю строку (включая пробелы) одним именем команды, которую она пытается выполнить.
Ответ или решение
Почему подстановка команд приводит к ошибке «команда не найдена»?
Подстановка команд – это мощный инструмент, который позволяет выполнять команды в оболочке и использовать их вывод в качестве аргументов для других команд. Однако, неправильно использованная подстановка команд может привести к ошибкам, как в вашем случае. Рассмотрим подробнее, почему возникают ошибки при использовании конструкции $().
Пример 1: $() и /etc/passwd
Когда вы выполняете следующую команду:
$(cat /etc/passwd)
вы на самом деле пытаетесь выполнить команды, которые выводятся командой cat /etc/passwd
. Файл /etc/passwd
содержит информацию о пользователях системы, каждый из которых представлен в определенном формате. Например, содержимое файла может выглядеть так:
root:x:0:0:root:/root:/bin/ash
Когда оболочка пытается выполнить результат команды cat /etc/passwd
, она интерпретирует каждую строку файла как отдельную команду. Это невалидные команды, что и приводит к ошибке. Вы получаете сообщение об ошибке, потому что оболочка не может идентифицировать root:x:0:0:root:/root:/bin/ash
как действительную команду.
Пример 2: $() и whereis cat
Второй пример, который вы привели:
$(whereis cat)
здесь происходит аналогичная ситуация. Команда whereis cat
выводит строки, указывающие местоположение исполняемого файла cat
, возможно, что-то вроде:
cat: /bin/cat /usr/share/man/man1/cat.1.gz
Когда вы используете конструкцию $()
, оболочка снова пытается выполнить вывод этой команды как команду, что также приводит к ошибке, так как cat:
не является корректной командой.
Как правильно использовать подстановку команд?
Чтобы избежать таких ошибок, обратите внимание на следующую рекомендацию:
-
Не пытайтесь выполнить вывод команд напрямую: Если вам нужно работать с выводом команды, лучше перенаправить его в переменную или файл.
Например, вы можете сделать так:
output=$(cat /etc/passwd) echo "$output"
Это перенаправит содержимое файла в переменную
output
, а затем вы можете обрабатывать её по своему усмотрению. -
Использование подстановки для аргументов: Если вам нужно передать вывод команды как аргументы, используйте подходящие команды и убедитесь, что вывод содержит правильные форматы.
-
Избегайте кавычек при выполнении команд: Если вы используете
$()
, кавычки не нужны, так как это уже выполняет команду и возвращает результат.
Заключение
Ваша ситуация с подстановкой команд иллюстрирует важность понимания того, как работает это мощное средство в оболочке. Ошибка «команда не найдена» возникает не из-за некорректного синтаксиса самой подстановки, а из-за неправильного толкования её выводов как команд. Обработка выводов команд, как показано выше, поможет избежать подобных ошибок в будущем.
Эти принципы помогут вам использовать подстановку команд более эффективно и избегать распространенных ошибок в вашей практике работы с оболочкой.