2016-07-08 39 views
1

我正在写一个bash脚本,我想从外部发送一个参数给我的脚本,该脚本以连字符( - )开头,就像这个'-d'一样。连字符( - )在bash脚本参数中是否允许?

不过,我得到以下警告,当我执行我的脚本

目录名称:无效选项 - “d”

我想说的警告,因为我可以看到我的脚本工作,尽管这个的。但我也想摆脱这些警告。任何人都可以帮忙吗?

更多的澄清,我正在执行脚本像这 -

sh script.sh <param1> -d <param2> 

从那里这一论点被用于

case ${2} in 
    -d|--days)  timeUnit="d";; 
    -h|--hours)  timeUnit="h";; 
+1

如果您发布了一些代码,某些输入和某些预期输出,则更容易看到发生了什么。 – Kusalananda

+1

换句话说[mcve] - :)@Kusalananda –

+0

我已更新该帖子。现在好吗? – Vishal

回答

2

脚本这不是一个警告附加代码片段,它是一个错误。

如果你想传递一个破折号dirname然后开始一个文件名,你有两个选择:根据您的调用行

dirname -- -d 

dirname ./-d 

,我们可以推断您必须错误地将脚本的参数列表中的-d参数中继给参数列表,该参数列表是从内部调用的dirname调用你的脚本。

你可能做这样的事情你的脚本中:

​​

也许

dirname "$2" 

其中任何一个将在-d参数传递给dirname

您需要正确解析脚本的参数,并且只将选项值的脚本的-d选项传递给dirname调用。这个过程通常被称为选项处理

这里是你如何能做到的选择处理的例子:

dir=''; 
nonOpt=(); 
for ((i = 1; i <= $#; ++i)); do 
    arg="${@:$i:1}"; 
    if [[ "$arg" == '--' ]]; then 
     nonOpt+=("${@:$i+1}"); 
     break; 
    elif [[ "$arg" == -?* ]]; then 
     case "${arg:1}" in 
      (d|dir) 
       if [[ $i -eq $# ]]; then printf 'error: trailing -d option.\n' >&2; exit 1; fi; 
       let ++i; 
       dir="${@:$i:1}"; 
       ;; 
      (h|help) 
       printf 'script.sh [-h|--help] {param1} -d|--dir {dir}\n' >&2; 
       exit 1; 
       ;; 
      (*) 
       printf "error: invalid option: $arg.\\n" >&2; 
       exit 1; 
       ;; 
     esac; 
    else 
     nonOpt+=("$arg"); 
    fi; 
done; 
if [[ ${#nonOpt[@]} -ne 1 ]]; then printf 'error: require 1 non-option argument.\n' >&2; exit 1; fi; 
param1="${nonOpt[0]}"; 
if [[ "$dir" == '' ]]; then printf 'error: missing {dir}.\n' >&2; exit 1; fi; 

dirname -- "$dir"; 
+0

不,它不是文件名。文件名是有效的,所以我试图执行这样的脚本“sh script.sh -d ”@bgoldst – Vishal

+1

是的,它是一个文件名。 'dirname'实用程序将文件名称作为参数。如果它不是文件名,那么你不应该使用'dirname'工具。 – bgoldst

0

连字符被允许在shell脚本参数。

警告/错误是因为您将该参数传递给另一个不知道-d选项的命令。

您应该look into using getopts解析命令行参数。

0

问题是你用里面的参数做什么。请注意,大多数程序将以连字符开头的参数作为选项处理,所以在通过实际参数之前正确结束选项--并不重要。

在你的情况下,假设你通过$1dirname,它应该看起来像:

dir=`dirname -- "$1"` 

或者,如果它被认为是实物期权的外壳,那么你必须先消费,并删除, shift将做的工作:

while [ $# -ne 0 ]; do 
    case "$1" in 
     -d) 
      myoptionD=true 
      shift 
      ;; 
     -*) 
      echo "Unknown option: $1" >&2 
      exit 2 
      ;; 
     *) 
      break 
      ;; 
    esac 
done 

...或者你可以使用getopt对于这一点。