Вопрос или проблема
Какой хороший способ выполнения shell-скрипта от имени другого пользователя. Я использую Debian etch, и я знаю, от чьего имени я хочу действовать.
Если бы я делал это вручную, я бы сделал:
su postgres
./backup_db.sh /tmp/test
exit
Поскольку я хочу автоматизировать процесс, мне нужен способ запустить backup_db.sh от имени postgres (унаследовав среду и т.д.)
Спасибо!
Чтобы запустить ваш скрипт от имени другого пользователя одной командой, выполните:
/bin/su -c "/path/to/backup_db.sh /tmp/test" - postgres
Расшифровка:
/bin/su : смена пользователя
-c "/path/to..." : команда для выполнения
- : опция для su, делает сессию входа (подключает профиль пользователя)
postgres : пользователь, от которого нужно выполнить
Я рекомендую всегда использовать полные пути в таких скриптах – нельзя всегда гарантировать, что вы будете в правильном каталоге при использовании su (может быть, кто-то сменил домашний каталог, кто знает). Я также всегда использую полный путь к su (/bin/su), потому что я параноик. Возможно, кто-то может изменить ваш путь и заставить использовать скомпрометированную версию su.
Если цель запуска от пользователя, у которого определен shell nologin, то можно использовать опцию -s для указания shell:
/bin/su -s /bin/bash -c '/path/to/your/script' testuser
Смотрите на следующий вопрос:
запустить скрипт от пользователя, у которого определен shell nologin
Чтобы автоматизировать это по расписанию, можно добавить это в crontab пользователя. Задания cron не получают полную среду, хотя, но было бы лучше добавить все переменные окружения, которые вам нужны, прямо в сам скрипт.
Чтобы отредактировать crontab пользователя:
sudo crontab -u postgres -e
Это должно быть полезным чтением — setuid в shell-скриптах
Если вы запускаете su с аргументом “- имя_пользователя
“, это создаст shell входа для пользователя, чтобы дать ту же среду, что и у пользователя. Обычно используется для быстрого выполнения вашего скрипта в домашней среде из другого логина.
Попробуйте посмотреть руководство su:
su -c script_run_as_postgres.sh – postgres
В качестве альтернативы, можно использовать sudo, чтобы разрешить вам выполнять только эту команду от имени postgres без пароля. Это требует некоторой настройки в вашем /etc/sudoers.
Метод “su -c …”, предложенный другими, хорош. Для автоматизации вы можете добавить скрипт в crontab пользователя, от имени которого его нужно выполнить.
Если у пользователя уже есть доступ к sudo и вы не знаете пароль суперпользователя, то можно попытаться следующее: Это перезапустит postgres, инициализированный в /data/my-db/pgsql/9.6/data
sudo su - postgres -c "/usr/pgsql-9.6/bin/pg_ctl -D /data/my-db/pgsql/9.6/data -l /var/log/pgsql.log restart"
Вы также можете использовать:
sudo -u postgres script_run_as_postgres.sh
Для сайтов, где может быть сложная конфигурация PAM, которая затрудняет это, можно обойтись без использования su/sudo с помощью systemd
и немного большего количества написанного текста:
- Определите сервис типа
oneshot
, который выполняет ваш скрипт. Если ваш скрипт содержит всего несколько команд, вы можете использовать один или несколькоExecStart
с командами вместо выполнения внешнего файла, содержащего эти же команды.
/home/myuser2/myscript.service
[Unit]
Description=My Script
[Service]
Type=oneshot
User=myuser2
ExecStart=/full/path/to/my/script.sh
[Install]
WantedBy=multi-user.target
- Определите правило Polkit, которое позволит другому непривилегированному пользователю запускать этот сервис
/etc/polkit-1/rules.d/my-script.rules
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.user == "myuser1") {
if (action.lookup("unit") == "myscript.service") {
var verb = action.lookup("verb");
if (verb == "start" || verb == "stop" || verb == "restart") {
return polkit.Result.YES;
}
}
}
});
- Активируйте сервис:
systemctl enable /home/myuser2/myscript.service
Теперь myuser1
может выполнить systemctl start myscript.service
, который попросит systemd выполнить скрипт (от имени myuser2
). Сервис можно отлаживать как обычно с помощью systemctl status
и journalctl
.
Ответ или решение
Чтобы запустить shell-скрипт от имени другого пользователя на Debian etch, важно учитывать ряд аспектов для обеспечения корректного выполнения задачи. Давайте развернем пошаговую инструкцию для автоматизации этого процесса, применяя стандартные инструменты линукс-систем, такие как su
, sudo
, cron
и systemd
.
Решение с использованием su
Для запуска скрипта от имени другого пользователя, можно использовать команду /bin/su
. Это обеспечивает выполнение команды с учетом окружения пользователя:
/bin/su -c "/путь/к/backup_db.sh /tmp/test" - postgres
Разбор команды:
/bin/su
: Переключение пользователя.-c "/путь/к/..."
: Команда, которую необходимо выполнить.-
: Запуск сессии как login shell, что необходимо для загрузки пользовательского окружения.postgres
: Имя пользователя, от которого выполняется команда.
Использование sudo
Если у вас настроен sudo
, это может быть более гибким решением. Подразумевается, что необходимые разрешения установлены в файле /etc/sudoers
:
sudo -u postgres /путь/к/backup_db.sh /tmp/test
Автоматизация с cron
Чтобы запланировать выполнение на регулярной основе, можно добавить задачу в crontab
пользователя. Откройте Crontab от имени пользователя postgres
:
sudo crontab -u postgres -e
И добавьте строку, соответствующую вашему графику. Например, для ежедневного выполнения в 3 утра:
0 3 * * * /путь/к/backup_db.sh /tmp/test
Запуск через systemd
Для более безопасного и структурированного подхода вы можете воспользоваться systemd
. Создайте сервис:
# /etc/systemd/system/backup.service
[Unit]
Description=Backup database
[Service]
Type=oneshot
User=postgres
ExecStart=/путь/к/backup_db.sh /tmp/test
[Install]
WantedBy=multi-user.target
Активируйте и запустите сервис:
systemctl enable backup.service
systemctl start backup.service
Заключение
Каждый метод имеет свои преимущества и области применения. Выбор метода зависит от ваших конкретных требований к безопасности, простоте поддержки и частоты выполнения задач. Старайтесь всегда использовать полные пути и внимательно следите за разрешениями для обеспечения безопасности вашего скрипта.