获取 运行 脚本的强制选项
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 -la
是 ls -l -a
的缩写)。长选项有半标准格式(以双破折号开头,例如 ls --color
),但 getopts
不支持此格式。
getopts
将选项变量(在本例中为 opt
)设置为选项 not,包括 -
,所以你的案例应该看起来像f)
而不是 -f)
.
不要在 getopts
循环中间使用 shift
。 getopts
跟踪它在参数列表中的位置,如果参数列表在处理它时发生移动……事情会变得非常混乱。相反,在循环后使用 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" ] ||
...
我有 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 -la
是ls -l -a
的缩写)。长选项有半标准格式(以双破折号开头,例如ls --color
),但getopts
不支持此格式。getopts
将选项变量(在本例中为opt
)设置为选项 not,包括-
,所以你的案例应该看起来像f)
而不是-f)
.不要在
getopts
循环中间使用shift
。getopts
跟踪它在参数列表中的位置,如果参数列表在处理它时发生移动……事情会变得非常混乱。相反,在循环后使用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" ] ||
...