Вопрос или проблема
Я читал этот вопрос-ответ, но похоже, что параметр всегда воспринимается как файл.
Я хочу преобразовать команду diff <(ls old) <(ls new)
с использованием замещения процесса из этой ссылки в одну функцию, которая принимает два аргумента, хотя это несколько избыточно.
Я попробовал следующее, что просто заменяет аргументы:
d2c(){
diff <($1) <($2)
}
затем выполнение d2c "objdump -d foo1" "objdump -d foo2"
показывает d2c:1: нет такого файла или каталога: objdump -d foo1
С fifo вышеуказанная проблема остается.
Вопрос: Как я могу передать аргумент как ‘”objdump -d foo1″‘, а затем позволить его выполнить как команду?
Похоже, вы хотите, чтобы $1
и $2
интерпретировались как код оболочки, а не как имя команды для выполнения, поэтому вам нужно:
d2c() {
diff <(eval " $1") <(eval " $2")
}
(обратите внимание на пробел в начале, чтобы избежать проблем с командами, имя которых начинается с -
).
Также убедитесь, что вы используете одиночные кавычки, а не двойные, при передаче этих кодов в d2c
, чтобы исключить риск уязвимостей к внедрению команд.
d2c 'echo "$var1"' 'echo "$var2"; echo "$var3"'
Не
d2c "echo $var1" "echo $var2; echo $var3"
Например.
Ответ или решение
Для решения проблемы, связанной с передачей команд с аргументами, содержащими пробелы, в shell-функции, важно учитывать, как Bash интерпретирует и обрабатывает аргументы. В представленном сценарии вы сталкиваетесь с проблемой, когда переданная строка воспринимается как имя файла, а не как команда, которую необходимо выполнить. Эта задача решается с использованием конструкции eval
, однако есть важные моменты, которые нужно учитывать для обеспечения корректности выполнения и безопасности.
1. Описание проблемы
Вы пытаетесь использовать конструкцию подстановки процессов (Process Substitution) для сравнения выводов двух команд с помощью функции d2c
, так как это делается в Bash. Например, вы хотите сравнить результаты команд objdump -d foo1
и objdump -d foo2
, однако вы сталкиваетесь с ошибкой, утверждающей, что файл или каталог не найден. Это связано с тем, что Bash воспринимает строку с пробелами как одно целое и пытается интерпретировать её как путь к файлу.
2. Решение проблемы
Чтобы переданная строка исполнялась как команда, а не интерпретировалась как файл, необходимо воспользоваться eval
. Это позволяет Bash-у выполнять строку как код. Для этого необходимо создать функцию следующим образом:
d2c() {
diff <(eval " $1") <(eval " $2")
}
Объяснение:
- Использование
eval
:eval
помогает интерпретировать строку как набор команд. Однако важно помнить о рисках безопасности, связанных с использованиемeval
, особенно если входные данные получены из ненадежных источников. - Пробел перед
$1
и$2
: Это используется для предотвращения ситуаций, когда команда может начинаться с тире (-
), что потенциально может привести к неожиданным последствиям при выполнении.
3. Советы по безопасности и практике
-
Избегайте использования двойных кавычек: При передаче команд в функцию
d2c
следует использовать одиночные кавычки, чтобы минимизировать риск выполнения нежелательного кода, который может быть добавлен в аргументы через подстановку переменных. Например:d2c 'echo "$var1"' 'echo "$var2"; echo "$var3"'
Это делает код более устойчивым к атакам типа "инъекция команд".
-
Инжекция команд: Всегда проверяйте и очищайте данные, если используете
eval
, чтобы исключить возможность ввода опасных команд через переменные.
4. Заключение
Решение проблемы с использованием eval
является быстрым и действенным, однако его следует применять с осторожностью из-за потенциальных рисков безопасности. Для более безопасной работы рассмотрите другие альтернативы, такие как использование временных файлов или функций обработки строк, если ваши условия позволяют это сделать.
Это руководство по улучшению использования shell-аргументов в командах Bash поможет вам более эффективно устранять подобные проблемы, сохраняя безопасность вашего скрипта.