几个shell编程题

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

1、检查进程

写一个shell脚本,每隔10秒,检查当前系统中有没有进程名字为“firefox”的进程,如果有的话显示“firefox 进程出现了!”并退出,返回码设置为等待的秒数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while true
do
process = `pgrep -f firefox`
#pgrep命令以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
#ps -ef | grep 'firefox' ?
i=0
if [ ${#process} -gt 0 ]# ${#string}获取字符串长度
then
echo “firefox进程出现了!”
echo “等待时间为:$i”
break
else
i = i+10
sleep 10
fi
done

2、解释这行命令的含义

如果输入123,会显示什么?如果输入1234显示什么?

1
2
3
4
5
6
#从标准输入中读取abc的值
read abc;
#若abc小于999,则res为too small。否则,res为ok
test $abc -lt 999 && res='too small' || res=ok;
#输出res
echo $res;

3、求矩形面积

编写一个Shell脚本,求矩形面积。长、宽参数从命令行传入。

1
2
3
read width height
area=$(($width*$height))
echo $area

4、监视用户是否登录

写一个脚本,持续监视用户stu是否登录,如果登录了,就每隔1分钟把你的用户名和QQ号码发给他,重复发送3次为止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while true
do
user=`who | grep -w “stu”`
if [ ${#user} -gt 0 ]
then
#或者不用循环,重复三次
i=0
while [ “$i” –lt 5 ]
do
echo “please enter message and press ctrl + D”
write stu
i=$((i+1))
sleep 60
done
fi
done

5、给出下脚本的执行结果

1
2
3
4
5
6
7
i=1
while [ “$i” –lt 5 ]
do
j=$((i*i))
echo “$j”
i=$((i+1))
done

运行结果为:
1
4
9
16

6、试解释以下命令或命令组的含义

1
2
3
4
5
6
7
8
9
10
$grep ‘789’  lppasswd  |  wc –l	
#统计带有789的密码个数(实际上这个命令根本执行不了)
ls –l | grep ‘^d’
#列出ls -l输出的内容中,d开头的内容
ls -d ?[!y]*[e-f]
#任意单个字符+非y字符+任意多个字符+e或f结尾
echo $HOME
#输出用户的主目录
cat file1 file2 > cat.out 2> cat.err
#将file1,2的内容输出至cat.out,并将错误信息输出到cat.err

7、权限问题

假设使用ls命令: $ls –lR 显示下列信息

1
2
3
4
5
6
$ls –lR
drwxr-xr-x 3 judy finance …. jobs
./jobs:
drwxrwxrwx 2 judy finance …. work
./work:
-rw–r-- r-- 1 judy finance …. joblog

用户 Fred是 finance 组的成员, Fred是否可以拷贝 joblog 文件到自己的目录下?简述理由。
可以拷贝文件,因为joblog的同组用户有读权限,对work目录和jobs目录有执行权限,并且对自己的目录有写权限,所以可以复制。

8.计算两个数的最大公约数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
read -p "请输入两个正整数,以空格键分割,按enter键结束:" x y
big=0
small=0
if (( $x > $y ))
then
small=y
else
small=x
fi
z=1
for (( i=1;i<=small;i++ ))
do
if(( x%i==0&&y%i==0 ))
then
z=$i
fi
done
echo "$x 和 $y 的最大公约数是:$z"

9.找最大数和第二大数

输入一系列数,输出最大的数和第二大的数,回忆诸多排序算法,用冒泡排序的思想轻松解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
read -a num -p "请输入一系列整数,以空格分隔,按enter键结束:"
maxnum=${num[0]}
secnum=${num[0]}
for (( i=0;i<${#num[*]};i++ ))
do
if ((${num[i]}>$maxnum))
then
secnum=$maxnum
maxnum=${num[i]}
else
if((${num[i]}>$secnum))
then
secnum=${num[i]}
fi
fi
done
echo -e "最大数:$maxnum\n第二大数:$secnum"

事实上,大一上的水平怎么可能要求用数组呢,:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
maxnum=$1
secnum=$1
for i in $@
do
if ((i>$maxnum))
then
secnum=$maxnum
maxnum=${num[i]}
else
if((i>$secnum))
then
secnum=$i
fi
fi
done
echo -e "最大数:$maxnum\n第二大数:$secnum"
#以上内容编写为脚本,参数通过执行脚本输入:
sh shell.sh 1 2 3 4 5 6 7 8 9 10

$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个

$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

命令

注:# 是系统管理员的命令提示符,$是普通用户的命令提示符

$login: UserName
$password: [your password]

登录

$〈Ctrl-d〉
$ exit
$ logout
退出:

date 显示日期和时间

date -s 20041229 设置日期

date -s 12:23:23 设置时间

cal [month] [year] 显示日历

cal 只显示当前月份信息

pwd:(print working directory) 显示当前工作目录

ln [-s] target [link name] 为文件建立一个链接文件

CST: China Standard Time

who 显示登陆到系统的所有用户的详细信息
cd 可从任何位置返回主目录(用户joe:/home/joe root用户:/root)

“.”,代表当前目录
“..”,代表当前目录的父目录

cat [-n] filename 将文件的文本内容一次全部显示在屏幕上 -n :打印行号

alias ls=’ls —color=auto’ 给变量取别名
unalias cp 取消别名

whoami 显示当前用户有效帐号
ls 显示该目录或路径下所包含的文件及目录列表,以及文件的相关信息
touch 以当前时间创建文件或更新已有文件的时间戳

more 分屏显示文件内容
less 对文件或其它输出进行分页显示
wc 该命令能够统计文件中的字符数、单词数和行数。

id 显示用户 id 以及群组 id
chmod 改变权限

cp 复制文件

mv 对文件进行名称更改或路径迁移

whereis 显示指令的二进制码、原始码与在线手册说明文件的存放目录

grep 对文本文件的内容进行模式查找

grep [-option] pattern files

pattern匹配模式:
若匹配模式中包含字符串参数,则最好用引号括起,以免引起歧义

正则表达式:

^ 只匹配行首,用在字符串前面
$ 只匹配行尾,用在字符串后面
X* 0个或多个字符X
. 只匹配任意单字符
[字符表] 字符表中的任意字符
[‘^’字符表] 任意不在字符表中的字符
\ 屏蔽其后的特殊字符的特殊含义
{n} 前导的正则表达式重复n次
{min,max} 前导的正则表达式重复min~max次

pgrep 找某进程

rm 删除文件或目录
mkdir 创建目录

rmdir 删除目录

ping 检测主机
find 在指定目录下查找文件

sleep 延迟一段时间

chroot 更换根目录
top 实时显示 process 的动态

wget 下载文件的命令

dmesg 显示开机信息

locate 在这个数据库文件中进行检索文件名
mail 发送 E-mail
wall 所有在线用户会收到以下信息:
write 若一用户在线,可用 write 命令发送信息。
mesg 决定是否接受 write、wall 命令发送的消息,
man 是一个帮助命令,可以通过这个命令显示需要命令信息。
help 查询内建命令的帮助文档
w 显示目前登入系统的用户信息
su 变更使用者(swich user)

sudo 以系统管理者的身份执行指令

last 显示用户最近的登录信息
du 显示目录或文件的大小
df 显示磁盘使用情况
tail 显示文件末尾
head 查看文件开头部分的内容。

mount 挂载Linux系统外的文件

ps 用于列出当前进程清单

job 显示后台任务的执行情况

command & 末尾加&符号将进程交给后台执行

fg %jobID 进程恢复到前台

bg %jobID 进程恢复到后台

nohup {command|script} & 使进程在用户退出后仍能继续执行

细节概念

Linux是多用户、多任务、抢占式操作系统,原著者Linus,是开源操作系统。
Linux操作系统基本组成:内核、SHELL、System Applications

三种引号:

单引号括起来的所有字符都作为普通字符出现

由双引号括起来的字符,除$、\、引号几种符号具有其特殊功能外,其余字符都作为普通字符对待

反引号括起来的内容被Shell解释为命令行

输入文件 — 标准输入 – stdin 0
输出文件 — 标准输出 – stdout 1
错误输出文件 —标准错误输出 – stderr 2

kernel:

管理程序的运行,管理对文件系统的读写,管理存储器,管理输入、输出,管理网络。

操作系统发展简史
批处理系统 多道程序系统 分时系统
实时系统 通用操作系统 个人机系统
网络操作系统 分布式系统

操作系统定义
操作系统是计算机系统的基本系统软件。操作系统负责控制、管理计算机的所有软件、硬件资源,是唯一直接和硬件打交道的软件系统,同时还为计算机用户提供良好的界面。因此,操作系统直接面对所有硬件、软件和用户,它是协调计算机各组成部分之间、人机之间关系的重要软件系统。

输出重定向中,> 的意思是覆盖, >>的意思是追加

硬链接( Hard Link)
原文件名和链接文件名都指向相同的物理位址。 (i-node number )
如果删除硬链接文件的源文件,硬链接文件仍然存在,而且保留了原有的内容
硬链接不能跨越文件系统
符号链接( Symbolic Link)
它的内容是它所链接的文件的路径名
由于存放的是源文件的路径名,因而如果删除符号链接文件的源文件,符号链接文件将无法找到原有资料。
能够跨越文件系统

在移动文件时不需要被移动文件的权限,但需其所在目录具有写权限
在目录下增删文件、子目录时要有目录的写权限(touch,rm,mkdir,rmdir)
用ls列目录要有目录的读权限
进入目录或将该目录作路径分量时(cd)要有目录的执行权限,故要使用任一个文件,必须有该文件及找到该文件的路径上所有目录分量的执行权限。
仅当要打开一个文件时,即执行涉及到文件内容的操作时,才需要文件的许可。

bash shell支持C式for循环 : for (( i=0;i<5;i++ ))

复习题

一、填空题:

1、ls、cp等命令文件一般位于哪个目录: /bin

2、在Linux系统中,第一个启动的进程是: init 其编号为:1

3、给出文件的三种类型的名称 普通文件、目录文件、设备文件

4、当前用户是stu,当前目录在/home/stu/mydir/,则执行cd ../..命令后当前目录是 /home ,再执行cd命令后当前目录是 /home/stu

5、env 命令可以显示环境变量?。

6、在多用户环境下,管理员在关机重启机器之前一般可以使用 wall 命令通知所有在线用户注意存盘退出。

7、root 用户具有系统的最大权限。

二、选择题。
1、我们实验使用的shell是哪个? D
A、bsh B、ksh C、csh D、bash
2、可以分页显示文件内容的命令是C_
A、pwd B、cat C、more D、page
3、bash中默认已有的变量一般不包括(A )。
A、find B、PWD C、HOME D、USER。
4、从标准输入读入值并赋予一个变量的命令是(C )
A、out B、scan C、read D、in
5、 下列哪个命令可将文本文件f.txt拷贝为f.bak?(B )
A、cp f.txt | f.bak B、cat f.txt>f.bak C、cp f.txt >f.bak D、ls f.txt f.bak

三、 判断题。

1、Linux是多任务操作系统。( ✔ )

2、Linux 是多用户操作系统。( ✔ )

三、简答下列问题。

1、解释read命令的功能,举例说明其用法。

read命令是从标准输入读入变量值,例如:
read var1 var2
hello world(注:var1为hello,var2为world)
read var1 var2
hello world 0.0(注:var1为hello,var2为world!0.0)
read var1 var2
hello(注:var1为hello,var2为空)

2、如果当前目录下只有一个文件abc123,解释echo abc*和echo xyz=abc*命令的输出。

“echo abc\”命令会输出abc123,“echo xyz=abc*”命令会输出xyz=abc*。*
出现这种结果的原因为,“\”既可以作为通配符,也可以作为字符。由于目录下的文件只有abc123,那么在“echo abc”时,*作为通配符,匹配的结果就是abc123。而由于目录下没有以xyz=abc开头的文件,所以在“echo xyz=abc”时,是作为一个字符串进行输出的。

3、画图示意操作系统、硬件和应用软件关系。

在这里插入图片描述

五、根据以下小题的要求写出相应的命令或命令组。

1、显示当前目录下文件名以abc开头同时以123结尾的文件。

ls | grep “^abc.*123$”

2、把文本文件file1复制为file2,然后在file2尾部增加一行内容为“END”。设置权限,自己的文件file1,只允许自己完全访问和使用,自己之外的人仅有读权限。

cp file1 file2
echo “END” >> file2
chmod 744 file1

3、假设myprog.sh是你所写的一个脚本程序,写出命令在后台执行它。

sh myprog.sh &

4、用命令或命令组合列出当前目录下的所有目录文件(不列出其他文件)。

ls -d \/*

5、在上一级目录的子目录src中建立一个空文件,文件名叫my_logfile。

touch ../src/my_logfile

6、在当前路径下建立 /letters/mail的符号链接m-soft。

ln -s /letters/mail ./m-soft

7、在屏幕上显示字符串“$abc”。

echo \$abc