简体   繁体   English

Bash:使用函数执行带引号的命令

[英]Bash: execute a command with quotes using a function

I have a generic function which executes a given command, prints its output to the console and returns the command's output in the same time:我有一个通用函数,它执行给定的命令,将其输出打印到控制台并同时返回命令的输出:

# 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

When I execute the command I see that only the command sudo is executed and this is because I'm getting the sudo help output:当我执行命令时,我看到只有命令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 ...

Note: I wrote the cmd_exec generic function because I need to send the output of the command to both stdout and stderr because I want its output to be printed on the console during the execution without waiting the execution to finish.注意:我编写了cmd_exec通用函数,因为我需要将命令的输出发送到 stdout 和 stderr,因为我希望在执行期间将其输出打印在控制台上,而无需等待执行完成。

When you assign this array:当您分配此数组时:

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

You don't want to pass it like that to your function:你不想把它像那样传递给你的函数:

cmd_exec $backup_cmd

In this case, only the first element of the array will be passed, ie sudo .在这种情况下,只会传递数组的第一个元素,即sudo

You should pass the array elements as double-quoted expansion:您应该将数组元素作为双引号扩展传递:

cmd_exec "${backup_cmd[@]}"

There's no need to store parameters to your local variable cmd in your function, you may use the function parameters as $@ instead:无需将参数存储到函数中的局部变量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
}

Please note that variables will not be expanded in single-quoted arguments.请注意,变量不会在单引号参数中展开。 In other words, if you want to set the arguments optional like this:换句话说,如果你想像这样设置可选的参数:

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

You need to use double quotes instead:您需要改用双引号:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM