如何编辑脚本,以便变量值将包含在撇号中而不需要用户添加撇号?

时间:2018-02-19 11:32:35

标签: linux bash shell variables

我写了以下bash脚本:

#!/bin/bash

TIMEOUT="5"
SESSIONS="8"

function usage {
    echo "Usage: $(basename $0) -l servers.list -c COMMAND"
    echo ""
    echo "Options:"
    echo "   -l               :     Provide list containing hostnames/ips"
    echo "   -c               :     Command to run"
    echo "   -u [optional]    :     Run commands remotely as supplied user"
    echo "   -r [optional]    :     Connect to remote machine as root, run commands as supplied user"
    echo ""
    echo " **** \"-u\" is mandatory if \"-r\" is used ****"
    echo ""
}

while getopts ":l:c:u:r:" opt; do
    case $opt in
        l)
            LIST=$OPTARG
        ;;
        c)
            COMMANDS="$OPTARG"
        ;;
        u)
            USER=$OPTARG
            USERSWITCH="-l $USER"
        ;;
        r)
            RUSER=$OPTARG
            RUSERSWITCH="-l root"
            RUSERCMD="su - $USER -c '$COMMANDS'"
        ;;
        *)
            usage
            exit 1
        ;;
    esac
done

if [[ -z $LIST ]] || [[ -z $COMMANDS ]]; then
    echo "Error - not enough arguments have been supplied"
fi

if [[ -z $USER ]]; then
    /usr/bin/pssh -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
    echo "user not supplied"
elif [[ ! -z $USER ]] && [[ ! -z $RUSER ]]; then
    echo "connecting as root running as user"
    /usr/bin/pssh $RUSERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$RUSERCMD"
elif [[ ! -z $USER ]] && [[ -z $RUSER ]]; then
    echo "Connecting as supplied user"
    /usr/bin/pssh $USERSWITCH -i -p $SESSIONS -t 100000000 -x "-oStrictHostKeyChecking=no" -O ConnectTimeout=$TIMEOUT -h $LIST "$COMMANDS"
fi

它基本上包含了命令" parallel-ssh"并允许我的工作场所需要的更多功能,例如提供列表或以特定用户身份运行命令。

该脚本完美无缺。

我唯一的问题是在" -c"之后提供的命令。 switch - 必须放在里面("")或者命令中的空格会使变量只获得命令中的第一个单词。

如何编辑脚本以便能够获得-c之后的任何内容,即使没有放入("")?

2 个答案:

答案 0 :(得分:3)

你可以这样做(感谢@JohnKugelman提供了有用的提示):

c)
    shift "$((OPTIND-2))"
    cmd=$(printf "%q " "$@")
    break
  • OPTIND:要处理的下一个参数的索引
  • $((OPTIND-2))-c选项
  • 之前的参数数量
  • shift "$((OPTIND-2))":将所有内容移至-c选项
  • printf "%q " "$@":打印剩余的参数($@ - 只有命令,因为其他一切都被移走了)
  • %qhelp printf -> quote the argument in a way that can be reused as shell input

答案 1 :(得分:0)

我不太确定你为什么要面对这个问题但是使用变量${COMMANDS}总是一个很好的做法,因为它保持所有变量不变。

由于您在-c之后使用变量,因此应使用RUSERCMD="su - $USER -c '${COMMANDS}'"