getopts用于运行脚本的强制选项

时间:2017-07-24 14:46:05

标签: bash getopts

我有8个选项,这些选项是运行脚本所必需的。但是,我无法在第一个参数后传递选项值。能告诉我这里我做错了吗?

 #!/usr/bin/env bash
    usage() { echo "Usage: $0 -f sample_R1.fastq -r sample_R2.fastq -hrp HISAT2_REFERENCE_PATH -g GTF_file -sp KNOWN_SPLICE_FILE -b BOWTIE2_REFERENCE.fasta -rsem_path RSEM_REFERENCE -out_path OUTPUT_PATH -h help" 1>&2; exit 1; }

while getopts ":f:r:hrp:g:s:b:rsem_path:out_path:h" opt; do
    case "${opt}" in
        f) f="$OPTARG"; shift ;; # sample_R1.fastq 
        r) r="$OPTARG"; shift ;; # sample_R2_fastq
        hrp) hrp="$OPTARG"; shift ;;    # HISAT2_REFERENCE_PATH
        g) g="$OPTARG"; shift ;;        # GTF_file
        sp) sp="$OPTARG"; shift ;; # KNOWN_SPLICE_FILE
        b) b="$OPTARG"; shift ;;        # BOWTIE2_REFERENCE
        rsem_path) rsem_path="$OPTARG"; shift ;; #RSEM Reference path
        out_path) out_path="$OPTARG"; shift ;; #Results output path
        h | *) usage ; exit;;
    esac
done

echo "f = ${f}"
echo "r = ${r}"
echo "hrp = ${hrp}"
echo "g = ${g}"
echo "sp = ${sp}"
echo "b = ${b}"
echo "rsem_path = ${rsem_path}"
echo "out_path = ${out_path}"

结果

f = ./test_data/HBR_Rep1_ERCC-Mix2_Build37-ErccTranscripts-chr22.read1.fastq
r = 
hrp = 
g = 
sp = 
b = 
rsem_path = 
out_path = 

2 个答案:

答案 0 :(得分:2)

这里有很多问题:

  • getopts仅提供单字母选项,并会将-hrp视为-h -r -p的简写(就像ls -lals -l -a的缩写})。长选项有一种半标准格式(以双短划线开头,例如ls --color),但getopts不支持此选项。

  • getopts将选项变量(在这种情况下为opt)设置为 not 选项,包括-,因此您的案例应该如下所示例如f)代替-f)

  • 请勿在{{1​​}}循环中间使用shiftgetopts跟踪它在参数列表中的位置,如果参数列表在它处理时被移动......事情变得非常困惑。相反,在循环之后使用getopts来摆脱已经处理的所有选项。

  • 您实际上并未捕获选项值。也就是说,在解析shift $((OPTIND-1))时,-f sample_R1.fastq会将OPTARG设置为“sample_R1.fastq”但您忽略它并将getopts设置为字符串“true”。

  • 最后,您使用“:”启动了选项字符串,告诉f它不应该报告错误,因为您将采用相应的,但您不会。此外,即使没有“:”,如果getopts看到一个不在列表中的选项,它也会运行getopts设置为“?”的循环,所以你应该检查一下并在这种情况下给出使用信息。

以下是我对更正版本的看法:

opt

请注意,如果您想在省略某些选项时给出错误消息,则需要检查是否已设置所有这些变量。像#!/usr/bin/env bash usage() { echo "Usage: $0 -f sample_R1.fastq -r sample_R2.fastq -H HISAT2_REFERENCE_PATH -g GTF_file -s KNOWN_SPLICE_FILE -b BOWTIE2_REFERENCE.fasta -R RSEM_REFERENCE -o OUTPUT_PATH [-h]" 1>&2; exit 1; } while getopts "f:r:H:g:s:b:R:o:h" opt; do case "${opt}" in f) f="$OPTARG" ;; # sample_R1.fastq r) r="$OPTARG" ;; # sample_R2_fastq H) hrp="$OPTARG" ;; # HISAT2_REFERENCE_PATH g) g="$OPTARG" ;; # GTF_file s) sp="$OPTARG" ;; # KNOWN_SPLICE_FILE b) b="$OPTARG" ;; # BOWTIE2_REFERENCE R) rsem_path="$OPTARG" ;; #RSEM Reference path o) out_path="$OPTARG" ;; #Results output path h | [?]) usage ; exit;; esac done shift $((OPTIND-1)) echo "f = ${f}" echo "r = ${r}" echo "hrp = ${hrp}" echo "g = ${g}" echo "sp = ${sp}" echo "b = ${b}" echo "rsem_path = ${rsem_path}" echo "out_path = ${out_path}" ...

这样的东西

答案 1 :(得分:0)

你不需要" - "在case语句中,所以-f应该是f-r r等。