Bash: выполнить команду с кавычками, используя функцию - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть общая функция c, которая выполняет данную команду, печатает ее вывод на консоль и возвращает результат команды одновременно:

# Command execution
# Executes a given command, redirect stdout to stderr, prints output and returns exit code
# Function arguments:
#   - $1: the command to be executed
cmd_exec() {
    cmd=$1

    exec 5>&2
    echo "Executing command '$cmd' ..."
    output=`"${cmd[@]}" 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]}`
    status=$?
    echo "Command exited with status code: $status"
    echo

    echo "$output"

    echo
    return $status
}

backup_cmd=(sudo -u postgres sh -c '/usr/bin/pg_dump -U postgres -Fc database > /path/to/file')

cmd_exec $backup_cmd
status=$?
if [ "$status" -ne "0" ]; then
    echo "Error during backup!"
fi

Когда я выполняю команду, я вижу, что выполняется только команда sudo, и это потому, что я получаю вывод справки sudo:

Executing command 'sudo' ...
Command exited with status code: 1

usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user]
            [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-T timeout] [-u user] file ...

Примечание: Я написал cmd_exec generi c функция, потому что мне нужно отправить вывод команды как stdout, так и stderr, потому что я хочу, чтобы ее вывод печатался на консоли во время выполнения, не дожидаясь завершения до окончания sh.

1 Ответ

0 голосов
/ 25 февраля 2020

Когда вы присваиваете этот массив:

backup_cmd=(sudo -u postgres sh -c '/usr/bin/pg_dump -U postgres -Fc database > /path/to/file')

Вы не хотите, чтобы это передавалось вашей функции:

cmd_exec $backup_cmd

В этом случае будет передан только первый элемент массива, т.е. sudo.

Вы должны передать элементы массива как двойные кавычки:

cmd_exec "${backup_cmd[@]}"

Нет необходимости сохранять параметры в локальной переменной cmd в вашей функции, вы можете использовать параметры функции как $@ вместо:

# Command execution
# Executes a given command, redirect stdout to stderr, prints output and returns exit code
# Function arguments:
#   - $@: the command to be executed along with its arguments
cmd_exec() {
    exec 5>&2
    echo "Executing command '$cmd' ..."
    output=`"$@" 2>&1 |tee /dev/fd/5; exit ${PIPESTATUS[0]}`
    status=$?
    echo "Command exited with status code: $status"
    echo

    echo "$output"

    echo
    return $status
}

Обратите внимание, что переменные будут не можно развернуть в одинарных кавычках. Другими словами, если вы хотите установить необязательные аргументы, например, так:

backup_cmd=(sudo -u postgres sh -c '$pgdump -U $username -Fc $database > $filename')

Вместо них необходимо использовать двойные кавычки:

backup_cmd=(sudo -u postgres sh -c "$pgdump -U $username -Fc $database > $filename")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...