1、shell 编程题:在根目录下有四个文件 m1.c,m2.c,m3.c,m4.c,用 Shell 编程,实现自动创建 m1,m2,m3,m4 四个目录,并将 m1.c,m2.c,m3.c,m4.c 四个文件分别剪贴到各自相应的目录下。
#!/bin/bash
# 创建四个目录
mkdir m1 m2 m3 m4
# 剪切文件到对应目录
mv m1.c m1/
mv m2.c m2/
mv m3.c m3/
mv m4.c m4/
echo "文件剪切完成!"
注:Shell 脚本在执行时有两个格式上的要求:以?#!/bin/bash?开头、必须有可执行权限。?
2、shell 编程题:用 Shell 编程,判断一文件是不是字符设备文件,如果是将其拷贝到/dev 目录下。
#!/bin/bash
if [ $# -ne 1 ]; then
# 检查参数数量是否正确
echo "参数错误!请传入一个文件路径作为参数。"
exit 1
fi
if [ ! -e "$1" ]; then
# 检查文件是否存在
echo "文件 $1 不存在,请检查路径是否正确。"
exit 1
fi
if [ -c "$1" ]; then
# 检查文件类型是否为字符设备文件
cp "$1" /dev
echo "文件 $1 已成功拷贝到 /dev 目录下。"
else
echo "文件 $1 不是字符设备文件,无需拷贝。"
fi
注:$n ?//n 为数字,$0 代表命令本身,$1-9 代表第 1 到第 9 个参数,10 以上的参数需要用大括号包含如 ${10}
????????$* ?//代表命令行中的所有参数,$* 将所有参数看成一个整体
????????$@ ?//这个变量也可以代表命令行中的所有参数,不过 $@ 把每个参数区分对待
????????$# ?//代表命令行中所有参数的个数????????
????????判断两个字符串
= ?//相等
????????判断两个整数
-lt ?//小于 -le ?//小于等于 -eq ?//等于 -gt ?//大于 -ge ?//大于等于 -ne ?//不等于
? ? ? ??按照文件权限进行判断
-r ?//有读的权限 -w ?//有写的权限 -x ?//有执行的权限
? ? ? ??按照文件类型进行判断
-f ?//文件存在并且是一个常规的文件 -e ?//文件存在 -d ?//文件存在并是一个目录
????????if 语句的基本语法如下,需要注意 [ 条件判断式?] 中括号与判断式之间必须有空格。
#单分支 if [ 条件判断式 ] then 代码 fi #多分支 if [ 条件判断式 ] then 代码 elif [ 条件判断式 ] then 代码 fi
3、shell 编程题:编写一个名为 del 的脚本程序,先检查所给文件是否存在。如果文件不存在,请给出提示;如果存在,完成对其的完整删除。
#!/bin/bash
if [ $# -ne 1 ];
then
# 检查参数数量是否正确
echo "参数错误!请传入一个文件路径作为参数。"
exit 1
fi
if [ ! -e "$1" ];
then
# 检查文件是否存在
echo "文件 $1 不存在,请检查路径是否正确。"
exit 1
fi
rm -rf "$1"
# 删除文件
echo "文件 $1 已成功删除。"
4、shell 编程题:编写一个名为 copy 的脚本程序,格式 copy。如果 file1 不存在,请提示;如果 file2 不存在,创建它。
#!/bin/bash
if [ $# -ne 2 ]; then
# 检查参数数量是否正确
echo "参数错误!请传入两个参数:源文件和目标文件。"
exit 1
fi
if [ ! -f "$1" ]; then
# 检查源文件是否存在
echo "源文件 $1 不存在,请检查路径是否正确。"
exit 1
fi
if [ ! -f "$2" ]; then
# 检查目标文件是否存在,如果不存在则创建
touch "$2"
fi
cp "$1" "$2"
# 复制源文件到目标文件
echo "文件已成功复制从 $1 到 $2。"
5、shell 编程题:编写一个名为 mul 的脚本程序,参数为一小于 10 的正整数。先检查参数是否符合要求。如果不符合要求,请给出提示;如果符合要求,分别输出其与 1 到 9 的乘积。
#!/bin/bash
if [ "$1" -le 0 ] || [ "$1" -ge 10 ]; then
# 检查参数是否存在且小于 10
echo "参数错误!请输入一个小于 10 的正整数作为参数。"
exit 1
fi
num="$1"
for i in {1..9}; do
# 输出乘积结果
mul=$((num * i))
echo "$num x $i = $mul"
done
注:for 循环有两个基本语法,语法一:?
for 变量 in 值1 值2 值3... do 程序 done
语法二:
for((初始值;循环控制条件;变量变化)) do 程序 done?
在定义变量时变量名称可以由字母、数字和下划线组成,但不能以数字开头;等号的两侧不能有空格;变量名称一般为大写。
将命令的返回值赋给变量时使用如下写法;
- A=`data`,表示运行?` `?中的命令,并把结果返回给 A;
- A=$(data),$() 相当于 ``。
在 Shell 编程中有各种运算操作,语法格式为?$((运算式))?或?$[运算式]?或者?expr m + n;如果希望将?expr?的值赋给某个变量,使用?``?即可。
6、shell 编程题:编写一个名为 check 的脚本程序,参数为一小于 100 的正整数。先检查参数是否符合要求。如果不符合要求,请给 出提示;如果符合要求,检查其是否为素数,并给出结果“This is a prime number”或“This is not a prime number”。
#!/bin/bash
if [ $# -eq 0 ] || [ "$1" -ge 100 ] || [ "$1" -le 0 ]; then
# 检查参数是否存在且小于 100
echo "参数错误!请输入一个小于 100 的正整数作为参数。"
exit 1
fi
is_prime=true
for ((i=2; i<$1; ++i)); do
# 判断该数是否为素数
if (( $1 % $i == 0 )); then
is_prime=false
break
fi
done
if $is_prime; then
# 给出判断结果
echo "This is a prime number."
else
echo "This is not a prime number."
fi
7、shell 编程题:编写一个名为 cubic 的脚本程序,参数为一小于 20 的正整数。先检查参数是否符合要求。如果不符合要求,请给 出提示;如果符合要求,输出从 1 到该正整数的立方值。
#!/bin/bash
if [ $# -eq 0 ] || [ "$1" -gt 20 ]; then
# 检查参数是否存在且小于 20
echo "参数错误!请输入一个小于 20 的正整数作为参数。"
exit 1
fi
for ((i=1; i<=$1; i++)); do
# 循环计算并输出立方值
cubic=$((i * i * i))
echo $cubic
done
8、shell 编程题:编写一个 shell 脚本,它使得能够显示下面序列的前 20 个数字。0,1,1,2,3,5,8,13…,前二个数字之和为第三个 数字,即著名的 Fibonacci 序列。
#!/bin/bash
num1=0
num2=1
# 初始化前两个数字
echo $num1
echo $num2
# 显示前两个数字
for ((i=3; i<=20; i++)); do
# 循环计算并显示后面的数字
num=$((num1 + num2))
# 计算当前数字
echo $num
# 显示当前数字
num1=$num2
num2=$num
# 更新前两个数字,向前移动计算窗口
done
9、编写 shell 脚本,计算 1 到 10 的阶乘。
#!/bin/bash
sum=1
for num in {1..10..1}; do
let sum=$sum*$num
done
echo $sum
注:在Bash脚本中,
for
循环的条件语句最后可以选择性地添加分号。?
10、编写 shell 脚本,实现:输入一个文件名,判断其是否为普通文件。
#!/bin/bash
echo "Enter a file name:"
read file
if [ -f $file ]; then
echo "File $file exists."
fi
注:在我们进行 Shell 编程的时候,有时候也需要跟控制台进行交互,比如用户动态的输入一些数据,这个时候就需要用到 read。
基本语法为:read(选项)(参数)
- -p 制定读取值时的提示符
- -t 指定读取值时的等待时间,如果没有在规定时间内输入,则不再等待。
11、添加一个新组为 class1,然后添加属于这个组的 30 个用户,用户名的形式为 stdxx,其中 xx 从 01 到 30。
#!/bin/sh
i=1
groupadd class1
while [ $i -le 30 ]
do
if [ $i -le 9 ]; then
USERNAME=stu0${i}
else
USERNAME=stu${i}
fi
useradd $USERNAME
mkdir /home/$USERNAME
chown -R $USERNAME /home/$USERNAME
chgrp -R class1 /home/$USERNAME
i=`expr $i + 1`
# 或 i=$(($i + 1)) 或 let "i=i+1"
done
注:while循环的格式:
while [ 条件判断式 ] do 程序 done
12、编写 shell 程序,实现自动删除 50 个用户账号的功能。账号名为 stud1 至 stud50。
#!/bin/sh
i=1
while [ $i -le 50 ]; do
userdel -r stud$i
sum=`expr $i + 1`
i=$sum
done
if [ $? -eq 0 ]; then
echo "remove successful!"
else
echo "remove failed!"
fi
13、下面给出了一个 SHELL 程序,按照其行后有#(n)形式的语句解释,补充程序,并执行程序
#!/bin/bash
#(1)使用/bin/bash 解释脚本
dir=$1
#(2)将位置变量 1 赋值给变量 dir
if [ -d $dir ]
#(3)如果 dir 所指为目录
then
cd $dir
#(4)将当前目录改为 dir
for file in *
do
if [ -f $file ]
#(5)如果循环变量 file 所指是普通文件
then
cat $file
#(6)显示文件 file 的内容
echo "remove successful!"
fi
done
else
echo "bad directory name $dir"
fi
14、试编写一个 SHELL 程序,该程序能接收用户从键盘输入的 100 个整数,然后求出其总和、最大值及最小值。
#!/bin/sh
read max
min=$max
sum=$max
i=1
while [ $i -lt 100 ]
do
read x
sum=`expr $sum + $x`
if [ $max -lt $x ]
then
max=$x
fi
if [ $x -lt $min ]
then
min=$x
fi
i=`expr $i + 1`
done
echo "sum = $sum ; max = $max ; min = $min"
15、编写 1 个弹出式菜单的 shell 程序并实现其简单的菜单功能:即用户按下数字 1,则提示用户输入源和目的文件名后执行复制;输入数字 2, 则提示用户输入要更名的文件或目录后执行更名操作; 输入数字 3,则提示用户 输入要删除的文件并执行删除操作;输入数字 4,则提示用户输入要查找的文件 并执行查找操作;输入数字 5,则退出该菜单 shell 程序的执行。
#!/bin/sh
clear
while [ 0 ]; do
echo "************************************************"
echo " menu "
echo " 1.copy "
echo " 2.rename "
echo " 3.remove "
echo " 4.find "
echo " 5.exit "
echo "************************************************"
echo -n "select: "
read choice
case $choice in
1)
echo -n "source file: "
read src
echo -n "destination folder: "
read des
cp -arf $src $des
if [ $? -eq 0 ]; then
echo "copy successful!"
else
echo "copy failed"
fi
;;
2)
echo -n "the file to be renamed: "
read src
echo -n "the new file: "
read des
mv $src $des
if [ $? -eq 0 ]; then
echo "rename successful!"
else
echo "rename failed"
fi
;;
3)
echo -n "the file to be removed: "
read src
rm -rf $src
if [ $? -eq 0 ]; then
echo "remove successful!"
else
echo "remove failed"
fi
;;
4)
echo -n "the file to be found: "
read src
find $HOME -name $src
;;
5)
exit
;;
*)
echo "Invalid option"
;;
esac
done
注:case语法规则
case $变量名 in "值1") 如果变量的值等于1,则执行程序1 ;; "值2") 如果变量的值等于2,则执行程序2 ;; ...... *) 如果变量的值都不是以上的值,则执行此程序 ;; esac?
16、用 Shell 编程,判断一文件是不是字符设备文件,如果是将其拷贝到/dev 目录下。?
#!/bin/bash
FILENAME=$1
if [ -c "$FILENAME" ]; then
cp "$FILENAME" /dev
fi
17、编写 shell 程序,实现自动删除 50 个账号的功能。账号名为 stud1 至 stud50。
#!/bin/sh
i=1
while [ $i -le 50 ]; do
userdel -r stud${i}
i=$(($i+1))
done
18、某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案:
(1)在下午 4:50 删除/abc 目录下的全部子目录和全部文件;
(2)从早 8:00~下午 6:00 每小时读取/xyz 目录下 x1 文件中每行第一个域的全部数据加入到/backup 目录下的 bak01.txt 文件内;
(3)每逢星期一下午 5:50 将/data 目录下的所有目录和文件归档并压缩为文件:backup.tar.gz; (4)在下午 5:55 将 IDE 接口的 CDROM 卸载(假设:CDROM 的设备名为 hdc);
(5)在早晨 8:00 前开机后启动。
#!/bin/bash
# 1. 在下午 4:50 删除/abc 目录下的全部子目录和全部文件
rm -rf /abc/*
# 2. 从早 8:00~下午 6:00 每小时读取/xyz 目录下 x1 文件中每行第一个域的全部数据加入到/backup 目录下的 bak01.txt 文件内
if [[ $(date +%H) -ge 8 && $(date +%H) -lt 18 ]]; then
awk '{print $1}' /xyz/x1 >> /backup/bak01.txt
fi
# 3. 每逢星期一下午 5:50 将/data 目录下的所有目录和文件归档并压缩为文件:backup.tar.gz
if [[ $(date +%u) -eq 1 && $(date +%H:%M) == "17:50" ]]; then
tar -zcf /backup/backup.tar.gz /data/*
fi
# 4. 在下午 5:55 将 IDE 接口的 CDROM 卸载(假设:CDROM 的设备名为 hdc)
if [[ $(date +%H:%M) == "17:55" ]]; then
eject /dev/hdc
fi
将上述代码保存为一个名为 daily_tasks.sh?的文件,并赋予执行权限。然后,可以使用 crontab -e?命令编辑 cron 任务,并添加以下行到文件的末尾,以在早晨 8:00 前开机后启动脚本:
@reboot /path/to/daily_tasks.sh
请将 /path/to/daily_tasks.sh?替换为实际的脚本路径。 请注意,上述脚本中的时间判断是基于当前系统时间进行的。确保脚本和路径都正确,并有足够的权限执行所需的操作。
19、设计一个 Shell 程序,在/userdata 目录下建立 50 个目录,即 user1~user50,并设置每个目录的权限,其中其他用户的权限为: 读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行。
#!/bin/sh
i=1
while [ $i -le 50 ]; do
if [ -d /userdata ]; then
mkdir -p /userdata/user$i
chmod 754 /userdata/user$i
echo "user$i"
i=$((i+1))
else
mkdir /userdata
mkdir -p /userdata/user$i
chmod 754 /userdata/user$i
echo "user$i"
i=$((i+1))
fi
done