《Linux编程》作业 ·002【Shell编程】

注:前言、目录见 https://blog.csdn.net/qq_44220418/article/details/108428971

友情提醒:仅供参考理解,请勿直接复制粘贴

友情提醒:仅供参考理解,请勿直接复制粘贴

友情提醒:仅供参考理解,请勿直接复制粘贴

第1题

1、编写一个文件名为square的脚本程序计算和输出一组正整数的平方和 ,参数为命令行输入的一组不大于20的正整数。

# square.sh

sum=0
for arg in $*
do
	sum=`expr ${sum} + ${arg} \* ${arg}`  # 算术运算符的乘号是 \*
done
echo ${sum}

# 文件编辑完成后,使用格式如  ./square.sh 1 2 3 6 3

第2题

2、编写shell程序,对用户输入的用户名进行核对,若用户名为系统登录用户,显示欢迎信息(当前时间 用户名),否则显示非系统用户提示,重新输入(# 号退出)

# 02.sh

# who命令找出系统中所有已登录用户相关信息
# awk命令切割出用户名
# 用()将每一个用户名其存入数组
users=(`who | awk '{printf "" $1}'`)

# 用于接收用户输入的字符串str
str=""

# 提示用户输入,并接收输入
echo "请输入系统登录用户的用户名:"
read str

# 循环接收输入(判断#号有点坑,用[]说明这是一个判断表达式)
while ([ "${str}" != '#' ])
do
	# ${users[@]}形如:excious root unw
	# 对上述数组,使用grep命令,加上参数 -w 统计全单词匹配的有哪些列
	# 对上述grep命令统计结果,使用wc命令,加上参数 -w 统计匹配到的单词数,存入变量cnt
	cnt=`echo "${users[@]}" | grep -w "${str}" | wc -w`
	
	# if判断
	if [ ${cnt} -gt 0 ]
	then
		# 匹配到了某个用户名,输出用户名和时间,退出程序
		echo "${str} "`date`
		break
	else
		# 未匹配到该用户名,提示非系统用户,要求重新输入
		echo "非系统用户,请重新输入"
		read str
	fi
done

# 使用示例如下:
:<<EOF
【示例1】

$ ./02.sh

请输入系统登录用户的用户名:
exc
非系统用户,请重新输入
excious
excious 2021年 03月 28日 星期日 17:20:09 CST


【示例2】

$ ./02.sh

请输入系统登录用户的用户名:
exc
非系统用户,请重新输入
#
EOF

第3题

3、编写一个shell程序,脚本文件名为 listfile,若命令行的若干参数是合法目录名,则程序显示这些目录下所有C语言源文件(扩展名为.c)的内容,否则显示错误的目录名信息。

# listfile.sh

# Tips:如果不输入任何目录,会把当前目录作为默认的查找目录(这一点,可以对参数列表长度判断来修正,个人感觉没必要,默认当前目录就挺好的)
# 核心命令形如:find /home/excious/new/bash /home /home/excious -maxdepth 1 -name "*.c"

# 记录不合法路径的数组
arr=()

# 遍历每一个参数
for arg in $*
do
	# 使用shell的文件测试运算符测试参数中的目录是否存在
	if [ ! -d ${arg} ]
	then
		# 不存在的目录的路径名将被加入到数组arr中
		# 通过重新创建数组,实现追加新元素
		arr=("${arr[@]}" ${arg})
	fi
done

# 根据不合法路径数组arr长度,判断是否存在不合法参数
if [ ${#arr[@]} -gt 0 ]
then
	# 存在,输出报错信息
	echo "共有${#arr[@]}个错误的目录参数如下:"
	for item in ${arr[@]}
	do
		echo -e "\t${item}"
	done
else
	# 不存在,可以输出全部的.c文件的信息
	cnt=`find $@ -maxdepth 1 -name "*.c" | wc -l`
	echo "共找到以下${cnt}个.c文件"
	find $@ -maxdepth 1 -name "*.c"  # (直接执行命令了,不用echo `命令`,不然带空格的文件名、用空格分隔,很难处理)
fi

# 使用示例如下:
:<<EOF
【示例1】

$ ./listfile.sh /home2 /home3 /home/excious/new /home/excious/te /home/excious/new/bash/home03 /home/excious/new/bash/my

共有3个错误的目录参数如下:
	/home2
	/home3
	/home/excious/te


【示例2】

$ ./listfile.sh /home/excious/new /home/excious/new/bash/home03 /home/excious/new/bash/my

共找到以下11个.c文件
/home/excious/new/test.c
/home/excious/new/test2.c
/home/excious/new/bash/home03/1.c
/home/excious/new/bash/home03/2.c
/home/excious/new/bash/home03/3.c
/home/excious/new/bash/home03/4.c
/home/excious/new/bash/home03/1 2.c
/home/excious/new/bash/my/a.c
/home/excious/new/bash/my/b.c
/home/excious/new/bash/my/c.c
/home/excious/new/bash/my/d.c

EOF

第4题

4、请将基本命令1-2章作业 1 中编写的整型数组计算程序改写成有累加和与最大值两个函数模块的源程序项目文件(分模块)进行编译运行,可采用静态库和动态库方式。给出执行结果贴图(源文件,结果图)

附——1-2章作业1-4:


Linux命令操作:在自己的用户目录下建立一个子目录 proexam,在该子目录中建立 exam.c 和exmax.c两个C语言源文件,exam.c 用来输出整型数组 datalist 中的每个数据,exmax.c 用自定义函数 getmax( )输出该数组中的最大值,并用 cat 命令将这两个源文件合并成 exall.c 源文件。并进行编译调试运行(也可写出makefile文件)。

examfunc.h文件

#ifndef EXAMFUNC_H
#define EXAMFUNC_H

int sum(int []);
int max(int []);

#endif

examfunc.c文件

#include "examfunc.h"

int sum(int a[], int n) {
	int res = 0;
	for (int i = 0; i < n; ++i)
		res += a[i]
	return res;
}

int max(int a[], int n) {
	int res = a[0];
	for (int i = 1; i < n; ++i)
		res = res > a[i] ? res : a[i];
	return res;
}

exam.c文件

#include "examfunc.h"
#include <stdio.h>

int main() {
	int datalist[] = { 1, 2, 33, 4, 5};
	
	printf("数组的累加和为%d,数组的最大值为%d\n", sum(datalist, sizeof(datalist)/sizeof(int), max(datalist, sizeof(datalist)/sizeof(int));
	
	return 0;
}

04.sh文件

# 04.sh

# 静态/动态编译相关知识可以参考博客https://blog.csdn.net/daidaihema/article/details/80902012

gcc examfunc.c -c -I .
ar rcs examfunc.a examfunc.o
gcc exam.c -I . examfunc.a -o exam
./exam

# 使用示例
# 
# ./04.sh 
# 
# 数组的累加和为45,数组的最大值为33

运行截图

  • 运行脚本04.sh
  • 运行脚本04.sh

第5题

5、编写shell程序( 文件名 test_funcprg ),运用自定义函数sum()与max()计算一组整数数组的累加和与最大值,并按菜单选择输出相应计算结果。数组数据可由键盘读入,并以菜单方式运行(菜单选项:sum , max, exit)

# test_funcprg.sh

# sum函数
sum() {
	# 提示用户输入数组数据
	arr=()
	read -p "请输入一个数组:" -a arr

	# 计算数组累加和
	res=0
	for num in ${arr[@]}
	do
		res=$((${res} + ${num}))
	done
	
	# 输出结果,等待用户返回菜单
	echo "数组的累加和为${res}(按回车开始返回菜单)"
	getch
}

# max函数
max() {
	# 提示用户输入数组数据
	arr=()
	read -p "请输入一个数组:" -a arr

	# 计算数组累加和
	res=${arr[0]}
	for num in ${arr[@]}
	do
		# 三目运算符,相当于C语言里的 res = (res > num) ? res : num
		res=`[ ${res} -gt ${num} ] && echo ${res} || echo ${num}`
	done
	
	# 输出结果,等待用户返回菜单
	echo "数组的最大值为${res}(按回车开始返回菜单)"
	getch
}

# 用于等待一个回车(或者其他输入)后清屏
getch() {
	read
	clear
}

# 主函数
# 先清屏,打印菜单,等待输入
a=0
clear
while :
do
	echo "1.sum"
	echo "2.max"
	echo "3.exit"
	read -p "请输入你的选择:" a
	case ${a} in
	1)
		clear
		sum
		;;
	2)
		clear
		max
		;;
	3)
		clear
		echo "您已退出"
		break
		;;
	*)
		clear
		echo "您输入的选项\"${a}\"有误(按回车开始返回菜单)"
		getch
		;;
	esac
done


# 使用示例
:<<EOF

$ ./test_funcprg.sh

1.sum
2.max
3.exit
请输入你的选择:1

请输入一个数组:1 22 124 53
数组的累加和为200(按回车开始返回菜单)

1.sum
2.max
3.exit
请输入你的选择:2

请输入一个数组:1 214 12 2 215 62 123
数组的最大值为215(按回车开始返回菜单)

1.sum
2.max
3.exit
请输入你的选择:1241

您输入的选项"1241"有误(按回车开始返回菜单)

1.sum
2.max
3.exit
请输入你的选择:3

您已退出

EOF
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

God-Excious

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值