Shell脚本无法在MacOS上读取getopts参数

时间:2018-04-04 10:31:02

标签: bash macos shell

我编写了一个脚本,根据命令行中使用的开关执行任务。这是我的脚本: 预计git分支名称和两个可选开关

-r用于重置数据库

-t用于合并训练数据

test.sh

merge_training=false
reset_database=false

while getopts ":tr" opt; do
  case ${opt} in
    t ) # process option t
       echo "one"
       $merge_training=true
       ;;
    r ) # process option r
       echo "two"
       $reset_database=true
       ;;
   esac
done

echo $reset_database
echo $merge_training

当我使用命令运行此脚本时:

sh test.sh branchname -r -t

它不打印一个两个,并打印最后一个语句:

false
false

这里有什么问题?

3 个答案:

答案 0 :(得分:2)

你的作业有什么问题。您应该收到2条错误消息:

false=true: command not found

提示:永远不要在作业的左侧放置$

惯例是将选项放在第一个,然后是额外的参数,所以你的命令行应该是:

bash test.sh -r -t branchname

使用bash而不是shsh是一个POSIX shell,大致是bash的一个子集(很复杂)。不要混淆两者。

merge_training=false
reset_database=false

while getopts ":tr" opt; do
  case ${opt} in
    t ) # process option t
       echo "one"
       merge_training=true     #  <<<<<<<<<<<<<<<
       ;;
    r ) # process option r
       echo "two"
       reset_database=true     #  <<<<<<<<<<<<<<<
       ;;
   esac
done

shift $(( OPTIND-1 ))
extra="$1"

echo $reset_database
echo $merge_training
echo $extra        

答案 1 :(得分:2)

当您将branchname作为参数删除时,它可以正常工作( - 但您还必须从$删除$merge_training=true,否则您会尝试false=true。 。)

所以你可以做的是将$1 param保存在变量中并简单地移位。

这里是代码:

#!/bin/bash

merge_training=false
reset_database=false
branchname="$1"
shift
while getopts ":tr" opt; do
  case $opt in
    t ) # process option t
       echo "one"
       merge_training=true
       ;;
    r ) # process option r
       echo "two"
       reset_database=true
       ;;
   esac
done

echo $branchname
echo $reset_database
echo $merge_training

答案 2 :(得分:2)

您可以在脚本上增强的一些要点,

  1. 变量作业不需要左侧的$
  2. 命令行参数在处理实际branchname之前会看到额外的参数OPTSTRING,您需要在进入{{1}之前排除第一个参数呼叫。
  3. 始终将shell解释器设置为要运行脚本的shell解释器。在getopts()执行bash
  4. 除非您有充分的理由不这样做,否则请始终引用您的shell变量。
  5. 如果您将参数作为#!/usr/bin/env bash

    传递,则更新的脚本应如下所示
    bash test.sh branchname -r -t