Как выполнить группу команд в качестве другого пользователя в Bash?
Уже есть некоторые существующие вопросы, которые заданы здесь о запуске команд в качестве другого пользователя. Однако вопрос и ответы сосредоточены на одной команде вместо длинной группы команд.
Например, рассмотрим следующий script:
#!/bin/bash
set -e
root_command -p param1 # run as root
# these commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'
Здесь есть несколько важных моментов:
-
Заключительные три команды должны запускаться как другой пользователь с помощью su
или sudo
. В примере было три команды, но предположим, что их было еще много...
-
В самих командах используются одиночные и двойные кавычки.
Второй пункт выше не позволяет использовать следующий синтаксис:
su somebody -c "command"
... поскольку сами команды содержат кавычки.
Каков правильный способ "группировать" команды и запускать их под другой учетной записью пользователя?
Ответы
Ответ 1
Попробуйте следующее:
su somebody <<'EOF'
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'
EOF
<<
вводит здесь-doc. Следующий токен - это разделитель, и все до строки, начинающейся с разделителя, подается в качестве стандартного ввода команды. Помещение разделителя в одинарные кавычки предотвращает замену переменных внутри этого документа.
Ответ 2
Я не настолько хорош с bash -foo, поэтому существует более элегантный способ, но я уже сталкивался с этой проблемой в прошлом, используя несколько сценариев и "драйвер"
например.
Driver
#!/bin/bash
set -e
su root script1
su somebody script2
script1
#!/bin/bash
set -e
root_command -p param1 # run as root
Скрипт2
#!/bin/bash
set -e
# these commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'
Ответ 3
#!/usr/bin/env bash
TOKEN_USER_X=TOKEN_USER_X
USER_X=peter # other user!
SCRIPT_PATH=$(readlink -f "$BASH_SOURCE")
if [[ "[email protected]" != "$TOKEN_USER_X" ]]; then
###### RUN THIS PART AS the user who started the script
echo "This script is $SCRIPT_PATH"
echo -n "Current user: "
echo $USER
read -p "insert: "
echo "got $REPLY"
su - $USER_X -c "$SCRIPT_PATH $TOKEN_USER_X" # execute code below after else (marked #TOKEN_USER_X)
else
#TOKEN_USER_X -- come here only if script received one parameter TOKEN_USER_X
###### RUN THIS PART AS USER peter
echo
echo "Now this script is $SCRIPT_PATH"
echo -n "Current user: "
echo $USER
read -p "insert: "
echo "got $REPLY"
exit 0
fi
echo
echo "Back to initial user..."
echo -n "Current user: "
echo $USER