GMT 脚本进阶(三):脚本的分享与扩展

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 上一篇文章中我们介绍了如何使用 getopts 来获取 GMT 脚本执行时需要的命令行参数。通过使用 getopts 我们已经基本实现了 GMT 绘图过程的对象化,即给一个网格文件画一张图这样的基本操作。这样的工作流程的确很方便,但是它也有它不方便的地方。 其一是你不太可能在编写脚本之初就考虑到以后在使用过程中的所有需求,所以你可能还是需要经常为你的脚本添加和修改命令选项。这当然很好,你的脚本会越来越强大。但是过多的命令选项会让脚本的使用变得越来越困难,其他人可能需要花很多时间来学习它。而且,有的需求其实是一次性的,这时候去修改脚本显然并不划算。另一个不足之处是分享你的脚本将变得困难。设想这样一个情景,你想分享你的数据和对应的绘图脚本给你的同事,你发现你面对的并不是简单地将文件夹打包一下的情况。你需要将你的模版脚本拷贝到文件夹打包发送,然后告诉你的同事怎么使用这个脚本绘图,或者另写一个说明。这无疑增加了整个分享过程的复杂度。要是你的同事想将压缩包分享给第三人,那情况就更复杂了。 看到这里你可能会想“赶紧来点干的啊!”。 干的来了。 本篇教程我们就是要来解决分享与扩展性的问题,即如何将脚本特例化。什么意思?为了应对分享与扩展性这两个问题,我们的解决思路是在需要的时候为特定的数据(集)自动生成对应的绘图脚本。这个脚本内只包含 GMT 绘图命令,所以可以在任何装有 GMT 的电脑上运行。你的同事面对的只是单纯的 GMT 脚本,因此不需要额外学习任何其他知识。同时,你自己可以使用生成的脚本进行二次编辑,从而满足额外的绘图需求。这样就大大提高了模版脚本的扩展性。 说了这么多,到底怎么弄? 答:写一个 Shell 函数,接收一个规则字符串和一个命令字符串,视规则执行或者打印命令字符串。就是说每当我们要执行一条 GMT 绘图命令时都要经过这个函数。如果我们想要绘图,这个时候就执行这个绘图命令;如果我们想要得到的是命令本身,就打印这条命令。 有了这个思路,我们来直接看这个函数: # 执行输入的语句或者将其显示在屏幕上 参数1(0显示 1执行)参数2(命令语句)参数3(命令语句) RunOrEcho() { # 预处理 去除命令语句中的制表符 first_str=`echo ${2// /''}` # 判断第三个参数是否存在 if [[ x${3} != x ]]; then sec_str=`echo ${3// /''}` fi # 如果第一个参数为1则执行命令语句 否则在屏幕上显示命令语句 if [[ ${1} == 1 ]]; then ${first_str} if [[ x${3} != x ]]; then ${sec_str} fi else if [[ x${3} != x ]]; then printf "%s\n%s\n" "${first_str}" "${sec_str}" else printf "%s\n" "${first_str}" fi fi } 简单地测试一下这个函数: ...

July 22, 2020 · 2 分钟 · 419 字 · 张壹

GMT 脚本进阶(二):怎样用 getopts 拾取命令行参数

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 上一篇文章中我们介绍了一些在 GMT 脚本编写中可能会用到的 Shell 编程基础知识,今天我们将介绍 Linux 中一个很棒的内置命令 getopts。使用它我们可以方便地自定义标签并获取命令行参数。本篇教程将首先通过一个例子介绍 getopts 的使用方法,然后结合之前我们学习的 gmt_shell_functions.sh 脚本编写一个自动化绘制平面图的 Shell 脚本。如果你准备好了,我们就开始吧。 getopts 简短说明 话不多说,先上例子(personal_info.sh,不用着急看脚本,我们会在后面逐步讲解): #!/bin/bash # 这个简单脚本会拾取姓名、年龄与性别三个参数并显示对应的信息。 # 初始化三个变量name age gender为Unknown name="Unknown" age="Unknown" gender="Unknown" # 显示个人信息 参数依次为 name age gender show_info() { if [[ ${2} -ge 18 && ${3} == 'm' ]]; then echo ${1} is a ${2} years ago man. elif [[ ${2} -ge 18 && ${3} == 'f' ]]; then echo ${1} is a ${2} years ago woman. elif [[ ${2} -lt 18 && ${3} == 'm' ]]; then echo ${1} is a ${2} years ago boy. elif [[ ${2} -lt 18 && ${3} == 'f' ]]; then echo ${1} is a ${2} years ago girl. else echo "Alien." fi } # 使用getopts从命令行获取参数 while getopts "hn:a:g:" arg do case $arg in # 拾取到-h选项,显示帮助信息后退出 h) printf "usage: ${0##*/} -n<name> -a<age> -g<gender> [-h]\n" printf "%s\t%s\n" "-n" "Your name" printf "%s\t%s\n" "-a" "Your age." printf "%s\t%s\n" "-g" "Your gender. Enter 'm' for male and 'f' for female." printf "%s\t%s\n" "-h" "Show help information." exit 0;; n) name=$OPTARG;; # 对变量进行赋值,注意后跟双分号结束。 a) age=$OPTARG;; g) gender=$OPTARG;; ?) # 拾取到未知参数,显示帮助信息后退出。 printf "error: unknow argument\nuse -h option to see help information.\n" exit 1;; esac done # 检查参数值并调用函数显示个人信息 if [[ ${name} != "Unknown" && ${age} != "Unknown" && ${gender} != "Unknown" ]]; then show_info ${name} ${age} ${gender} fi 在终端运行此脚本: ...

July 6, 2020 · 4 分钟 · 685 字 · 张壹

GMT 脚本进阶(一):Shell 编程技巧

本系列共 4 篇:(一)Shell 技巧 · (二)怎样 getopts · (三)分享与扩展 · (四)C 语言 API 一般来说,我们在使用 GMT 绘制图件时可能会保留一些老的脚本。在需要时拷贝到工作文件夹中,再做适当修改并使用。这种方式的好处是对于特定数据有定制化的绘图脚本,可以方便的分享给他人。但是这种方式的不足即是脚本编写的工作量大、复用性差。而且随着脚本数量的增多,我们可能很难快速找到适用的老脚本。所以,利用 Shell 可编程属性,将常用的绘图流程标准化、模块化是提高 GMT 使用效率的重要一步,也是我们 GMT 脚本进阶的第一步。 本系列将分步骤介绍如何编写模块化的 GMT 脚本,帮助我们在日常使用中达到在任意文件夹内无需编写专门脚本也可以快速出图、批量化出图的要求。本篇内容为 Shell 编程中的一些基础知识,在我们后续的教程中会用到,大家可以先熟悉一下。 本教程中的脚本均在 Bash Shell 中测试通过。Windows 用户可使用 PowerShell。 使用变量 Shell 中可声明并使用变量,语法如下: # 注意变量名称与值之间用等号连接,不能有空格 name="Joe" age="19" # 使用变量时需添加$符号或使用${}包含,下面的语句将在终端显示Joe is 19 echo ${name} is ${age} # 对变量赋值时不需要添加$符号 age=20 # 下面的语句将在终端显示Joe is 20 echo ${name} is ${age} 为保证变量的正确调用,建议在任何时候都使用 ${ } 的方式。需要说明的是 Shell 中的所有变量都是作为字符串处理的,所以 age="19" 与 age=19 的含义是一样的。我们可以使用双引号或单引号来表示一个字符串,不同的是双引号中可包含变量,而单引号内的所有字符都将按照其原意进行处理。 使用函数 在 Shell 中我们可以将常用方法定义为函数,方便重复使用与管理。语法如下: # function标识可省略 function <func_name>() { <action> # return语句可省略 <return int> } 看一个具体的例子: ...

July 4, 2020 · 1 分钟 · 200 字 · 张壹