带有包含等号的命名参数的Bash脚本

带有包含等号的命名参数的Bash脚本,bash,shell,awk,Bash,Shell,Awk,我正在尝试使用与以下类似的命名参数将一些值传递给bash脚本: ./script.sh --username='myusername' --password='superS3cret!' --domainou="OU=Groups with Space,OU=subou,DC=mydomain,DC=local" 我有以下代码: #!/bin/bash while [ "$1" != "" ]; do PARAM=`echo

我正在尝试使用与以下类似的命名参数将一些值传递给bash脚本:

./script.sh --username='myusername' --password='superS3cret!' --domainou="OU=Groups with Space,OU=subou,DC=mydomain,DC=local"
我有以下代码:

#!/bin/bash

while [ "$1" != "" ]; do
    PARAM=`echo $1 | awk -vFPAT='([^=]*)|("[^"]+")' -vOFS="=" '{print $1}'`
    VALUE=`echo $1 | awk -vFPAT='([^=]*)|("[^"]+")' -vOFS="=" '{print $2}'`
    case $PARAM in
        -u | --username)
            username=$VALUE
            ;;
        -p | --password)
            password=$VALUE
            ;;
        -ou | --domainou)
            domainou=$VALUE
            ;;
        *)
            echo "ERROR: unknown parameter \"$PARAM\""
            exit 1
            ;;
    esac
    shift
done

echo $username
echo "$password"
echo "$domainou"
运行脚本时得到的结果是:

myusername
superS3cret!
OU
现在,前两行是正确的,但显然我不想你。。。 我想:

Awk似乎与报价中的=匹配。尽我所能,解决这个问题的方法是使用

-vFPAT='([^=]*)|("[^"]+")' -vOFS="=" 
但很明显,这是行不通的,所以我只是想知道,是否有任何awk大师可以帮助我理解我的awk声明有什么问题

谢谢
布拉德

你可以这样做:

#/bin/bash
而[$#-gt 0];做
案件“$1”
-u |--username=*)
username=“${1#*=}”
;;
-p |--password=*)
password=“${1#*=}”
;;
-ou |--domainou=*)
domainou=“${1#*=}”
;;
*)
printf“错误:未知选项:$1\n”
出口1
以撒
转移
完成
printf“用户名:$username\n”
printf“密码:$password\n”
printf“domainou:$domainou\n”

< /代码> 解析包含长和短optos的命令行选项,考虑使用GNU代码> GETOPT < /COD>,它支持长选项。虽然可以构建自己的解析器替换,但使用getopt可以提供更健壮的解析:

  • 选项的缩写(例如,接受--user for--username)
  • 检查所需/可选值
  • 错误处理
另见:


下面是对我最有效的方法

@dash-o肯定让我找到了正确的方向,但你提供的脚本打印出了无关的信息:

set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
我认为冒犯的界线是:

set --long 'username:,password:,ou:,domain:' -o 'u:p:' -- "$0" "$@"
下面是完成我需要的代码。我不能把这归功于我。我是从这里偷来的,但如果不是因为dash-o,我永远不会发现这是一个非常感谢你的东西

#!/bin/bash
die() { echo "$*" >&2; exit 2; }  # complain to STDERR and exit with error
needs_arg() { if [ -z "$OPTARG" ]; then die "No arg for --$OPT option"; fi; }

while getopts ab:c:-: OPT; do
  # support long options: https://stackoverflow.com/a/28466267/519360
  if [ "$OPT" = "-" ]; then   # long option: reformulate OPT and OPTARG
    OPT="${OPTARG%%=*}"       # extract long option name
    OPTARG="${OPTARG#$OPT}"   # extract long option argument (may be empty)
    OPTARG="${OPTARG#=}"      # if long option argument, remove assigning `=`
  fi
  case "$OPT" in
    u | username )  needs_arg; username="$OPTARG" ;;
    p | password )  needs_arg; password="$OPTARG" ;;
    o | domainou )  needs_arg; domainou="$OPTARG" ;;
    ??* )          die "Illegal option --$OPT" ;;  # bad long option
    \? )           exit 2 ;;  # bad short option (error reported via getopts)
  esac
done
shift $((OPTIND-1)) # remove parsed options and args from $@ list

echo "$username"
echo "$password"
echo "$domainou"

这里不需要
awk
。您可以使用纯bash用
PARAM=${1%%=*}
value=${1}*=}
替换试图提取参数-值对的两行。Awk不会看到引号,因为它们是shell语法的一部分。试用
echo
(和/或
printf
)可能会澄清shell处理的工作原理。有一个名为
getopt
的工具可以帮助您解析长选项。这是否回答了您的问题?将脚本复制/粘贴到并修复它告诉您的问题。不,您不能。试试
cmd-u bob
set --long 'username:,password:,ou:,domain:' -o 'u:p:' -- "$0" "$@"
#!/bin/bash
die() { echo "$*" >&2; exit 2; }  # complain to STDERR and exit with error
needs_arg() { if [ -z "$OPTARG" ]; then die "No arg for --$OPT option"; fi; }

while getopts ab:c:-: OPT; do
  # support long options: https://stackoverflow.com/a/28466267/519360
  if [ "$OPT" = "-" ]; then   # long option: reformulate OPT and OPTARG
    OPT="${OPTARG%%=*}"       # extract long option name
    OPTARG="${OPTARG#$OPT}"   # extract long option argument (may be empty)
    OPTARG="${OPTARG#=}"      # if long option argument, remove assigning `=`
  fi
  case "$OPT" in
    u | username )  needs_arg; username="$OPTARG" ;;
    p | password )  needs_arg; password="$OPTARG" ;;
    o | domainou )  needs_arg; domainou="$OPTARG" ;;
    ??* )          die "Illegal option --$OPT" ;;  # bad long option
    \? )           exit 2 ;;  # bad short option (error reported via getopts)
  esac
done
shift $((OPTIND-1)) # remove parsed options and args from $@ list

echo "$username"
echo "$password"
echo "$domainou"