比如我要输出一个基因在染色体上的位置信息,可以写如下bash脚本,保存为gene.sh

脚本中保存了基因的位置信息。

#!/bin/bash

START=5000000
END=6000000
SCFID=785
GENE=Cyp6a9

echo The ${GENE} is on Chr${SCFID}:${START}-${END}

然后在命令行执行即可。

chmod 777 gene.sh
./gene.sh
## The Cyp6a9 is on Chr785:5000000-6000000

不过,如果脚本并不是只执行一次,而是很多次。那么每次针对不同的基因,都要进入gene.sh文件,然后针对4个参数进行修改,然后保存文件。很不方便,也不适合批量操作。

这个时候就需要给脚本加上参数了,这样,每次在执行脚本的时候在命令行输入参数即可,不需要再进入脚本文件进行修改。

  1. 位置参数

通过在命令行的位置,来表示传入对应脚本的参数。这是最简单的一种,如下我们将4个参数对应STARTENDSCFID和 GENE进行传入参数。

#!/bin/bash

START=${1}
END=${2}
SCFID=${3}
GENE=${4}

echo The ${GENE} is on Chr${SCFID}:${START}-${END}

这时在执行的时候,只需在命令行输入对应参数即可,参数之间使用空格分割

./gene.sh 5000000 6000000 785 Cyp6a9
## The Cyp6a9 is on Chr785:5000000-6000000

这种方法虽然简单,但是输入参数的时候必须严格对应,不能空缺参数,不能颠倒位置,这对脚本的新用户是十分不友好的。

  1. 参数名匹配

另一种传递参数的方式就是使用关键词,通过关键词匹配进行参数传递,这种情况下的参数传入方式就比较灵活了,不依赖于参数位置。

#!/bin/bash
usage() {
 echo "Usage: ${0} [-s|--start] [-e|--end] [-i|--scfid] [-g|--gene]" 1>&2
 exit 1
}
while [[ $# -gt 0 ]];do
 key=${1}
 case ${key} in
   -s|--start)
     START=${2}
     shift 2
     ;;
   -e|--end)
     END=${2}
     shift 2
     ;;
   -i|--scfid)
     SCFID=${2}
     shift 2
     ;;
   -g|--gene)
     GENE=${2}
     shift 2
     ;;
   *)
     usage
     shift
     ;;
 esac
done
   
echo The ${GENE} is on Chr${SCFID}:${START}-${END}

这时在命令行,可以不按照顺序输入参数,也可以使用双横线和全称的方式输入:

./gene.sh -s 5000000 -e 6000000  -i 785 -g Cyp6a2
./gene.sh -e 6000000  -i 785 -g Cyp6a2 -s 5000000
./gene.sh  -e 6000000  -i 785 --gene Cyp6a2 -s 5000000
# .....

当然,如果命令参数没有找到匹配,会提示错误:

./gene.sh dsafda
## Usage: ./gene.sh [-s|--start] [-e|--end] [-i|--scfid] [-g|--gene]

这种参数传入的方式有两个关键,一个是使用case语句,另一个是使用了shiftshift的作用主要是移动位置参数。每执行一次都讲第一个位置参数向右移动一次。当然,如果是shift n就是每执行一次,向右移动n个位置。参考:

 https://www.computerhope.com/unix/bash/shift.htm

有时候我们常使用等号=来进行参数传递

./gene.sh -s=5000000 -e=6000000  -i=785 -g=Cyp6a2

整体做法和使用上述空格是一样的。


此外,还可以使用getopts函数,但是感觉有点复杂。可以参考:

https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash

【欢迎转发分享,转载请注明出处】


参考资料:

https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash

https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash

https://www.computerhope.com/unix/bash/shift.htm

bash脚本中的参数传递_JAVA