shell脚本学习(一)

目录

  • 执行行脚本
  • 注释
  • 变量
  • 字符串
  • 数组

打开文本编辑器,新建一个文件,扩展名为sh,创建test.sh文件,并输入代码:

#!/bin/bash
echo "Hello World !"

“#!” 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shellecho命令用于向窗口输出文本。

1、执行脚本

方式一: 保存代码,并cd到目录:

chmod +x ./test.sh  #使脚本具有执行权限
./test.sh  #执行脚本

注意,一定要写成./test.sh,而不是test.sh。运行其它二进制的程序也一样,直接写test.sh,linux系统会去PATH里寻找有没有叫test.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成test.sh是会找不到命令的,要用./test.sh告诉系统说,就在当前目录找。

方式二: cd到目录

/bin/sh test.sh

2、注释

“#”开头的行就是注释,会被解释器忽略,sh里没有多行注释,只能每一行加一个#号。只能像这样:

#!bin/bash
# ----------------------------------------------------------------------
# name:         test.sh
# version:      1.0
# createTime:   2017-03-14
# description:  shell基础
# author:       birdben
# email:        XXXXXXX@163.com
# ----------------------------------------------------------------------

如果非要要用多行注释可以以下两种方式:
1、可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果
2、如下:

echo "我不是单行注释"
# echo "我是单行注释,你看不到我"

echo "我不是多行注释"
:<<COMMENT
echo "我是多行注释1,你看不到我"
echo "我是多行注释2,你看不到我"
COMMENT
echo "我没有看到多行注释1和多行注释2"

执行脚本输出:

我不是单行注释
我不是多行注释
我没有看到多行注释1和多行注释2

可以看到在:<<COMMENTCOMMENT之间的脚本代码没有执行,其实COMMENT可以随意命名,只要别跟中间的注释内容相同即可。当Shell脚本执行遇到:<<COMMENT,就不执行脚本了,一直到再碰到COMMENT后才重新开始执行脚本。如果忘记写COMMENT或者写错(由于已经不执行脚本了,所以即使写错也不会报错),则:<<COMMENT之后的脚步将都不会执行。

3、变量

定义变量:

定义变量时,变量名不加美元符号($),如:

variableName="value"

注意,变量名和等号之间不能有空格

变量举例:

a=100
b="hello world"
echo $a
echo $b

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

str="String"
echo "Hi,$strs"

不会输出Strings,而是输出Hi,,这是因为Shellstrs当成一个变量,而strs未被赋值,其值为空。正确的方法是:

echo “Hi, ${str}s”
变量重新赋值:

已定义的变量,可以被重新定义,如:

str="String"
echo ${str}
str="hello"
echo ${str}
只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变
示例:

str="String"
echo ${str}
readonly str
str="hello"
echo ${str}

输出:

String
test.sh: line 5: str: readonly variable
删除变量

使用 unset 命令可以删除变量
示例:

str="String"
unset str
echo ${str}

上面脚本将不会有任何输出

shell中特殊变量

变量名只能包含数字、字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量。


示例:

echo "执行的文件名:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第三个参数为:$3"
echo "参数个数:$#"
echo "所有参数:$*"
echo "所有参数:$@"
echo "当前Shell进程的ID:$$"

执行脚本:

chmod +x test.sh 
./test.sh java oc c++

输出:

执行的文件名:./test.sh
第一个参数为:java
第二个参数为:oc
第三个参数为:c++
参数个数:3
所有参数:java oc c++
所有参数:java oc c++
当前Shell进程的ID:24348
$*$@ 的区别

$*$@都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@"会将各个参数分开,以"$1" "$2" … "$n"的形式输出所有参数。
下面的例子可以清楚的看到 $* 和 $@ 的区别:

echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \$@"
for var in $@
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"
done

执行:

./test.sh a b c

输出:

print each param from $*
a
b
c
print each param from $@
a
b
c
print each param from "$*"
a b c
print each param from "$@"
a
b
c

4、字符串

字符串可以用单引号,也可以用双引号,也可以不用引号

单引号字符串的限制:
1、单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
2、单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
1、双引号里可以有变量
2、双引号里可以出现转义字符

示例:

#!/bin/sh
str="hello world"
echo '$str'
echo "$str"

输出:

$str
czc, hello world
字符串拼接

示例:

#!/bin/sh
str="hello world"
str2="${str}!"
str3=""$str"!"
echo $str2
echo $str3

输出:

hello world!
hello world!
获取字符串长度

示例:

#!/bin/sh
str="hello world"
echo ${#str}

输出结果11

提取子字符串
#!/bin/sh
str="hello world"
subStr=${str:1:4}
echo $subStr

输出结果

ello
判断是否包含子串

方式一.

#!/bin/sh
strA="hello world"
strB="hello"
result=$(echo $strA | grep "${strB}")
if [[ "$result" != "" ]]
then
echo "包含"
else
echo "不包含"
fi

输出:包含
先打印长字符串,然后在长字符串中 grep 查找要搜索的字符串,用变量result记录结果
如果结果不为空,说明strA包含strB。如果结果为空,说明不包含。
这个方法充分利用了grep 的特性,最为简洁。

方式二:

#!/bin/sh
strA="hello world"
strB="low"
if [[ $strA =~ $strB ]]
then
echo "包含"
else
echo "不包含"
fi

输出:不包含
利用字符串运算符 =~ 直接判断strA是否包含strB

方式三:利用通配符

A="helloworld"
B="low"
if [[ $A == *$B* ]]
then
echo "包含"
else
echo "不包含"
fi

输出:包含
*代表任意字符,可有可无

5、数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小
在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1 ... valuen)
示例:

array=("a" "b" "c")
array2=(
    "a"
    "b"
    "c"
)

还可以单独定义数组的各个分量:

array[0]="d"
array[1]="e"
array[2]="f"

可以不使用连续的下标,而且下标的范围没有限制
读取数组元素值的一般格式是:
${array_name[index]}
示例:

a=${array[0]}

使用@ 或 * 可以获取数组中的所有元素
示例:

${array[@]}
${array[*]}

返回数组所有下标

${!array[@]}

获取数组长度的方法与获取字符串长度的方法相同

# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容