Shell教程

0.参考链接

[1].sh文件
[2]Linux–Shell基础
[3]SHELL脚本–expr命令全解
[4]pidof
[5]linux killall 、kill 、pkill 命令详解
[6]Shell编程基础

1.什么是.sh文件

  被称为脚本Bash的应用程序和使用开发人员文件。 SH文件被称为是创建并保存在Bash的语言,因为它包含的说明都写在该语言。 SH文件可以,如果文本命令shell的命令行界面中键入执行。 SH文件大多是用于程序开发人员,这些文件都是Bash的应用程序非常重要,因为该应用程序主要使用脚本以及命令将被执行,使这个应用程序的工作。而且,由于SH文件是使用这个应用程序编程脚本和它们包含执行程序的命令,他们确实是非常重要的。shell 是用来解决用户如何与操作系统通信的问题。
  Linux 的 核 叫 kernel , 壳有很多种,有命令行的: bash 、sh 、csh 、ksh, 有图形化的:KDE、GNOME、CDE、 XFCE ,据说 Linus 那伙人只负责开发 核。
  Windows 9X 系列的核是 DOS,图形化的壳叫 Windows Explorer ,命令行 壳 叫 command。从 Windows XP 开始,Windows 的 核 叫做 Windows NT (Windows New Technology),图形化壳叫 Windows Explorer ,命令行壳有command 、cmd.exe ,后面还推出了 Windows PowerShell。由于 Windows NT 技术是针对图形化壳设计出来的核,而 Windows 9X 就是在 DOS 上加了一个 壳。所以 Windows XP 蓝屏情况比 Windows 9X 少得多

2.编写规范

1)代码规范:

 # !/bin/bash           文件首行,指定告知系统当前这个脚本要使用的shell解释器

2)文件命名规范:

文件名.sh .sh是Linux下bash shell 的默认后缀

3) 使用流程:

创建.sh文件

touch test.sh

touch/vim 编写shell代码

#!/bin/bash
echo "hello world"

为文件添加执行权限 chmod +x 文件

chmod +x test.sh

执行shell脚本

./test.sh

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

3.编程语法

3.1变量

创建文件
vim test3.sh
编辑
#!/bin/bash
time=`date -d +"%Y %m %d %H:%M%S"`
echo $time
权限
chmod +x test3.sh
执行
./test3.sh

(1)变量的含义
  在一个脚本周期内,其值可以发生改变的量就是变量。其中脚本周期可以简单理解为当前的shell文件。
(2)变量的定义和使用
  定义形如:class_name=“star”
  使用形如:echo $class_name

变量名的规范
注意,变量名后面的等号不能有空格 ;
变量的命名规则如下:

  • 只能使用英文字母,数字和下划线
  • 不能以数字开头
  • 不能使用bash中的关键字(可用help命令查看保留关键字)

关于单双引号的问题
  双引号能够识别变量,双引号能够实现转义(类似于“*”);单引号是不能识别变量,只会原样输出,单引号是不能转义的
  反引号`(Esc下方的那个键),当在脚本中需要执行一些指令并且将执行的结果赋给变量的时候需要使用“反引号”。
(3)只读变量
  语法:readonly 变量名

创建文件
vim test4.sh
编写脚本
#!/bin/bash
a=10
readonly a
a=20
echo $a
权限
chmod +x test4.sh
执行
./test4.sh

(4)接收用户输入(重点)
  语法:read -p 提示信息 变量名

#! /bin/bash
read -p  '请输入需要创建的文件路径:'   filepath
touch  $filepath
echo  '创建文件成功!'
ls  -l  $filepath

  执行文件
在这里插入图片描述
(5)删除变量(了解)
  语法:unset 变量名

#!/bin/bash
b=20
echo $b
unset b
echo $b

3.2运算符

(1)算数运算符
  下表列出了常用的算数运算符,假定变量a为10,变量b为20:

运算符说明举例
+加法expr $a + $b   结果为30
-减法expr $a - $b   结果为-10
*乘法expr $a \* $b  结果为200
/除法expr $b / $a   结果为2
%取余expr $b $a   结果为0
=赋值a=$b   将变量b的值赋给a
==相等,相等返回true[ $a == $b ]   返回false
!=不等,不等返回true[ $a != $b ]   返回true

  注意:条件表达式要放在方括号之间,并且要有空格,例如:[$ a==$b]是错误的,必须写成[ $a == $b ]
(2)关系运算符
  关系运算符只支持数字,不支持字符串,除非字符串的值是数字。下表列出了常用的关系运算符,假定变量a为10,变量b为20。

运算符说明举例
-eq equal检测两个数是否相等,相等返回true[ $a -eq $b ]   返回 false
-ne  not equal检测两个数是否相等,不相等返回true[ $a -ne $b ]   返回true
-gt  great than检测左边的数是否大于右边的,如果是,则返回true[ $a -gt $b ]   返回 false
-lt less than检测左边的数是否大于右边的,如果是,则返回true[ $a -lt $b ]    返回true
-ge great than or equal检测左边的数是否大于等于右边的,如果是,则返回true[ $a -ge $b ]   返回 false
-le  less than or equal检测左边的数是否小于等于右边的,如果是,则返回true[ $a -le $b ]   返回true

  写一个脚本,判断当前输入的用户是否存在,如果存在则提示“用户存在”否则提示“用户不存在”

#!/bin/bash
read -p '请输入所要查询的用户名:' username
count=`cat /etc/passwd | grep $username | wc -l `
if [ $count -gt  0  ]
then
        echo '该用户存在'
else
        echo '该用户不存在'
fi

在这里插入图片描述
(3)逻辑运算符
  下表列出了常用的布尔运算符,假定变量a为10,变量b为20:

运算符说明举例
! 非运算表达式为 真 则返回false,否则返回true[ ! false ]   返回 true
-o  or,或运算有一个表达式为真,则返回true[ $a -lt 20 -o &b -gt 30]   返回 true
-a and,与运算全部表达式为真,才返回true[ $a -lt 20 -o &b -gt 30]   返回false

(4)逻辑运算符
   下表列出了常用的字符串运算符,假定变量a为“abc”,变量b为“efg”

运算符说明举例
=两个字符串是否相等,相等返回true[ $a = $b ]    返回 false
!=两个字符串是否相等,不相等返回true[ $a != $b ]    返回 true
-z检测字符串长度是否为0,为0返回 true[ -z $a ]   返回 false
-n检测字符串长度是否为0,不为0返回 true[ -n $a ]    返回 true
str检测字符串是否为空,不为空返回 true[ $a ]    返回 true

(5)文件测试运算符
   文件测试运算符用于检测 Unix/Linux 文件的各种属性。属性检测描述如下:

运算符说明举例
-b file检测文件是否块设备文件,如果是,则返回true[ -b $file ]    返回 false
-c file检测文件是否是文字设备文件,如果是,则返回true[ -c $file ]    返回 false
-d file检测文件是否是字符设备文件,如果是,则返回true[ -d $file ]    返回 false
-f file检测文件是否是普通文件(既不是目录,也不是设备文件)。如果是,则返回 true[ -f $file ]    返回 true
-q file检测文件是否设置了 SGID 位,如果是,则返回 true[ -q $file ]    返回 false
-k file检测文件是否设置了黏着位(Sticky Bit ),如果是,则返回 true[ -k $file ]    返回 false
-p file检测文件是否有名管道,如果是,则返回 true[ -p $file ]    返回 false
-u file检测文件是否设置了 SUID 位,如果是,则返回 true[ -u $file ]    返回 false
-k file检测文件是否设置了黏着位(Sticky Bit ),如果是,则返回 true[ -k $file ]    返回 false
-r file检测文件是否可读,如果是,则返回 true[ -r $file ]    返回 true
-w file检测文件是否可写,如果是,则返回 true[ -w $file ]    返回 true
-k file检测文件是否设置了黏着位(Sticky Bit ),如果是,则返回 true[ -k $file ]    返回 false
-x file检测文件是否可执行,如果是,则返回 true[ -x $file ]    返回 true
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true[ -s $file]
-e file检测文件(包括目录)是否存在,如果是,则返回true[ -e $file ]    返回 true

3.3控制语句

(1)条件判断语句
多个条件:

if condition1
then
    command1
elif conditon2
then
    command2
else
    commandN
fi

case语句:

if condition1
then
    command1
elif conditon2
then
    command2
else
    commandN
fi

(2)循环语句
for:

for var in list
do
    commands
done

while:

while condition
do
    commands
done

(3) select 循环语句

echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
  break;
done
echo "You have selected $var"

3.4 shell脚本传参

传递:
./test.sh  a  b  c
 
接收:
在脚本中可以用“$1”来表示 a ;$2”来表示 b ,以此类推。

示例:

#!/bin/bash
echo $1 $2 $3

在这里插入图片描述

3.5 函数

  如果你写过比较复杂的脚本,就会发现可能在几个地方使用了相同的代码,这时如果用上函数,会方便很多。函数没有必要声明。只要在执行之前出现定义就行。下面是一个名为xtitlebar的脚本,它可以改变终端窗口的名称。这里使用了一个名为help的函数,该函数在脚本中使用了两次:

#!/bin/bash
help()
{
cat << HELP
xtitlebar -- change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] "string_for_titelbar"
OPTIONS: -h help text
EXAMPLE: xtitlebar "cvs"
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
if [[ $1 == '' || $1 == '-h' ]]; then
  help
fi
# send the escape sequence to change the xterm titelbar:
echo -e "\033]0;$1\007"
#

3.6 脚本调试

  最简单的调试方法当然是使用echo命令。你可以在任何怀疑出错的地方用echo打印变量值,这也是大部分shell程序员花费80%的时间用于调试的原因。Shell脚本的好处在于无需重新编译,而插入一个echo命令也不需要多少时间。shell也有一个真正的调试模式,如果脚本"strangescript"出错,可以使用如下命令进行调试:

sh -x strangescript

  上述命令会执行该脚本,同时显示所有变量的值。
  shell还有一个不执行脚本只检查语法的模式,命令如下:

sh -n your_script

  这个命令会返回所有语法错误。

3.7 pidof命令

  pidof–用于查找一个运行的程序的PID。

  • -s 表示只返回1个 pid
  • -x 表示同时返回运行给定程序的 shell 的 pid
  • -o 表示告诉 piod 表示忽略后面给定的 pid ,可以使用多个 -o 。

3.8killall相关命令

(1)killall
  Linux系统中的killall命令用于杀死指定名字的进程(kill processes by name)。我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀死的进程,我们还需要在之前使用ps等命令再配合grep来查找进程,而killall把这两个过程合二为一,是一个很好用的命令。

killall [参数] [进程名]

  • -Z 只杀死拥有scontext 的进程
  • -e 要求匹配进程名称
  • -I 忽略小写
  • -g 杀死进程组而不是进程
  • -i 交互模式,杀死进程前先询问用户
  • -l 列出所有的已知信号名称
  • -q 不输出警告信息
  • -s 发送指定的信号
  • -v 报告信号是否成功发送
  • -w 等待进程死亡
  • –help 显示帮助信息
  • –version 显示版本显示

(2)KILL
  Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令。通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后台进程就须用kill命令来终止,我们就需要先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程。kill命令是通过向进程发送指定的信号来结束相应进程的。在默认情况下,采用编号为15的TERM信号。TERM信号将终止所有不能捕获该信号的进程。对于那些可以捕获该信号的进程就要用编号为9的kill信号,强行“杀掉”该进程。

kill [参数] [进程id]

  • -l 信号,若果不加信号的编号参数,则使用“-l”参数会列出全部的信号名称
  • -a 当处理当前进程时,不限制命令名和进程号的对应关系
  • -p 指定kill 命令只打印相关进程的进程号,而不发送任何信号
  • -s 指定发送信号
  • -u 指定用户

  kill命令可以带信号号码选项,也可以不带。如果没有信号号码,kill命令就会发出终止信号(15),这个信号可以被进程捕获,使得进程在退出之前可以清理并释放资源。也可以用kill向进程发送特定的信号。例如:

kill -2 123

  它的效果等同于在前台运行PID为123的进程时按下Ctrl+C键。但是,普通用户只能使用不带signal参数的kill命令或最多使用-9信号。
  kill可以带有进程ID号作为参数。当用kill向这些进程发送信号时,必须是这些进程的主人。如果试图撤销一个没有权限撤销的进程或撤销一个不存在的进程,就会得到一个错误信息。
  可以向多个进程发信号或终止它们。
  当kill成功地发送了信号后,shell会在屏幕上显示出进程的终止信息。有时这个信息不会马上显示,只有当按下Enter键使shell的命令提示符再次出现时,才会显示出来。
  应注意,信号使进程强行终止,这常会带来一些副作用,如数据丢失或者终端无法恢复到正常状态。发送信号时必须小心,只有在万不得已时,才用kill信号(9),因为进程不能首先捕获它。要撤销所有的后台作业,可以输入kill 0。因为有些在后台运行的命令会启  动多个进程,跟踪并找到所有要杀掉的进程的PID是件很麻烦的事。这时,使用kill 0来终止所有由当前shell启动的进程,是个有效的方法。

实例1:列出所有信号名称
命令:kill -l
输出:
[root@localhost test6]# kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

说明:
只有第9种信号(SIGKILL)才可以无条件终止进程,其他信号进程都有权利忽略。    下面是常用的信号:
HUP    1    终端断线
INT     2    中断(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \TERM   15    终止
KILL    9    强制终止
CONT   18    继续(与STOP相反, fg/bg命令)
STOP    19    暂停(同 Ctrl + Z)

实例2:得到指定信号的数值

[root@localhost test6]# kill -l KILL
9
[root@localhost test6]# kill -l SIGKILL
9
[root@localhost test6]# kill -l TERM
15
[root@localhost test6]# kill -l SIGTERM
15
[root@localhost test6]#


实例3:先用ps查找进程,然后用kill杀掉

命令:kill 3268
[root@localhost test6]# ps -ef|grep vim 
root      3268  2884  0 16:21 pts/1    00:00:00 vim install.log
root      3370  2822  0 16:21 pts/0    00:00:00 grep vim
[root@localhost test6]# kill 3268 


实例4:彻底杀死进程
命令:kill –9 3268   // -9 强制杀掉进程

  init是Linux系统操作中不可缺少的程序之一。所谓的init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。所以,init始终是第一个进程(其进程编号始终为1)。 其它所有进程都是init进程的子孙。init进程是不可杀的!
(3)PKILL
  pkill 和killall 应用方法差不多,也是直接杀死运行中的程式;如果你想杀掉单个进程,请用kill 来杀掉。

应用方法:#pkill 正在运行的程式名

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值