解析 shell 脚本的参数,记录。
不是简单的传参数进去的那种,那个用$1
接就行了= =
是-f config.json
这种
抄作业 👇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| for i in "$@"; do case $i in -b=*|--batch_size=*) sh_batch_size="${i#*=}" shift ;; -s=*|--data_file=*) sh_data_file="${i#*=}" shift ;; -e=*|--epoch=*) sh_epoch="${i#*=}" shift ;; -d=*|--data_dir=*) sh_data_dir="${i#*=}" shift ;; -r=*|--res_model_dir=*) sh_res_model_dir="${i#*=}" shift ;; -p=*|--pretrained_model_dir=*) sh_pretrained_model_dir="${i#*=}" shift ;; *) ;; esac done
echo "batch_size = ${sh_batch_size}" echo "data_dir = ${sh_data_dir}" echo "data_file = ${sh_data_file}" echo "epoch = ${sh_epoch}" echo "output_dir = ${sh_res_model_dir}" echo "pretrained_model_dir = ${sh_pretrained_model_dir}"
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ➜ ~ otest [2021/12/11 21:43:20] batch_size = data_dir = data_file = epoch = output_dir = pretrained_model_dir = ➜ ~ otest -b=64 -s=data_file.txt -e=80 -d=/data -r=/output -p=pre-model/p.tar batch_size = 64 data_dir = /data data_file = data_file.txt epoch = 80 output_dir = /output pretrained_model_dir = pre-model/p.tar
|
为什么
- 虽然各自语言都有 flag 包的实现,但是 shell 脚本作为入口可定制性最高,可以做些预处理和后处理。
- 有些平台是固定参数的,需要包一层做参数转义,shell 无疑是最方便的。
- 学一下总是没坏处的。
$@
1 2 3 4 5 6 7
| echo '$0:' "$0" echo '$1:' "$1" echo '$#:' "$#" echo '$*:' "$*" echo '$@:' "$@" echo '$$:' "$$"
|
1 2 3 4 5 6 7 8 9
| ➜ ~ otest 1 2 [2021/12/11 21:24:05] $0: /Users/onns/Onns/code/bash/otest $1: 1 $#: 2 $*: 1 2 $@: 1 2 $$: 83125 ➜ ~ echo $? [2021/12/11 21:24:29] 0
|
shell 里的一些特殊变量:
$0
文件名(看起来是绝对路径)
$#
参数个数,不包括本身
$$
进程 id
$?
获取上一个程序的返回值,或者上一个函数的 return 值
当$*
和$@
不被双引号包围时,没有区别。
被包裹时:
1 2 3 4 5 6 7 8
| for i in "$@"; do echo $i done
for i in "$*"; do echo $i done
|
1 2 3 4
| ➜ ~ otest 1 2 [2021/12/11 21:24:31] 1 2 1 2
|
所以$@
可以拿到所有参数。
case
;;
相当于 break
string)
相当于 case 的某一个条件,说是string
其实不标准,应该叫pattern
,这里用了*
代表全匹配,用了|
代表或,其实就是参数的简称和全称,全称可读性高,但是简称方便。
shift n
可以将n
个参数丢弃,n 省略则为1
。
1 2 3 4 5 6
| echo '$#:' "$#" echo '$*:' "$*" shift 3 echo '$#:' "$#" echo '$*:' "$*"
|
1 2 3 4 5
| ➜ ~ otest 1 2 3 4 5 [2021/12/11 21:43:28] $#: 5 $*: 1 2 3 4 5 $#: 2 $*: 4 5
|
shift
作用就是在解析完参数之后丢弃。
${i#*=}
作用:只取${i}变量=
右边的东西。
详细可以参考:https://onns.xyz/blog/2021/05/02/the-linux-command-line-note-27/
1 2 3 4 5 6 7 8 9 10 11 12 13
| i="abacbbbdag" echo "i: ${i}" echo "i: ${i#*a}" echo "i: ${i##*a}" echo "i: ${i#*b}" echo "i: ${i##*b}" echo "-----------" echo "i: ${i}" echo "i: ${i%a*}" echo "i: ${i%%a*}" echo "i: ${i%b*}" echo "i: ${i%%b*}"
|
1 2 3 4 5 6 7 8 9 10 11 12
| ➜ ~ otest 1 2 3 4 5 [2021/12/11 22:09:04] i: abacbbbdag i: bacbbbdag i: g i: acbbbdag i: dag ----------- i: abacbbbdag i: abacbbbd i: i: abacbb i: a
|
结尾
因为平台是通过=
传参的,所以写了这种方式,另一种方式同理的,或者看下参考链接里第二个的实现。
参考文档
22:14:07 done