linux 环境及 shell 程序

25
Linux 环环环 Shell 环环 环环环 环环 1

Upload: george-foster

Post on 01-Jan-2016

148 views

Category:

Documents


1 download

DESCRIPTION

Linux 环境及 Shell 程序. 操作系统实验 1. 二、 Shell 编程与进程通信. 常用 shell 命令. 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、 > 、 | 目录操作 cd 、 pwd 、 ls mkdir 、 cp 、 mv 、 rm -r 文本过滤 head 、 tail 、 grep 、 sort 、 sed 、 awk 其他 find 、 expr - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Linux 环境及 Shell 程序

Linux 环境及 Shell 程序

操作系统实验 1

Page 2: Linux 环境及 Shell 程序

二、 Shell 编程与进程通信

Page 3: Linux 环境及 Shell 程序

常用 shell 命令 文件及文件属性操作

ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd

输入输出操作 echo 、 cat >> 、 > 、 |

目录操作 cd 、 pwd 、 ls mkdir 、 cp 、 mv 、 rm -r

文本过滤 head 、 tail 、 grep 、 sort 、 sed 、 awk

其他 find 、 expr

获取信息: man

Page 4: Linux 环境及 Shell 程序

Shell 简介 shell 是用户和内核之间的接口。为屏蔽内核复杂性,在内核

周围建一个外壳( shell ),用户向 shell 提出请求, shell将请求传给内核。 Shell 有多种,一般使用bash ( bonurne shell )。

Shell 是一种命令解释器,支持变量、函数、控制语句等,类似于一种高级编程语言。

以 #!/bin/sh 开头,指示所用的命令解释器, # 后接注释

Page 5: Linux 环境及 Shell 程序

为什么要有 shell 脚本 系统管理员每天需要进行大量且重复的管理工作,如文件路径备份、更新等。这时候可以将重复进行的操作写入一个文本文件,作为 shell 脚本运行。 如,系统管理员每天都需要运行如下命令groupadd groupnameusradd –m username1 -g groupnameusradd –m username2 –g groupname -m 默认方式, /home/username1

Page 6: Linux 环境及 Shell 程序

Shell 脚本运行过程 编写 shell 脚本

使用任意编辑器( gedit 、 vim 、 nano 等)编写脚本 添加执行权限: chmod u+x test.sh 运行脚本: ./test.sh

运行脚本的几种方式 sh 脚本名: sh 只执行 bash ,读文件,只需 r 权限;开启新的儿

子 shell 运行脚本 ./ 脚本名 :当前目录下该脚本,作为可执行程序运行,需 x 权限,每

次开启新的儿子 shell 运行脚本 . 脚本名: . 是一个命令,不开启儿子 shell ,当前 shell 运行

Page 7: Linux 环境及 Shell 程序

Vim 编辑器 三种模式

插入模式: 键盘按键当作文本 命令模式: 键盘按键当作命令 底行模式: 输入“ :” 进入。

另存为 :w 新文件名 保存退出 :wq 不保存退出 :q!

Page 8: Linux 环境及 Shell 程序

Shell 脚本示例#!/bin/sh #This is s1sudo groupadd g1sudo usradd –m u1 –g g1 sudo usradd –m u2 -g g1

chmod u+x s1./s2

/etc/group 查看组/etc/passwd 查看用户

Page 9: Linux 环境及 Shell 程序

Shell 脚本示例#!/bin/sh #This is s2#print “Hello Shell!”echo “Hello Shell!”

chmod u+x s2./s2

Page 10: Linux 环境及 Shell 程序

Shell 的变量 变量名 = 变量值

不需要声明类型,直接赋值使用 等号后无空格,若变量值中有空格,需要引号,如 a=

“ hello world” 都为字符串类型,数值运算需要外部命令, expr 变量取值:在变量名称前加“ $” 

双引号“”:可引用除 $ 、 `、 \ 外任意字符或字符串 单引号‘’:可引用引号里所有字符(包括引号) $ A=a $ echo $A 输出结果为 a $ echo “$A” 输出结果为 a $ echo ‘$A’ 输出结果为 $A

Page 11: Linux 环境及 Shell 程序

系统变量和特殊变量 系统变量 env 命令查看所有环境变量

$HOME  用户主目录, ~ $PATH  执行命令时所搜寻的目录

特殊变量 $0  这个程序的执行名字

$n  这个程序的第 n 个参数值$*  这个程序的所有参数 $#  这个程序的参数个数 $$  这个进程的 PID  $?  执行上一个指令的返回值

test.sh:

#!/bin/sh

echo Filename: $0 

echo Arguments: $*

echo Number of args.: $# 

echo 1st arg.: $1 

echo 2nd arg.: $2 

执行: ./test.sh 1 2

Page 12: Linux 环境及 Shell 程序

条件测试 测试文件状态-d: 目录-s: 文件非空-f: 正规文件-w: 可写-L: 符号链接-u: 文件有 suid 位-r: 可读-x: 可执行

表达式-eq =-ne !=-gt >-lt <-n 非空串-z 空串-le <=-ge >=

逻辑操作-a &&-o ||!

# [ -f /etc/passwd -a -f /etc/inittab ]

# echo $?

0

# [ -x /etc/passwd -o -x /bin/sh ]

# echo $?

0

Page 13: Linux 环境及 Shell 程序

控制语句 if 语句

if [ 条件测试 ]then actionelif [ 条件 ] then actionelse actionfi

#!/bin/sh scores=40;if [ $scores -gt 90 ]then echo "very good!"elif [ $scores -gt 80 ] then echo "good!"elif [ $scores -gt 60 ] then echo "pass!"else echo "no pass!"fi

Page 14: Linux 环境及 Shell 程序

for 循环:for var in [list]do commands... done

while 循环:while [condition]do commands... done

循环语句

#!/bin/shnumber=1while [ $number -le 10 ]do

useradd user$numberecho Add a user whose name is:user$numbernumber=`expr $number + 1`

done

Page 15: Linux 环境及 Shell 程序

进程通信 进程间通信的作用

进程间需要数据传输、资源共享和事件通知。 进程间通信的方式

管道通信(无名管道和命名管道)信号通信内存资源共享消息队列信号量

Page 16: Linux 环境及 Shell 程序

管道通信 管道是单向的、先进先出的,把一个进程的输出和另一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)在管道的头部读出数据。

管道包括无名管道和有名管道两种,前者用于父子进程间通信,后者用于运行任意两进程通信。

Page 17: Linux 环境及 Shell 程序

无名管道 创建无名管道: pipe()

 #include <unistd.h> int pipe(int filedes[2]); 成功返回 0 ,否则返回 -1 filedes 是两个文件描述符, filedis[0] 为管道读

端, filedis[1] 为管道写端

Page 18: Linux 环境及 Shell 程序

无名管道 读管道

使用读文件描述符 fd[0] ,调用 read( ) 系统调用。 #include <unistd.h> ssize_t read(int fd,void *buf,size_t nbytes); 返回:读到的字节数,若已到文件尾为 0 ,出错为 -1 。

写管道 使用写文件描述符 fd[1] ,调用 write( ) 系统调用。 #include <unistd.h> ssize_t write(int fd,const void *buf,size_t nbytes); 返回:已写字节数,若出错为 -1 。

Page 19: Linux 环境及 Shell 程序

fork () 创建子进程

一个现有进程调用 fork 函数可以创建一个子进程。 fork 函数被调用一次但返回两次。若在子进程中则返回 0 ,父进程中则返回子进程 ID 。

main(){ int i=fork();

if(i != 0){ 父进程执行的程序段; }else if (i != -1){ 子进程执行的程序段; }

父子进程都执行的程序段;}

Page 20: Linux 环境及 Shell 程序

Wait() 阻塞自己,直到子进程死亡

进程调用 wait (),立即阻塞自己,由 wait 自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程, wait 就会一直阻塞在这里,直到有一个出现为止

Page 21: Linux 环境及 Shell 程序

无名管道 父进程写数据,子进程读数据

先调用 pipe() 创建一个管道用于父子进程间通信,再调用 fork() 创建一个子进程,该子进程会继承父进程所创建的管道。必须在系统调用 fork() 前调用 pipe()。

之后如父进程关闭写端,子进程关闭读端,就可以实现子进程向父进程发送消息。

Page 22: Linux 环境及 Shell 程序

管道 pipe(fd) 创建一个管道( #include <unistd.h> ), fd[0] 为管道的读端; fd[1] 为管道的写端。管道可用来实现父进程与其子孙进程之间的通信。管道以 FIFO 方式传送消息。 例:

main() { int x,fd[2]; char buf[30],s[30]; pipe(fd); /* 创建管道 */ while((x=fork())= = -1); /* 创建子进程失败时,循环 */ if(x = = 0) { sprintf(buf,“This is an example\n”); close(fd[0]); write(fd[1],buf,30); /* 把 buf 中的字符写入管道 */ exit(0); } wait(); read(fd[0],s,30); /* 父进程读管道中的字符 */ printf(“%s”,s); }

Page 23: Linux 环境及 Shell 程序

Linux 下 c 编程 运行 c 文件, hello.c 为例 gcc 文件名 ./ 运行程序

gcc hello.c 编译 + 链接,得到可执行文件 a.out gcc –o hello hello.c 编译 + 链接,得到可执行文件

hello

C 语言源程序.c

编译器gcc

可执行文件

Page 24: Linux 环境及 Shell 程序

实验: Shell 编程与父子进程通信

Page 25: Linux 环境及 Shell 程序

作业 Shell 编程

设计一个 shell 程序,添加一个新组为 class1 ,然后添加属于这个组的 30 个用户,用户名的形式为 stdxx,其中 xx 从 01 到 30 。

父子进程间管道通信 创建一个无名管道和子进程,子进程向父进程发送消

息(如” This message is sent from child process” ),父进程在收到消息后能做出反应(打印出” the parent process has received the message” 和该消息 )