Как выполнить группу команд в качестве другого пользователя в 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