Shell编程快速入门指南

第一个shell脚本

#!/bin/bash
echo "hello, world"

运行程序可以作为解释器参数或者作为可执行程序

bash test.sh
chmod +x test.sh
test.sh

变量

命名

name="huruji"

需要注意的是变量名与等号之间不能有空格。

使用

echo $name
echo ${name}

使用在变量名前添加$即可,{}表示这个变量名的边界。

只读变量

name="huruji"
readonly name

使用readonly可以将变量定义为只读变量,只读变量不能再次赋值

删除变量

name="huruji"
unset name

使用unset删除变量,之后不能再使用。

字符串

name="huruji"

echo "my name is $name"

字符串可以使用单引号和双引号,单引号中不能包含单引号,即使转义单引号也不次那个,双引号则可以,双引号也可以使用字符串。

拼接

name="huruji"
hello="my name is ${name}"

获取字符串长度

str="huruji"
echo ${#str} #6

提取子字符串

str="huruji"
echo ${str:2:3}

从字符串的第二个字符开始提取3个字符,输出ruj

查找

str="huruji"
echo `expr index "$str" u`

此时输出2,因为此时第一个字符位置从1开始

数组

定义

names=("huruji" "greywind" "xie")
echo ${names[0]}
echo ${names[2]}

读取

echo ${names[2]}
echo ${names[@]}

如上例子,使用@可以获取数组中的所有元素

获取长度

length=${#names[@]}
length=${#names[*]}

Shell参数传递

执行Shell脚本的时候,可以向脚本传递参数,在Shell中获取这些参数的格式为$n,即$1,$2.......,

echo "第一个参数是:$1"
echo "第一个参数是:$2"
echo "第一个参数是:$3"

运行

chmod +x test.sh
test.sh 12 13 14

则此时输出:

第一个参数是:12
第一个参数是:13
第一个参数是:14

此外,还有其他几个特殊字符来处理参数

  • $#:传递脚本的参数个数
  • $*:显示所有的参数
  • $$:脚本当前运行的进程ID号
  • $!:后台运行的最后一个进程的ID号
  • $@:返回所有参数
  • $-:显示Shell的使用的当前选项
  • $?:退出的状态,0表示没有错误,其他则表示有错误

运算

算数运算
原生bash不支持简单的数学运算,可以借助于其他命令来完成,例如awk和expr,其中expr最常用。expr是一款表达式计算工具,使用它能完成表达式的求值操作。

val=`expr 2 + 2`
echo $val

需要注意的是运算符两边需要空格,且使用的是反引号。
算术运算符包括:+ - × / % = == !=

关系运算
关系运算只支持数字,不支持字符串,除非字符串的值是数字。

a=12
b=13
if [ $a -eq $b ]
    then
    echo "相等"
else
    echo "不等"
fi
  • -eq:是否相等
  • -ne:是否不等
  • -gt:大于
  • -lt:小于
  • -ge:大于等于
  • -le:小于等于

布尔运算

  • !:非
  • -o:或
  • -a:与

逻辑运算符

  • &&:逻辑与
  • ||:逻辑或

字符串运算符

  • =:相等 [ $a = $b ]
  • !=:不等 [ $a != $b ]
  • -z:字符串长度是否为0,为0返回true [ -z $a ]
  • -n:字符串长度是否为0,不为0返回true [ -n $a ]
  • str:字符串是否为空,不为空返回true [ $a ]

文件测试运算符
用于检测Unix文件的各种属性。

  • -b:检测文件是否为块设备文件 [ -b $file ]
  • -c:检测文件是否为字符设备文件 [ -c $file ]
  • -d:检测文件是否为目录 [ -d $file ]
  • -f:检测文件是否为普通文件 [ -f $file ]
  • -g:检测文件是否设置了SGID位 [ -g $file ]
  • -k:检测文件是否设置了粘着位 [ -k $file ]
  • -p:检测文件是否是有名管道 [ -p $file ]
  • -u:检测文件是否设置了SUID位 [ -u $file ]
  • -r:检测文件是否可读 [ -r $file ]
  • -w:检测文件是否可写 [ -w $file ]
  • -x:检测文件是否可执行 [ -x $file ]
  • -s:检测文件大小是否大于0 [ -s $file ]
  • -e:检测文件是否存在 [ -e $file ]
file="/home/greywind/Desktop/learnShell/test.sh"

if [ -e $file ]
    then
    echo "文件存在"
else
    echo "文件不存在"
fi

if [ -r $file ]
    then
    echo "可读"
else
    echo "不可读"
fi

if [ -w $file ]
    then
    echo "可写"
else
    echo "不可写"
fi


if [ -x $file ]
    then
    echo "可执行"
else
    echo "不可执行"
fi

if [ -d $file ]
    then
    echo "是目录"
else
    echo "不是目录"
fi

if [ -f $file ]
    then
    echo "是普通文件"
else
    echo "不是普通文件"
fi

echo

echo在显示输出的时候可以省略双引号,使用read命令可以从标准输入中读取一行并赋值给变量

read name
echo your name is $name

换行使用转义\n,不换行使用\c
此外使用 > 可以将echo结果写入指定文件,这个文件不存在会自动创建

echo "it is a test" > "/home/greywind/Desktop/learnShell/hello"

使用反引号可以显示命令执行的结果,如date、history、pwd

echo `pwd`
echo `date`

printf

Shell中的输出命令printf类似于C语言中的printf(),
语法格式:

printf format-string [arguments...]
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 

test

test命令用于检查某个条件是否成立,可以进行数值、字符、文件三方面的测试

a=100
b=200
if test a == b
    then
    echo "相等"
else
    echo "不等"
fi

流程控制

if

a=100
b=200
if test $a -eq $b
    then
    echo "相等"
else
    echo "不等"
fi
a=100
b=200
if test $a -eq $b
    then
    echo "相等"
elif test $a -gt $b
    then
    echo "a大于b"
elif test $a -lt $b
    then
    echo "a小于b"
fi

for

for num in 1 2 3 4
do
    echo ${num}
done
num=10
for((i=1;i<10;i++));
do
    ((num=num+10))
done
echo $num

while

num=1
while [ $num -lt 100 ]
do
    ((num++))
done

echo $num

无限循环

while:
do
      command
done
while true
do
      command
done
for (( ; ; ))

until

until condition
do
      command
done

case

case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

需要注意的是与其他语言不同Shell使用;;表示break,另外没有一个匹配则使用*捕获该值

echo "输入1 2 3任意一个数字"
read num
case $num in
    1)echo "输入了1"
;;
    2)echo "输入了2"
;;
    3)echo "输入了3"
;;
    *)echo "输入的值不是1 2 3"
;;
esac

与其他语言类似,循环可以使用break和continue跳出

函数

函数定义
用户自定义函数可以使用或者不使用function关键字,同时指定了return值则返回这个值,如果没有return语句则以最后一条运行结果作为返回值。

function first(){
    echo "hello world"
}
first(){
    echo "hello world"
}

调用函数直接使用这个函数名即可

first

函数参数
调用函数可以传入参数,函数内部使用$n获取传入的参数,类似于运行程序使用时获取使用的参数,不过需要注意的是两位数以上应该使用{}告诉shell边界例如${12}、${20}

function add(){
    num=0;
    for((i=1;i<=$#;i++));
    do
        num=`expr $i + $num`
    done
    return $num
}
add 1 2 3 4 5
a=$?

echo $a

函数本身是一个命令,所以只能通过$?来获得这个返回值

输入输出重定向

在上文的例子中可以使用 > 可以将echo结果写入指定文件,这就是一种输出重定向,重定向主要有以下:

  • command > file:输出重定向至文件file
  • command < file:输入重定向至文件file
  • command >> file:输出以追加的方式重定向至文件file
  • n > file:将文件描述符为n的文件重定向至文件file
  • n >> file:将文件描述符为 n 的文件以追加的方式重定向到文件file
  • n >& m:将输出文件 m 和 n 合并
  • n <& m:将输入文件 m 和 n 合并
  • << tag:将开始标记 tag 和结束标记 tag 之间的内容作为输入

将whoami命令输出保存到user文件中

who > "./user"

使用cat命令就可以看到内容已经保存了,如果不想覆盖文件的内容那么就使用追加的方式即可。

who >> "./user"

Shell文件包含

Shell脚本可以包含外部脚本,可以很方便的封装一些公用的代码作为一个独立的文件,包含的语法格式如下:

. filename
# 或
source filename

如:
test1.sh

echo "hello world"

test.sh

source ./test1.sh

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

推荐阅读更多精彩内容

  • 基础 头文件 #!/bin/bash 或者#!/bin/sh #!约定的标记,如IOS的Import 执行文件时需...
    ZMJun阅读 1,199评论 1 2
  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,018评论 2 34
  • 一,shell题记 不懂shell的程序员不是好程序员,学习shell是为了自动化,使用自动化可以非常有效的提高工...
    架构师小秘圈阅读 8,667评论 3 70
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 98,515评论 9 468