【linux编程】生信编程-shell脚本编程-脚本格式

shell编程

shell定义

Shell 脚本是一个包含一连串 shell 命令语句的文本文件,通常以 .sh 为扩展名,可被当作一个独立的程序来执行,从而实现数据的批量处理。其通常由 shell header (shebang) 和 body (命令语句) 两部分组成。

Shell header

#!/bin/bash
set -e
set -u

!/bin/bash → shebang,表示执行该脚本所用的解释器。整个脚本必须以这行开始,且必须放在脚本的开头。

set -e (可选) → 如果任何语句的执行结果不是true则退出脚本 (遇到错误立即终止脚本) ,从而可以及时地修改脚本而大大地提高工作效率。

如果使用 set +e 则表示遇到错误报错但继续执行后续脚本。

set -u (可选) → 如果使用未定义的变量则报错并退出脚本。

Body

代码的主体部分描述 “需要做什么,如何去做”。例如定义变量,列出一系列需要执行的命令等,shell 会按照我们所写的顺序依次执行各个命令。当然,我们可以用#来做注释,来增加复杂代码的可读性。

echo "Hello world!" #此处为注释,不会显示在输出结果中
echo "This is my first shell script!"
path=$HOME
echo "List the content of the path $path"
echo "Contents:"
ls -l $path

如何执行 shell 脚本

直接用 sh 或 bash 命令执行脚本,如:

$ bash MyFirstShellScript.sh
$ sh ./MyFirstShellScript.sh 
$ sh /path/to/script/MyFirstShellScript.sh

赋予脚本可执行权限,直接执行脚本,如:

$ chmod u+x MyFirstShellScript 
$ chmod 755 MyFirstShellScript 
$ ./MyFirstShellScript
$ /path/to/script/MyFirstShellScript.sh

Shell 变量

shell 变量定义

Shell 变量可以存储一定的信息 (输入文件,参数的值,输入文件目录,输出结果目录和),从而在后续的命令中对这些信息进行处理。Shell 变量的值实际上都是字符串(没有定义的变量默认是一个空字符串。Shell 变量可以不需要任何声明而直接定义,变量名由字母、数字和下划线组成,大小写敏感;并且定义变量时等号两边不能有空格,否则会被认为是命令。在变量名前加 $ 来获取变量的值。

shell 变量种类

  • 系统变量:由操作系统创建,如:$PATH, $HOME, $BASH 等。
  • 自定义变量:由用户创建:如上例中的 $path。
$ echo $HOME
/root
$ echo $BASH
/bin/bash
$ path=$HOME
$ echo $path
/root

命令替换

使用$() 或 `` 来实现命令替换,即执行一个 shell 命令然后把输出结果存到一个变量中。使用方式:var=$(command) 或 var=command

$ echo "Today is $(date "+%Y-%m-%d")"
Today is 2017-04-16
$ path=$HOME
$ command_output=`ls $HOME`
$ echo $command_output
Desktop Documents Downloads Music MyFirstShellScript.sh Pictures Public Videos

${} 的高级应用:取路径、文件名、后缀、字符串和替换

规律

#是从左面开始匹配
%是从右面开始匹配

使用一个符号 (# 或 %) 是最小匹配
使用两个符号 (## 或 %%) 是最大匹配

* 用来去掉不需要的字符
可以自己指定分割符号与 #, % 和 * 配合来决定取哪部分来替换

可以自己指定起始位置来决定提取哪部分字符串
可以使用 /str1/str2 来替换特定字符串
$ var=/home/username/data/test.txt.bac
$ echo ${var}
/home/username/data/test.txt.bac

$ echo ${var#*/}
#去掉第一个 / 及其左边的字符串
home/username/data/test.txt.bac

$ echo ${var##*/}
#去掉最后一个 / 及其左边的字符串
test.txt.bac

$ echo ${var%/*}
#去掉最后一个 / 及其右边的字符串
/home/username/data

$ echo ${var%%/*}
#去掉第一个 / 及其右边的字符串 (输出结果为空)

$ echo ${var#*.} 
#去掉第一个 . 及其左边的字符串
txt.bac

$ echo ${var##*.} 
#去掉最后一个 . 及其左边的字符串
bac

$ echo ${var%.*} 
#去掉最后一个 . 及其右边的字符串
/home/username/data/test.txt

$ echo ${var%%.*} 
#去掉第一个 . 及其右边的字符串
/home/username/data/test

$ echo ${var:0:5} 
#取第0位后的5个字节
/home

$ echo ${var:5:9} 
#取第5位后的9个字节
/username

$ echo ${var/username/cat} 
#将 username 替换为 cat
/home/cat/data/test.txt.bac

$ echo ${#var} 
#取变量的长度

引用

引用是指用引用符号将字符串引起来,以防其中的特殊字符被 shell 解释为其它含义。我们可以通过引用来控制‘命令替换’或把含有空格 (或其它特殊字符) 的字符串做为一个整体进行参数传递。

Shell 中三种常见的引用形式:

' ' (单引号) 所有字符保持原义但字符串中不能出现单引号本身 (全引用)

z 除 $, ` 和 \ 以外的所有字符保持原义 (部分引用)

\ (反斜线) 转义字符,使接下来的一个字符保持原义

单引号和双引号的区别:

在引用内容为纯文本时,二者没有本质差别。

如果想要获取变量的值时,则需要使用双引号。

$ test="world"

$ echo "Hello $test"
Hello World

$ echo 'Hello $test'
Hello $test

转义

在某些情况下,我们需要保留特殊字符的原义,这时就需要用 \ 来转义。举个例子:

$ var="Hello world"
$ echo "The content of variable '\$var' is \"$var\""
The content of variable '$var' is "Hello world"

Shell 脚本中的参数传递

Shell 脚本可以从命令行获取参数,这些参数被存入变量 $1, $2, $3 ... 中,这些变量被称为特殊变量。

特殊变量 含义
$# 从命令行传递给脚本的参数个数
$0 当前执行脚本的名字
$n 从命令行传递给脚本的参数,从左到右被存入变量:$1, $2, $3 ... $9
$* 从命令行传递给脚本的所有参数
$@ 从命令行传递给脚本的所有参数
$$ 当前 shell 进程的 PID
$? 上一个执行命令的返回值

#!/bin/bash
set -e
set -u
echo "number of arguments: $#"
echo "script name is: $0"
echo "first argument is: $1"
echo "second argument is: $2"
echo "all arguments are: $*"
echo "all arguments are: $@"
echo "process number of the current process is: $$"
echo "exit value of the last command executed: $?"

执行脚本
sh test.sh hello world

显示结果

number of arguments: 2
script name is: test.sh
first argument is: hello
second argument is: world
all arguments are: hello world
all arguments are: hello world
process number of the current process is: 106836
exit value of the last command executed: 0

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,622评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,716评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,746评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,991评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,706评论 6 413
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,036评论 1 329
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,029评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,203评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,725评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,451评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,677评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,161评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,857评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,266评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,606评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,407评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,643评论 2 380

推荐阅读更多精彩内容

  • 概述 首先,咱们来了解一下,什么是Shell。操作系统内核给我们提供了各种接口,同时也提供了各种用户层的库,理论上...
    keysaim阅读 1,404评论 0 0
  • 这是我第一次尝试使用双拼输入法翻译一篇日本的Liunx基础教材上的一章。共花费一周左右。 shell的使用 前言 ...
    今後次阅读 1,060评论 0 4
  • 一、shell脚本介绍 1.1 开头(环境使用shebang机制) #!/bin/bash 必须写在文件首行 符号...
    优果馥斯阅读 3,324评论 0 1
  • 一、什么是Shell脚本 示例 看个例子吧: 示例解释 第1行:指定脚本解释器,这里是用/bin/sh做解释器的 ...
    Rick617阅读 797评论 0 1
  • 10.11号!今天是女儿升入初中的第一次月考。 昨天数学老师都班级里做了个模拟,女儿满分,连附加题都做对了。班主任...
    欣寳dx阅读 380评论 0 0