获取 运行 脚本的强制选项

getopts for mandatory options for running the script

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

 #!/usr/bin/env bash
    usage() { echo "Usage: [=11=] -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 = 

case 语句中不需要“-”,所以 -f 应该是 f -r r 等。

这里有很多问题:

  • getopts 只做单字母选项,并且会将 -hrp 视为 -h -r -p 的 shorthand(就像 ls -lals -l -a 的缩写)。长选项有半标准格式(以双破折号开头,例如 ls --color),但 getopts 不支持此格式。

  • getopts 将选项变量(在本例中为 opt)设置为选项 not,包括 - ,所以你的案例应该看起来像f) 而不是 -f).

  • 不要在 getopts 循环中间使用 shiftgetopts 跟踪它在参数列表中的位置,如果参数列表在处理它时发生移动……事情会变得非常混乱。相反,在循环后使用 shift $((OPTIND-1)) 来删除所有已处理的选项。

  • 您实际上并没有捕获选项值。也就是说,在解析 -f sample_R1.fastq 时,getopts 会将 OPTARG 设置为 "sample_R1.fastq" 但您忽略它并仅将 f 设置为字符串 "true".

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

这是我对更正版本的看法:

#!/usr/bin/env bash
    usage() { echo "Usage: [=10=] -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}"

请注意,如果您想在某些选项被省略时给出错误消息,则需要检查所有这些变量是否已设置。像 if [ -z "$f" ] || [ -z "$r" ] ||...