1 / 25

Linux 环境及 Shell 程序

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

Download Presentation

Linux 环境及 Shell 程序

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux环境及Shell程序 操作系统实验1

  2. 二、Shell编程与进程通信

  3. 常用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

  4. Shell简介 • shell是用户和内核之间的接口。为屏蔽内核复杂性,在内核周围建一个外壳(shell),用户向shell提出请求,shell将请求传给内核。Shell有多种,一般使用bash(bonurne shell)。 • Shell是一种命令解释器,支持变量、函数、控制语句等,类似于一种高级编程语言。 • 以#!/bin/sh开头,指示所用的命令解释器,#后接注释

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

  6. Shell脚本运行过程 • 编写shell脚本 • 使用任意编辑器(gedit、vim、nano等)编写脚本 • 添加执行权限: chmod u+x test.sh • 运行脚本: ./test.sh • 运行脚本的几种方式 • sh 脚本名:sh 只执行bash,读文件,只需r权限;开启新的儿子shell运行脚本 • ./脚本名 :当前目录下该脚本,作为可执行程序运行,需x权限,每次开启新的儿子shell运行脚本 • . 脚本名:. 是一个命令,不开启儿子shell,当前shell运行

  7. Vim编辑器 • 三种模式 • 插入模式: 键盘按键当作文本 • 命令模式: 键盘按键当作命令 • 底行模式: 输入“:” 进入。 • 另存为 :w 新文件名 • 保存退出 :wq • 不保存退出:q!

  8. Shell脚本示例 #!/bin/sh #This is s1 sudo groupadd g1 sudo usradd –m u1 –g g1 sudo usradd –m u2 -g g1 chmod u+x s1 ./s2 /etc/group查看组 /etc/passwd查看用户

  9. Shell脚本示例 #!/bin/sh #This is s2 #print “Hello Shell!” echo “Hello Shell!” chmod u+x s2 ./s2

  10. Shell的变量 • 变量名=变量值 • 不需要声明类型,直接赋值使用 • 等号后无空格,若变量值中有空格,需要引号,如a=“hello world” • 都为字符串类型,数值运算需要外部命令,expr • 变量取值:在变量名称前加“$”  • 双引号“”:可引用除$、`、\外任意字符或字符串 • 单引号‘’:可引用引号里所有字符(包括引号) • $ A=a • $ echo $A 输出结果为 a • $ echo “$A” 输出结果为 a • $ echo ‘$A’ 输出结果为 $A

  11. 系统变量和特殊变量 • 系统变量 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

  12. 条件测试 • 表达式 -eq = -ne != -gt > -lt < -n 非空串 -z 空串 -le <= -ge >= • 测试文件状态 -d:目录 -s:文件非空 -f:正规文件 -w:可写 -L:符号链接 -u:文件有suid位 -r:可读 -x:可执行 • 逻辑操作 -a && -o || ! # [ -f /etc/passwd -a -f /etc/inittab ] # echo $? 0 # [ -x /etc/passwd -o -x /bin/sh ] # echo $? 0

  13. 控制语句 • if 语句 if [条件测试] then action elif [条件] then action else action fi #!/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

  14. 循环语句 • for循环: for var in [list]do commands... done • while循环: while [condition]do commands... done #!/bin/sh number=1 while [ $number -le 10 ] do useradduser$number echo Add a user whose name is:user$number number=`expr $number + 1` done

  15. 进程通信 • 进程间通信的作用 进程间需要数据传输、资源共享和事件通知。 • 进程间通信的方式 • 管道通信(无名管道和命名管道) • 信号通信 • 内存资源共享 • 消息队列 • 信号量

  16. 管道通信 • 管道是单向的、先进先出的,把一个进程的输出和另一个进程的输入连接在一起。一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)在管道的头部读出数据。 • 管道包括无名管道和有名管道两种,前者用于父子进程间通信,后者用于运行任意两进程通信。

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

  18. 无名管道 • 读管道 • 使用读文件描述符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。

  19. fork() • 创建子进程 • 一个现有进程调用fork函数可以创建一个子进程。fork函数被调用一次但返回两次。若在子进程中则返回0,父进程中则返回子进程ID。 main() { int i=fork(); if(i != 0) { 父进程执行的程序段;} elseif (i != -1) { 子进程执行的程序段;} 父子进程都执行的程序段; }

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

  21. 无名管道 • 父进程写数据,子进程读数据 • 先调用pipe()创建一个管道用于父子进程间通信,再调用fork()创建一个子进程,该子进程会继承父进程所创建的管道。必须在系统调用fork()前调用pipe()。 • 之后如父进程关闭写端,子进程关闭读端,就可以实现子进程向父进程发送消息。

  22. 管道 • 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); • }

  23. Linux下c编程 • 运行c文件,hello.c为例 • gcc 文件名 • ./ 运行程序 • gcc hello.c 编译+链接,得到可执行文件a.out • gcc –o hello hello.c 编译+链接,得到可执行文件hello 编译器 gcc 可执行文件 C语言源程序 .c

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

  25. 作业 • Shell编程 • 设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30。 • 父子进程间管道通信 • 创建一个无名管道和子进程,子进程向父进程发送消息(如”This message is sent from child process”),父进程在收到消息后能做出反应(打印出”the parent process has received the message”和该消息)

More Related