题目1 shell 程序设计
- 格式:doc
- 大小:248.50 KB
- 文档页数:24
shell编程题Shell编程是Linux系统中非常重要的一部分,它能够帮助我们自动化执行各种命令和任务。
现在我将为大家介绍一个简单的Shell 编程题。
题目:编写一个Shell脚本,实现以下功能:1. 创建一个名为"mydir"的目录2. 在"mydir"目录中创建10个以数字命名的子目录,即1-103. 在每个子目录中创建一个空文件,文件名为子目录名+".txt",例如1.txt, 2.txt...4. 输出"mydir"目录下所有子目录名称和对应的文件数量解题思路:首先,我们需要使用mkdir命令来创建名为“mydir”的目录。
接着,可以使用一个循环来创建10个以数字命名的子目录,使用mkdir命令加上循环变量$i即可。
然后,我们再用一个循环在每个子目录中创建一个空文件。
同样,使用touch命令和循环变量$i即可。
最后,我们可以使用ls命令和grep命令来输出“mydir”目录下所有子目录名称和对应的文件数量。
具体实现方法如下:```#!/bin/bash#创建 mydir 目录mkdir mydir#循环创建 10 个数字命名的子目录for i in {1..10}domkdir mydir/$itouch mydir/$i/$i.txtdone#输出 mydir 目录下所有子目录名称和对应的文件数量ls -l mydir | grep "^d" | awk "{print $9}" | while read line donum=$(ls -l mydir/$line | grep "^-" | wc -l)echo "子目录 $line 中有 $num 个文件"done```以上便是一个简单的Shell编程题,希望对大家对Shell编程有所帮助。
实验四shell程序设计一、实验目的1.理解shell操作环境2.掌握shell程序编写方法二、实验内容1.练习、理解下面命令Alias设置指令的别名,执行命令后,列出目前所有的别名设置。
alias ld=’ls -ld .’为ls -ld .命令设置别名为ld。
history 20显示最近20个历史命令。
!!相当于再执行一遍上一条命令。
var1=”abcd1234”给变量var1赋值。
echo ${var1:3:4}从数组下标为3的值开始,显示4个值。
echo $HOME打印出当前用户环境的home目录路径/home/2011013305。
var2=$HOME给变量var2赋值,即将当前用户环境的home目录路径赋给var2。
echo ”我的主目录是$var2”显示“我的用户主目录是/home/2011013305”,没有该文件或目录。
set –o显示各命令的有效无效性,在后面加不同的参数,就能依照不同的需求进行设置。
ls *sh查找以sh结尾的文件或目录名,结果没有符合要求的文件。
arr1=(long live chair mao)给数组变量arr1赋值。
echo ${arr1[1]}显示下标为1的变量值,结果是live。
arr2=(`date`)给变量arr2赋值。
echo ${arr2[3]}显示下标为3的变量值,结果为空,执行不成功。
[ $? -eq 0 ] || echo ”上面命令执行失败。
”$? 是上个命令行执行是否成功,成功为0, -eq为”等于“的意思,执行结果为“上面的命令执行失败。
”{ date;pwd;tty;stty; }成组命令,按顺序执行{}大括号里的命令。
2.编写shell程序1)文件名webs.sh,在120.95.134.104主机建立个人主页空间;(提示:按照命令行操作命令和顺序编辑程序文件)#!/bin/bash# webs.shcd $HOMEmkdir public_htmlchmod o=rx .exit 02)文件名adds.sh,实现多个数值相加;(提示:多个数值通过参数提供) #!/bin/bash#adds.shs=0for i in $*do((s=s+i))doneecho $sexit 0执行结果:[2011013305@node1 ~]$ bash adds.sh[2011013305@node1 ~]$ bash adds.sh 1 2 36[2011013305@node1 ~]$ bash adds.sh 1 2 3 4 5153)文件名cleardirs.sh,删除指定目录下的文件和子目录;4)文件名clearfile.sh,删除指定目录下的文件及其子目录下的文件;(提示:使用find命令查找目录下文件)#!/bin/bash#clearfile.shx='find $1'for y in $xdo[ -d $y ] || {rm -f $y}doneexit 05)文件名feb.sh,显示费波纳奇数列 1 1 2 3 5 8 13 21 ...#!/bin/bash#feb.sha=1b=1echo -n $a $bfor((n=20;n>0;n--))doecho -n " $((a+b))"c=$((a+b))b=$aa=$cdoneexit 0Bash feb.sh运行文件,结果显示为:1 123 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 177113. 阅读理解程序120.95.134.104主机,/var/xg11x/adduser.sh#三、撰写实验报告报告中包括程序代码和注释。
linux shell编程题
正文:Linux shell编程题是指在Linux系统下,使用shell脚本语言进行编程的题目。
Shell脚本是一种解释性的脚本语言,可以用于编写自动化任务、系统管理以及数据处理等各种脚本程序。
下面是一些常见的Linux shell编程题目:
1. 编写一个脚本,实现统计一个文本文件中某个单词出现的次数。
2. 编写一个脚本,实现对一个目录下的所有文件进行备份,并将备份文件打包存储到另一个目录。
3. 编写一个脚本,实现对某个目录下的所有图片文件进行批量重命名,比如将所有的jpg文件重命名为png文件。
4. 编写一个脚本,实现统计某个目录下各个子目录的大小,并输出到一个文件中。
5. 编写一个脚本,实现对某个目录下的所有文件进行递归搜索,查找包含某个关键词的文件,并将结果输出到一个文件中。
这些题目涉及了Linux shell编程的一些基本概念与技巧,比如文件
操作、字符串处理、循环、条件判断等。
通过解答这些题目,可以提高对shell脚本语言的理解与应用能力,同时也能够加深对Linux系统的理解与熟悉程度。
总之,Linux shell编程题目对于提升Linux系统管理与自动化能力非常有帮助,对于那些希望深入学习Linux系统与shell脚本的人来说,是一种很好的学习方式和练习方法。
shell编程经典例题大全
Shell编程是一种在Unix或类Unix操作系统上进行脚本编程
的方法。
它可以通过命令行界面执行各种操作,包括文件操作、系
统管理和自动化任务等。
下面我将列举一些经典的Shell编程例题,以供参考:
1. 编写一个脚本,统计指定目录下所有文件的行数。
2. 创建一个脚本,实现自动备份指定目录的文件到另一个目录。
3. 编写一个脚本,监控系统内存使用情况,并在内存占用超过
一定阈值时发送警报。
4. 创建一个脚本,批量修改指定目录下的文件扩展名。
5. 编写一个脚本,实现定时清理指定目录下的过期文件。
6. 创建一个脚本,监控指定服务的运行状态,并在异常情况下
自动重启服务。
7. 编写一个脚本,实现日志文件的定时切割和压缩。
8. 创建一个脚本,批量修改指定目录下文件的权限和所有者。
9. 编写一个脚本,实现定时执行系统维护任务,如磁盘清理、日志轮转等。
10. 创建一个脚本,实现对指定目录下文件的关键词搜索并生成报告。
以上是一些常见的Shell编程例题,涵盖了文件操作、系统管理、定时任务等多个方面。
通过解决这些例题,可以帮助提高对Shell脚本编程的理解和实践能力。
希望这些例题对你有所帮助。
shell程序课程设计一、课程目标知识目标:1. 理解Shell程序的基本概念,掌握Shell脚本的基础语法和结构;2. 学习常用Shell命令,能够运用这些命令进行文件操作、系统监控和进程管理等;3. 学会使用变量、循环和条件判断等控制结构,能够编写简单的Shell程序。
技能目标:1. 能够编写简单的Shell脚本,实现自动化执行任务;2. 能够运用Shell脚本进行文件处理和数据分析;3. 能够对Shell脚本进行调试和优化,提高脚本执行效率。
情感态度价值观目标:1. 培养学生对计算机编程的兴趣和热情,提高他们主动学习的积极性;2. 培养学生的团队协作意识和问题解决能力,使他们能够更好地与他人合作共同完成任务;3. 增强学生的计算机操作能力和信息安全意识,让他们明白正确使用计算机技术的重要性。
分析课程性质、学生特点和教学要求,本课程目标具体、可衡量,旨在帮助学生掌握Shell编程的基础知识,培养他们编写脚本、解决问题的能力,同时注重培养学生对计算机技术的兴趣和正确使用计算机的态度。
通过本课程的学习,学生将能够独立完成简单的Shell程序设计,为今后的计算机编程学习打下坚实基础。
二、教学内容1. Shell概述- Shell的定义与作用- 常见Shell类型及特点2. Shell脚本基础- 脚本结构和执行方法- 变量定义与使用- 传递参数与特殊变量3. 常用Shell命令- 文件操作命令(如:ls、cp、mv等)- 文本处理命令(如:grep、sed、awk等)- 系统监控命令(如:ps、top、free等)4. 控制结构- 条件判断(if、case语句)- 循环控制(for、while语句)5. Shell函数与模块- 函数定义与调用- 模块化脚本编写6. 脚本调试与优化- 常见错误类型与解决方法- 性能优化技巧7. 实践案例- 文件整理与批量重命名- 系统监控与报警- 自动化部署与备份教学内容依据课程目标制定,涵盖Shell编程的基本概念、语法、常用命令、控制结构、函数与模块以及脚本调试与优化。
linux下shell 程序设计shell编程教学要点1.深入理解shell概念。
2.掌握linux下shell程序设计流程。
3.理解shell程序与C程序设计的区别。
4.掌握shell程序设计中用户变量和表达式的使用方法。
一.Shell编程概述问题1:请各位同学在home目录下创建5个目录,目录名称分别为student0,student1,student2,student3,student4.且修改它们的权限为所有用户都具有完全的操作权限。
问题2:请各位同学在home目录下创建100目录,目录名称为class1—class100.解决办法:通过一个shell脚本程序来实现,程序如下,用vi编辑器建立一个firstshell文件,内容如下:#!/bin/bash //指明该程序被那个shell来执行!cd /home/shelldir //进入home/shelldir目录mkdir newdir //在shelldir目录下新建newdir目录i=0 //给变量i赋初值while [ $i –lt 50 ]; do //循环,判断i是否小于50,成立继续循环let i=i+1 //让i变量值增加1mkdir /home/shelldir/newdir/student$i //在newdir目录下创建student1到student50chmod 754 /home/shelldir/newdir/student$idone保存文件,退出vi,通过执行#chmod a+x firstshell修改文件权限,赋予文件可执行权限,通过#./firstshell或者#/bin/bash firstshell来执行程序,查看程序运行结果。
程序说明:1.程序必须以下面的行开始(必须方在文件的第一行):#!/bin/bash符号#!用来告诉系统它后面的参数是用来执行该文件的程序。
在这个例子中我们使用/bin/bash来执行程序。
shell程序设计课程设计一、教学目标本课程的教学目标是使学生掌握Shell程序设计的基本概念、原理和方法,培养学生编写和调试Shell脚本的能力,提高学生在Linux环境下运用Shell程序解决问题的能力。
1.了解Unix/Linux操作系统的基本概念和原理。
2.掌握Shell程序设计的基本语法和结构。
3.熟悉常用的Shell命令和参数用法。
4.掌握Shell脚本的编写和调试方法。
5.了解Shell程序设计在实际应用中的典型案例。
6.能够使用Shell编写简单的程序,实现文本处理、文件操作等功能。
7.能够运用Shell程序解决实际问题,如自动化脚本、系统管理等。
8.具备阅读和分析复杂Shell脚本的能力。
9.能够对Shell脚本进行调试和优化。
情感态度价值观目标:1.培养学生对计算机科学的兴趣和好奇心。
2.培养学生独立思考、解决问题的能力。
3.培养学生团队协作、沟通交流的能力。
4.培养学生具有良好的职业道德和信息安全意识。
二、教学内容本课程的教学内容主要包括Unix/Linux操作系统基本概念、Shell程序设计语法、常用Shell命令、Shell脚本编写和调试方法等。
1.Unix/Linux操作系统基本概念:介绍Unix/Linux操作系统的发展历程、基本原理和常用命令。
2.Shell程序设计语法:讲解Shell程序的基本语法、变量、控制结构等。
3.常用Shell命令:介绍文本处理、文件操作、网络通信等常用命令及其参数用法。
4.Shell脚本编写和调试方法:讲解如何编写、调试和优化Shell脚本,分享实际案例。
三、教学方法本课程采用讲授法、案例分析法、实验法等多种教学方法,以激发学生的学习兴趣和主动性。
1.讲授法:通过讲解基本概念、原理和语法,使学生掌握Shell程序设计的基础知识。
2.案例分析法:分析实际案例,使学生了解Shell程序在实际应用中的作用和价值。
3.实验法:引导学生动手实践,培养学生在Linux环境下编写和调试Shell脚本的能力。
一简介Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。
Shell既是一种命令语言,又是一种程序设计语言。
作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。
因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。
可以说,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度。
注意:单独地学习Shell 是没有意义的,请先参考Unix/Linux入门教程,了解Unix/Linux 基础。
Shell有两种执行命令的方式:交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
批处理(Batch):用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。
Shell初学者请注意,在平常应用中,建议不要用root 帐号运行Shell 。
作为普通用户,不管您有意还是无意,都无法破坏系统;但如果是root,那就不同了,只要敲几个字母,就可能导致灾难性后果。
上面提到过,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本。
Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作一种Shell。
实验三Vi及Shell程序设计【实验目的】1、掌握vi的操作方法。
2、掌握Shell脚本的编程方法。
【实验内容】第一部分 vi1、请在/tmp目录下建立一个名为vitest的目录;(请书写命令)[root@wwq-VirtualBox:~]# mkdir /tmp/vitest2、进入vitest目录;[root@wwq-VirtualBox:~]#cd /tmp/vitest3、将/etc/man.config复制到本目录下;[root@wwq-VirtualBox:~]#cp /etc/man.config .注意:Ubuntu中没有man.config文件4、使用vi开启本目录下的man.config文件;[root@wwq-VirtualBox:~]#vi man.config5、在vi中设定行号;:set number6、移动到第58行,向右移动40个字符,请问看到什么目录?/dir/bin/foo7、移到第1行,并向下搜寻bzip2字符串,请问它在第几行?第118行8、将50到100行之间的man改为MAN,如何实现?:50,100s/man/MAN/gc9、修改完后,想全部复原,怎么样实现?:q!或者按u撤销10、复制65到73行这9行的内容,并粘贴到最后一行之后;按“65G”使光标移到65行,再按“9yy”,再按“G”到最后一行,再按“P”就可以完成操作。
11、删除21到42行之间的开头为#符号的批注数据,如何实现?按“21G”之后,再按“22dd”即可删除22行。
12、将这个文件另存为man.test.config文件;:w man.test.config13、转到第27行,并删除15个字符,结果出现的第一个单词是什么?删除:按“27G”,再按“15x”即可删除15个字符出现“you”单词14、在第一行新增一行,输入I am a student,怎样实现?按“1G”到第一行,再按“O”新增一行并进入插入模式,输入文字后按Esc回到一般模式。
shell程序设计(基础部分)其实作为命令语言交互式地解释和执行用户输入的命令只是shell功能的一个方面,shell还可以用来进行程序设计,它提供了定义变量和参数的手段以及丰富的程序控制结构。
使用shell编程类似于DOS中的批处理文件,称为shell script,又叫shell程序或shell命令文件。
1.shell基本语法shell的基本语法主要就是如何输入命令运行程序以及如何在程序之间通过shell的一些参数提供便利手段来进行通讯。
(1)输入输出重定向在Linux中,每一个进程都有三个特殊的文件描述指针:标准输入(standard input,文件描述指针为0)、标准输出(standard output,文件描述指针为1)、标准错误输出(standard error,文件描述指针为2)。
这三个特殊的文件描述指针使进程在一般情况下接收标准输入终端的输入,同时由标准终端来显示输出,Linux同时也向使用者提供可以使用普通的文件或管道来取代这些标准输入输出设备。
在shell中,使用者可以利用“>”和“<”来进行输入输出重定向。
如:command>file:将命令的输出结果重定向到一个文件。
command>&file:将命令的标准错误输出一起重定向到一个文件。
command>>file:将标准输出的结果追加到文件中。
command>>&file:将标准输出和标准错误输出的结构都追加到文件中。
command(2)管道pipepipe同样可以在标准输入输出和标准错误输出间做代替工作,这样一来,可以将某一个程序的输出送到另一个程序的输入,其语法如下:command1| command2[| command3...]也可以连同标准错误输出一起送入管道:command1| &command2[|& command3...](3)前台和后台在shell下面,一个新产生的进程可以通过用命令后面的符号“;”和“&”来分别以前台和后台的方式来执行,语法如下:command产生一个前台的进程,下一个命令须等该命令运行结束后才能输入。
shell编程题经典100例 1. 显示当前路径```shellpwd```2. 列出当前目录中的文件和目录```shellls```3. 创建一个新的目录```shellmkdir <目录名> ```4. 删除一个目录 ```shellrmdir <目录名> ```5. 删除一个文件 ```shellrm <文件名>```6. 复制一个文件```shellcp <源文件> <目标文件> ```7. 移动一个文件```shellmv <源文件> <目标文件> ```8. 重命名一个文件```shellmv <旧文件名> <新文件名> ```9. 创建一个符号链接```shellln -s <源文件> <符号链接> ```10. 显示一个文件的详细信息 ```shellls -l <文件名>```11. 显示一个目录的详细信息 ```shellls -ld <目录名>```12. 查找一个文件```shellfind <路径> -name <文件名> ```13. 搜索文本字符串```shellgrep <字符串> <文件>```14. 显示一个文件的指定行```shellhead -n <行数> <文件>```15. 显示一个文件的最后几行 ```shelltail -n <行数> <文件>```16. 比较两个文件```shelldiff <文件1> <文件2>```17. 合并两个文件```shellcat <文件1> <文件2> > <输出文件> ```18. 运行一个命令```shellcommand <参数>```19. 管道命令```shellcommand1 | command2```20. 重定向输出```shellcommand > <输出文件> ```21. 重定向输入```shellcommand < <输入文件> ```22. 使用环境变量```shellecho $PATH```23. 设置环境变量```shellPATH=/usr/bin:/bin export PATH```24. 创建一个脚本```shell#!/bin/bash# 脚本内容```25. 运行一个脚本 ```shell./<脚本名>```26. 调试一个脚本 ```shellbash -x <脚本名> ```27. 使用case语句 ```shellcase $1 in"start")# 执行启动命令;;"stop")# 执行停止命令;;esac```28. 使用if语句```shellif [ $1 -gt 10 ]; then# 执行条件为真的命令 else# 执行条件为假的命令 fi```29. 使用for循环```shellfor i in 1 2 3 4 5; do # 迭代执行命令done```30. 使用while循环```shellwhile [ $i -lt 10 ]; do # 循环执行命令i=$((i+1))done```31. 使用until循环```shelluntil [ $i -gt 10 ]; do # 循环执行命令i=$((i+1))done```32. 使用函数```shellfunction my_function() { # 函数体}my_function```33. 使用数组```shellarr=(1 2 3 4 5)echo ${arr[2]}```34. 使用字典```shelldeclare -A dictdict["name"]="John Doe" echo ${dict["name"]}```35. 使用正则表达式```shellif [[ $string =~ ^[[:alpha:]]+$ ]]; then # 匹配以字母开头的字符串fi```36. 使用管道符```shellls | grep "txt"```37. 使用换行符```shellecho -e "Line 1\nLine 2"```38. 使用引号```shellecho "This is a string with spaces"```39. 使用转义字符```shellecho "This is a string with a \n newline" ```40. 使用注释```shell# 这是一行注释```41. 使用条件?:```shellresult=$(if [ $condition ]; then echo "true"; else echo "false"; fi)```42. 使用切片```shellecho "${string:0:3}"```43. 使用join命令```shellecho $( IFS=","; echo "${array[]}" ) ```44. 使用read命令```shellread -p "Enter your name: " name```45. 使用变量赋值```shellvar=$(expr 1 + 2)```46. 使用算术运算```shell(( i++ ))```47. 使用逻辑运算符```shellif [[ $condition1 && $condition2 ]]; then # 条件 1 和条件 2 都为真fi48. 使用比较运算符```shellif [[ $var -gt 10 ]]; then # var 大于 10fi```49. 使用测试命令```shellif test -f <文件>; then# 文件存在```50. 使用getopts解析命令行参数 ```shellwhile getopts ":ab:" opt; do case $opt ina)flag_a=true;;b)arg_b=$OPTARG;; esac done```。
通过Shell编程中变量的定义和赋值的操作,进行条件测试语句的程序设计、选择结构的程序设计和循环结构的程序设计。
1.编写Shell程序,判断文件是否是符号链接文件,如果是则移动到/temp目录下,否则不做任何处理;代码:#!/bin/bash#filename:linkfileecho "Please input the direction of the file:"read FILENAMEif [ ! -f $FILENAME ];thenecho "$FILENAME is not exist!"exitelseif [ ! -L $FILENAME ];thenecho "$FILENAME is not a symbolic file!"exitelsemv $FILENAME /tempecho "$FILENAME has moved to /temp"fifi实验步骤:使用ln -s item link命令建立符号链接(软链接)文件,如图所示:为Q1.sh设置运行权限,并执行Q1.sh:查看链接文件情况:已经移动至/temp目录2.编写Shell程序,使用select命令生成选择菜单,允许用户在菜单中选择,并基于选择执行相应的命令;代码:#!/bin/bash#filename:selectPS3="Please choose the command:"select cmd in "ls -l" "date + %y" pwd who "cd /root" ps df clear exit do$cmdDone实验步骤:为Q2.sh设置运行权限,并执行Q2.sh:3.编写Shell程序,分别采用while和until循环结构来计算1~50之间所有奇数之和。
Shell 编程题以下是一个基于 shell 编程的题目集,覆盖了从基础的文件操作到复杂的系统调用的多个方面。
1. 文件操作**题目**:编写一个 shell 脚本,检查一个目录中的所有文件的MD5 哈希值是否都相同。
2. 文本处理**题目**:使用 awk 和 sed 命令,从文本文件中提取出所有的数字,并将它们相加。
3. 命令执行与重定向---------------**题目**:编写一个 shell 脚本,可以执行一个外部命令并获取其输出,然后基于该输出进行某些操作。
4. 变量与数据流-----------**题目**:使用 bash shell 脚本编写一个函数,该函数可以将一个字符串中的所有小写字母转换为大写。
5. 条件判断--------**题目**:编写一个 shell 脚本,判断两个文件是否相同(大小和内容)。
6. 循环结构--------**题目**:编写一个 shell 脚本,可以循环遍历一个目录下的所有文件,并对每个文件执行某个操作。
7. 函数与模块化-----------**题目**:编写一个 shell 函数,该函数可以接受一个目录作为参数,并统计该目录中的文件数量。
8. 并发与多线程(某些 shell 环境支持)----------------------**题目**:使用 bash 的并发特性,编写一个脚本,可以在多个线程中同时处理多个任务。
9. 系统调用与外部工具集成-----------------**题目**:编写一个 shell 脚本,该脚本可以调用外部工具(例如 grep、awk、sed 等)来处理文本数据。
10. 用户交互与图形界面(特定 shell 环境)-------------------------This topic is not specific to shell programming, but requires the use of a graphical user interface (GUI) toolkit such as GTK+ or Qt. Therefore, it cannot be covered in this document.。
题目1 shell 程序设计1.1 实验目的Linux操作系统中shell是用户与系统内核沟通的中介,它为用户使用操作系统的服务提供了一个命令界面。
用户在shell提示符($或#)下输入的每一个命令都由shell先解释,然后传给内核执行。
本实验要求用C语言编写一个简单的shell程序,希望达到以下目的:●用C语言编写清晰易读、设计优良的程序,并附有详细的文档。
●熟悉使用Linux下的软件开发工具,例如gcc、gdb和make。
●在编写系统应用程序时熟练使用man帮助手册。
●学习使用POSIX/UNIX系统调用、对进程进行管理和完成进程之间的通信,例如使用信号和管道进行进程间通信。
●理解并发程序中的同步问题。
●锻炼在团队成员之间的交流与合作能力。
1.2 实验要求1.2.1 ysh解释程序的重要特征本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。
实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。
ysh程序应当具有如下一些重要的特征:●能够执行外部程序命令,命令可以带参数。
.。
●能够执行fg、bg、cd、history、exit等内部命令。
●使用管道和输入输出重定向。
●支持前后台作业,提供作业控制功能,包括打印作业的清单,改变当前运行作业的前台/后台状态,以及控制作业的挂起、中止和继续运行。
除此之外,在这个实验中还须做到:●使用make工具建立工程。
●使用调试器gdb来调试程序。
●提供清晰、详细的设计文档和解决方案。
1.2.2 ysh解释程序的具体要求1. Shell程序形式本实验的ysh程序设计不包括对配置文件和命令行参数的支持。
如果实现为像bash那样支持配置文件,当然很好,但本实验并不要求。
ysh应提供一个命令提示符,如ysh>,表示接收用户的输入,每次执行完成后再打印下一个命令提示符ysh>。
当用户没有输入时,ysh需要一直处于随时等待输入状态,同时在屏幕上显示一些必要的信息。
2. 外部命令和内部命令在大多数情况下,用户输入的命令是执行存储在文件系统中的可执行程序,我们叫做外部命令或外部程序。
ysh应当支持在执行这些程序时可以将输入输出重新定向到一个文件,并允许若干个程序使用管道串联起来。
从本实验的角度来讲,我们把由管道连接起来的复合命令以及单独使用的命令统称为作业。
外部命令的形式是一系列分隔的字符串。
第一个字符串是可执行程序的名字,其他的是传给这个外部程序的参数。
如果第一个字符串所声明的可执行文件并不存在或者不可执行.则认为这个命令是错误的。
解释器还须支持一些内部命令,这些命令在ysh程序内部实现了特定的动作,下面是一些内部命令,如果用户提交了一个内部命令,ysh应当按照下面的描述执行相应动作。
●exit:结束所有的子进程并退出ysh。
●jobs:打印当前正在后台执行的作业和挂起的作业信息。
输出信息应采用便于用户理解的格式。
jobs自身是一条内部命令,所以不需要显示在输出上。
●fg %<int>:把<int>所标识的作业放到前台运行。
如果这个作业原来已经停止,那么让它继续运行。
shell应当在打印新的命令提示符之前等待前台运行的子进程结束。
●bg %<int>:在后台执行<int>标识的已挂起的进程。
3.命令行当用户在提示符后面输入命令时,输入的整行内容叫做“命令行字符串”,ysh应当保存每一条命令行字符串,直到它表示的作业执行结束,其中包括后台作业和被挂起的作业。
ysh应当给每一个命令行字符串赋一个非负整数标识符。
这个整数用来标识存储作业的数据结构,作业的数据结构应包含整个命令行字符串所表示的内容。
一旦命令行字符串代表的作业执行结束,ysh就要删掉表示这个作业的数据结构。
标识符可以循环使用。
对于包含内部命令的命令行字符串,不需要为它们建立作业的数据结构,因为它们本身的内容全部包含在ysh程序中。
4.前台和后台作业ysh应当能够执行前台和后台作业。
shell在前台作业执行结束之前要一直等待。
而在开始执行后台作业时要立刻打印出提示符ysh>,让用户输入下一条命令。
前台作业的执行总是优先于执行一个后台作业,ysh不需要在打印下一个提示符前等待后台作业的完成,无论是否有后台作业的执行,只要完成一个前台作业,便立即输出提示符ysh>。
一个后台作业结束时,ysh应当在作业执行结束后立刻打印出一条提示信息。
下面语法中会在命令语法分析程序中介绍相应的语法来支持后台作业。
5.特殊键又称组合键。
通过终端驱动程序,特殊的组合键可以产生信号给ysh,程序应当对这些信号做出适当的响应。
●Ctrl+Z:产生SIGTSTP信号,这个信号不是挂起ysh,而是让shell挂起在前台运行的作业,如果没有任何前台作业,则该特殊键无效。
●Ctrl+C:产生SIGINT信号,这个信号不是中止ysh,而是通过ysh发出信号杀死前台作业中的进程。
如果没有任何前台作业,则该特殊键无效。
6.分析用户输入1) 分隔符和特殊字符分析用户输入的语法分析器应具有下面介绍的功能,它能够检查用户的输入错误。
如果用户输入的某些地方出错了,ysh应提供合理的出错信息。
就像商业级别的shell一样,ysh每次接受用户输入的一行命令,在用户按下回车键(Enter)后开始执行分析动作。
空命令不产生任何操作,而只是打印一个新提示符。
定义空格符为分隔符,ysh应能处理命令行中间和前后出现的重复空格符。
某些字符被称做“元字符",它们在用户输入的上下文中具有特定的含义。
这些字符包括“&、| 、<、>“。
shell假设这些字符不会出现在程序名、参数名和文件名中,它们是ysh的保留字符。
下面几小节会解释这些元字符的含义。
2) 内部命令如果命令行字符串符合前面介绍的内部命令的格式,它就作为一个内部命令被解释。
如果不是,就要考虑可能是外部程序的执行,或者是错误的。
3) I/O重定向一个程序命令后面可能还跟有元字符“<”或“>”,它们是重定向符号,而在重定向符号后面还跟着一个文件名。
在“<”的情况下,程序的输入被重定向到一个指定的文件中。
在“>”的情况下,程序的输出被重定向到一个指定的文件中。
如果输出文件不存在,需要创建一个输出文件。
如果输入文件不存在,则认为是出现了错误。
4) 管道和协同程序在一条命令行中当若干个命令被元字符“|”分隔开时,这个元字符代表管道符号。
在这种情况下,ysh为每一个子命令都创建一个进程,并把它们的输入/输出用管道连接起来。
例如下面这条命令行:progA argA1 argA2<infile | progB argB1>outfile应生成progA和progB两个进程,progA的输入来自文件infile,progA的输出是progB的输入,并且progB的输出是文件outfile。
这种命令行可以通过进程间通信中的管道来实现。
含有一个和多个管道的命令会在如下几种情况下产生错误:●当其任何一个子程序执行出错时。
●除了第一个子程序以外的其他子程序的输入被重定向。
●除了最后一个子程序以外的其他子程序的输出被重定向。
由管道连接的多个进程所组成的作业只有当其所有的子进程都执行完毕后才算结束。
5)后台作业当用户需要在后台执行一个作业时,可以在作业命令的后面加上元字符“&”。
用户以该种方式输入的作业命令都必须放在后台执行,同时并不影响用户与终端的交互。
6)语法下面给出的语法规则描述图提供了控制用户输入的一种更规范的描述形式。
如果使用Linux中的现有工具lex和yacc来建立命令行分析器,还需要对这个语法进行修改,以便使它支持LALR(1)(Look Ahead Left Reduction)分析方法。
这个语法并不包括特殊键,因为它们不会在用户输入时显示出来,而是需要单独处理。
CommandLine代表用户的合法输入,它作为ysh要执行的一条“指令”。
这里假设存在一个词法分析器,它将空格符作为分隔符,并识别元字符作为一个词法记号等。
CommandLine := NULLFgCommandLineFgCommandLine&FgCommandLine := SimpleCommandFirstCommand MidCommand LastCommand SimpleCommand := ProgInvocation InputRedirect OutputRedirectFirstCommand := ProgInvocation InputRedirectMidCommand := NULL| ProgInvocation MidCommandLastCommand := |ProgInvocation OutputRedirectProgInvocation := ExecFi le Args .InputRedirect := NULL,<STRINGOutputRedirect := NULL>STRINGExecFile := STRINGArgs := NULLSTRING ArgsSTRING := NULLCHAR STRINGCHAR := 0 |1 |…| 9| a |b |…| z | A | B |…| Z7.实验步骤建议(1)阅读关于fork、exec、wait和exit系统调用的man帮助手册。
(2)编写小程序练习使用这些系统调用。
(3)阅读关于函数tcsetpgrp和setpgid的man帮助手册。
(4)练习编写控制进程组的小程序,要注意信号SIGTTIN和SIGTTOU。
(5)设计命令行分析器(包括设计文档)。
(6)实现命令行分析器。
(7)使用分析器,写一个简单的shell程序,使它能执行简单的命令。
(8)增加对程序在后台运行的支持,不必担心后台作业运行结束时要打印一条信息(这属于异步通知)。
增加jobs命令(这对于调试很有帮助)。
(9)增加输入输出重定向功能。
(10)添加代码支持在后台进程结束时打印出一条信息。
(11)添加作业控制特征,主要实现对组合键Ctrl+Z、Ctrl+C的响应,还有实现fg和bg命令功能。
(12)增加对管道的支持。
(13)实现上面的所有细节并集成。
(14)不断测试。
(15)写报告。
(16)结束。
1.3相关基础知识1.3.1 shell与内核的关系shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是包围内核的外壳,如图5—1所示。
当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。