Передача команды в качестве bash аргумента
bash — это обычная программка, такая же, как и любая другая, поэтому вы можете запускать ее по имени в командной строке.
По умолчанию bash запускает интерактивную оболочку для ввода и выполнения команд.
Кроме того, можно передать команду в bash в виде строки с помощью параметра "
-c".
Тогда bash запустит эту строку как команду, а после выполнения завершит работу:
$ bash -c "ls -l"
-rw-r--r-- 1 smith smith 325 Jul 3 17:44 animals.txt
Почему это бывает полезно?
Потому что новый процесс будет дочерним со своим собственным окружением, включая текущий каталог, переменные и их значения.
Любые изменения в дочерней оболочке не повлияют на текущую:
$ pwd
/home/smith
$ touch /tmp/badfile
$ bash -c "cd /tmp && rm badfile"
$ pwd
/home/smith
Пример выше запускает доп. оболочку только для того, чтобы поменяет каталог на
tmp и удалить файл, а затем завершает работу.
Однако наиболее показательно и полезно использование "
bash -c" вместе с
sudo и
перенаправлением ввода/вывода. Тогда-то эта фича является ключом к успеху.
Предположим, вы хотите создать файл журнала в системном каталоге "
/var/log", недоступном для записи обычным пользователям.
Вы добавляете
sudo, чтобы получить привилегии и создать файл журнала, но команда загадочным образом не исполняется:
$ sudo echo "New log file" > /var/log/custom.log
bash: /var/log/custom.log: Permission denied
Минуту, команда
sudo должна дать разрешение на создание любого файла в любом месте. Как что-то может пойти не так?
Почему sudo даже не запрашивает пароль?
Ответ: потому что sudo вообще не запускалась.
Вы применили
sudo к команде
echo, но не к перенаправлению вывода, которое запустилось первым и провалилось.
Опишем процесс пошагово:
1) вы нажали клавишу Enter;
2) оболочка начала вычислять всю команду, включая перенаправление;
3) оболочка попыталась создать файл
custom.log в защищенном каталоге "
/var/log";
У нас не было разрешения на запись в "
/var/log", поэтому оболочка сообщила, что в доступе отказано (Permission denied).
Чтобы решить эту проблему, нужно сообщить оболочке:
«Выполни всю команду, включая перенаправление вывода, от имени суперпользователя».
Это именно та ситуация, которую так хорошо решает "
bash -c".
Создайте команду, которую вы хотите запустить, в виде строки и передайте ее в качестве аргумента для "
sudo bash -c":
$ sudo bash -c 'echo "New log file" > /var/log/custom.log'
[sudo] password for smith: xxxxxxxx
$ cat /var/log/custom.log
New log file
На этот раз мы запустили от имени суперпользователя
bash, а не просто
echo.
По итогу,
bash выполнит всю строку как команду. Перенаправление проходит успешно.
Помните о "
bash -c", когда
sudo сочетается с
перенаправлением.
LinuxCamp