收藏 分销(赏)

Linux结课作业.doc

上传人:仙人****88 文档编号:11896228 上传时间:2025-08-19 格式:DOC 页数:19 大小:536.50KB 下载积分:10 金币
下载 相关 举报
Linux结课作业.doc_第1页
第1页 / 共19页
Linux结课作业.doc_第2页
第2页 / 共19页


点击查看更多>>
资源描述
一、Shell编程   要求:写出两个Shell程序,每个程序不少于十五行;说明程序主要功能;每行给出注释。 #Major Function:simple calculator for + - # / # #Time :Sunday May 5,2013 # #copyright : #!/bin/bash #!/bin/sh main() { echo "calculator V1.0" # 选择操作方式 help or calulate or exit while [ 1 ] do read select if [ "$select" = "help" ] then echo "1 calculator" echo "0 exit" elif [ "$select" = "1" ] then cal; elif [ "$select" = "0" ] then break; fi done } cal() { read str # 针对读入的字串,提取操作数及操作符 num1=`echo $str|cut -d' ' -f1` num2=`echo $str|cut -d' ' -f3` sign=`echo $str|cut -d' ' -f2` # 根据sign选择对应操作 + - # / case $sign in +) sum=`expr $num1 + $num2`; echo "$num1 $sign $num2 = $sum";; -) sum=`expr $num1 - $num2`; echo "$num1 $sign $num2 = $sum";; \#) sum=`expr $num1 \* $num2`; echo "$num1 * $num2 = $sum";; /) sum=`expr $num1 / $num2`; echo "$num1 $sign $num2 = $sum";; esac } main #!/bin/bash # 数字游戏 random () { FLOOR=0 RANGE=10 num=0 while [ $num -le $FLOOR ] do num=$RANDOM #通过使随机数成为指定范围的随机数 let "num %= $RANGE" done # echo "Random number between $FLOOR and $RANGE --- $number" return } random ######################## D1=$num random D2=$num while [ $D2 == $D1 ] do random D2=$num done random D3=$num while [ $D3 == $D2 ]||[ $D3 == $D1 ] do random D3=$num done random D4=$num while [ $D4 == $D3 ]||[ $D4 == $D2 ]||[ $D4 == $D1 ] do random D4=$num done #echo $D1 $D2 $D3 $D4 ######### This is for test input_num () { #输入四个数据 并判断比较对错情况 返回?A?B echo echo "Please input four different numbers between 1~9 ( Just like this \"5 2 1 4\" ) " read S1 S2 S3 S4 } zero () { while [ $S1 == 0 ]|| [ $S2 == 0 ]||[ $S3 == 0 ]||[ $S4 == 0 ] do echo "zero is not allowd" input_num done } input_num zero while [ $S1 == $S2 ]||[ $S1 == $S3 ]||[ $S1 == $S4 ]||[ $S2 == $S3 ]||[ $S2 == $S4 ]||[ $S3 == $S4 ] do echo "wrong input" input_num done echo $S1 $S2 $S3 $S4 declare A declare B # 比较函数 compare () { A=0 B=0 if [ $S1 == $D1 ] then let A=$A+1 elif [ $S1 == $D2 ]||[ $S1 == $D3 ]||[ $S1 == $D4 ] then let B=$B+1 fi if [ $S2 == $D2 ] then let A=$A+1 elif [ $S2 == $D1 ]||[ $S2 == $D3 ]||[ $S2 == $D4 ] then let B=$B+1 fi if [ $S3 == $D3 ] then let A=$A+1 elif [ $S3 == $D1 ]||[ $S3 == $D2 ]||[ $S3 == $D4 ] then let B=$B+1 fi if [ $S4 == $D4 ] then let A=$A+1 elif [ $S4 == $D1 ]||[ $S4 == $D2 ]||[ $S4 == $D3 ] then let B=$B+1 fi clear echo "$S1 $S2 $S3 $S4 $A"A" $B"B" ">>~/answ.txt /bin/cat ~/answ.txt while [ $A -lt 4 ] do input_num compare done if [ $A == 4 ] then echo " Congratulation, you are very good " fi return } compare 二、Linux操作系统配置实例   要求:查阅资料结合实际使用情况,写出Linux操作系统使用中的一个配置的详细过程;具体配 置目标不限(自选)。 1、Linux下安装MySQL需要下面两个文件:MySQL-server-5.1.7-0.i386.rpm mysql   2、Linux下安装MySQL    rpm文件是Red Hat公 司开发的软件安装包,rpm可让Linux在安装软件包时免除许多复杂的手续。该命令在安装时常用的参数是 –ivh ,其中i表示将安装指定的rmp软件包,V表示安装时的详细信息,h表示在安装期间出现“#”符号来显示目前的安装过程。这个符号将持续到安装完成后才停 止。    1)安装服务器端    在有两个rmp文件的目录下运行如下命令:    [root@test1 local]# rpm -ivh MySQL-server-5.1.7-0.i386.rpm MySQL-client-5.1.7-0.i386.rpm   显示如下信息。 warning: MySQL-server-5.1.7-0.i386.rpm signature: NOKEY, key ID 5072e1f5    Preparing...       ########################################### [100%]    1:MySQL-server     ########################################### [100%]     。。。。。。(省略显示)    /usr/bin/mysqladmin -u root password 'new-password'    /usr/bin/mysqladmin -u root -h test1 password 'new-password'     。。。。。。(省略显示)    Starting mysqld daemon with databases from /var/lib/mysql   如出现如上信息,服务端安装完毕。测试是否成功可运行netstat看Mysql端口是否打开,如打开表示服务已经启动,安装成功。Mysql默认的端口是3306。    [root@test1 local]# netstat -nat    Active Internet connections (servers and established)    Proto Recv-Q Send-Q Local Address      Foreign Address     State       tcp  0  0 0.0.0.0:3306     0.0.0.0:*      LISTEN       上面显示可以看出MySQL服务已经启动。    2)安装客户端    运行如下命令:    [root@test1 local]# rpm -ivh MySQL-client-5.1.7-0.i386.rpm    warning: MySQL-client-5.1.7-0.i386.rpm: V3 DSA signature: NOKEY, key ID 5072e1f5    Preparing...    ########################################### [100%]    1:MySQL-client  ########################################### [100%]    显示安装完毕。    用下面的命令连接mysql,测试是否成功。   3、登录MySQL    登录MySQL的命令是mysql, mysql 的使用语法如下:    mysql [-u username] [-h host] [-p[password]] [dbname]    username 与 password 分别是 MySQL 的用户名与密码,mysql的初始管理帐号是root,没有密码,注意:这个root用户不是Linux的系统用户。MySQL默认用户是root,由于 初始没有密码,第一次进时只需键入mysql即可。    [root@test1 local]# mysql    Welcome to the MySQL monitor. Commands end with ; or \g.    Your MySQL connection id is 1 to server version: 4.0.16-standard    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.    mysql>    出现了“mysql>”提示符,恭喜你,安装成功!    增加了密码后的登录格式如下:    mysql -u root -p    Enter password: (输入密码)   其中-u后跟的是用户名,-p要求输入密码,回车后在输入密码处输入密码。   注意:这个mysql文件在/usr/bin目录下,与后面讲的启动文件/etc/init.d/mysql不是一个文件。 三、Linux操作系统应用开发实例   要求:编写Linux下的一个应用程序。开发语言和工具不限;给出源代码和运行结果。关键代码部分要给出注释。 通过 Tcpserver class TcpServer : public QDialog { Q_OBJECT public: explicit TcpServer(QWidget *parent = 0); ~TcpServer(); void refused(); void initServer(); protected: void changeEvent(QEvent *e); private: Ui::TcpServer *ui; qint16 tcpPort; QTcpServer *tcpServer; QString fileName; QString theFileName; QFile *localFile; qint64 TotalBytes; qint64 bytesWritten; qint64 bytesToWrite; qint64 loadSize; QByteArray outBlock;//缓存一次发送的数据 QTcpSocket *clientConnection; QTime time;//计时器 private slots: void on_serverSendBtn_clicked(); void on_serverCloseBtn_clicked(); void on_serverOpenBtn_clicked(); void sendMessage(); void updateClientProgress(qint64 numBytes); signals: void sendFileName(QString fileName); }; Tcp client class TcpClient : public QDialog { Q_OBJECT public: explicit TcpClient(QWidget *parent = 0); ~TcpClient(); void setHostAddress(QHostAddress address); void setFileName(QString fileName){localFile = new QFile(fileName);} protected: void changeEvent(QEvent *e); private: Ui::TcpClient *ui; QTcpSocket *tcpClient; quint16 blockSize; QHostAddress hostAddress; qint16 tcpPort; qint64 TotalBytes; qint64 bytesReceived; qint64 bytesToReceive; qint64 fileNameSize; QString fileName; QFile *localFile; QByteArray inBlock; QTime time; private slots: void on_tcpClientCancleBtn_clicked(); void on_tcpClientCloseBtn_clicked(); void newConnect(); void readMessage(); void displayError(QAbstractSocket::SocketError); }; 实现: chat::chat(QString pasvusername, QString pasvuserip) : ui(new Ui::chat) { ui->setupUi(this); ui->textEdit->setFocusPolicy(Qt::StrongFocus); ui->textBrowser->setFocusPolicy(Qt::NoFocus); ui->textEdit->setFocus(); ui->textEdit->installEventFilter(this); a = 0; is_opened = false; // this->is_opened = false; xpasvusername = pasvusername; xpasvuserip = pasvuserip; ui->label->setText(tr("与%1聊天中 对方IP:%2").arg(xpasvusername).arg(pasvuserip)); //UDP部分 xchat = new QUdpSocket(this); xport = 45456; // xchat->bind(xport, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); xchat->bind( QHostAddress::QHostAddress(getIP()), xport ); connect(xchat, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams())); //TCP部分 server = new TcpServer(this); connect(server,SIGNAL(sendFileName(QString)),this,SLOT(sentFileName(QString))); connect(ui->textEdit,SIGNAL(currentCharFormatChanged(QTextCharFormat)),this,SLOT(currentFormatChanged(const QTextCharFormat))); } chat::~chat() { is_opened = false; delete ui; } bool chat::eventFilter(QObject *target, QEvent *event) { if(target == ui->textEdit) { if(event->type() == QEvent::KeyPress)//按下键盘某键 { QKeyEvent *k = static_cast<QKeyEvent *>(event); if(k->key() == Qt::Key_Return)//回车键 { on_send_clicked(); return true; } } } return QWidget::eventFilter(target,event); } //处理用户离开 void chat::participantLeft(QString userName,QString localHostName,QString time) { ui->textBrowser->setTextColor(Qt::gray); ui->textBrowser->setCurrentFont(QFont("Times New Roman",10)); ui->textBrowser->append(tr("%1 于 %2 离开!").arg(userName).arg(time)); } QString chat::getUserName() //获取用户名 { QStringList envVariables; envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*" << "HOSTNAME.*" << "DOMAINNAME.*"; QStringList environment = QProcess::systemEnvironment(); foreach (QString string, envVariables) { int index = environment.indexOf(QRegExp(string)); if (index != -1) { QStringList stringList = environment.at(index).split('='); if (stringList.size() == 2) { return stringList.at(1); break; } } } return false; } QString chat::getIP() //获取ip地址 { QList<QHostAddress> list = QNetworkInterface::allAddresses(); foreach (QHostAddress address, list) { if(address.protocol() == QAbstractSocket::IPv4Protocol) //我们使用IPv4地址 return address.toString(); } return 0; } void chat::hasPendingFile(QString userName,QString serverAddress, //接收文件 QString clientAddress,QString fileName) { QString ipAddress = getIP(); if(ipAddress == clientAddress) { int btn = QMessageBox::information(this,tr("接受文件"), tr("来自%1(%2)的文件:%3,是否接收?") .arg(userName).arg(serverAddress).arg(fileName), QMessageBox::Yes,QMessageBox::No); if(btn == QMessageBox::Yes) { QString name = QFileDialog::getSaveFileName(0,tr("保存文件"),fileName); if(!name.isEmpty()) { TcpClient *client = new TcpClient(this); client->setFileName(name); client->setHostAddress(QHostAddress(serverAddress)); client->show(); } } else{ sendMessage(Refuse,serverAddress); } } } 以上是主要源码 未包含局域网广播ip列表获取及udp实现部分 四、 linux内核源码解读 Linux信号机制 1.信号的来源 程序错误:除零,非法内存访问… 外部信号:终端Ctrl-C产生SGINT信号,定时器到期产生SIGALRM… 显式请求:kill函数允许进程发送任何信号给其他进程或进程组。 2.Linux下查看信号 在Linux下,可以通过以下命令查看系统所有的信号: kill -l 可以通过类似下面的命令显式的给一个进程发送一个信号: kill -2 pid 3.信号的处理 忽略信号:大部分信号可被忽略,除SIGSTOP和SIGKILL信号外(这是超级用户杀掉或停掉任意进程的手段)。 捕获信号:注册信号处理函数,它对产生的特定信号做处理。 让信号默认动作起作用:unix内核定义的默认动作,有5种情况: a) abort:终止进程并产生core文件。 b) stop:终止进程但不生成core文件。 c) 忽略:忽略信号。 d) suspend:挂起进程。 e) continue:若进程是挂起的,则resume进程,否则忽略此信号。 二、深入信号机制内部 1.信号检测和响应的时机 当前进程由于系统调用、中断或异常而进入内核态以后,从内核态返回到用户态之前。 当前进程在内核中进入睡眠以后刚被唤醒的时候(必定是在系统调用中),或者由于不可忽略信号的存在而提前返回到用户空间。 2.Linux 0.11中用于信号处理的数据结构 用于保存信号信息的结构体 [cpp] view plaincopy 1 struct sigaction { 2 void (*sa_handler)(int);//信号处理句柄 3 sigset_t sa_mask;//信号的屏蔽码,可以阻塞指定的信号 4 int sa_flags;//信号选项标志 5 void (*sa_restorer)(void);//信号恢复函数指针(系统内部使用) 6 }; 进程结构体重关于信号的定义 [cpp] view plaincopy 7 long signal; 8 struct sigaction sigaction[32]; 9 long blocked; /* bitmap of masked signals */ 3.信号的预处理操作 do_signal()函数 参数为内核态堆栈中的内容 [cpp] view plaincopy 10 void do_signal(long signr,long eax, long ebx, long ecx, long edx, 11 long fs, long es, long ds, 12 long eip, long cs, long eflags, 13 unsigned long * esp, long ss) 14 { 15 unsigned long sa_handler; 16 long old_eip=eip; 17 struct sigaction * sa = current->sigaction + signr - 1; 18 int longs; 19 unsigned long * tmp_esp; 20 21 sa_handler = (unsigned long) sa->sa_handler; 22 if (sa_handler==1) 23 return; 24 if (!sa_handler) { 25 if (signr==SIGCHLD) 26 return; 27 else 28 do_exit(1<<(signr-1)); 29 } 30 if (sa->sa_flags & SA_ONESHOT) 31 sa->sa_handler = NULL; 32 *(&eip) = sa_handler; 33 longs = (sa->sa_flags & SA_NOMASK)?7:8; 34 *(&esp) -= longs; 35 verify_area(esp,longs*4); 36 tmp_esp=esp; 37 put_fs_long((long) sa->sa_restorer,tmp_esp++); 38 put_fs_long(signr,tmp_esp++); 39 if (!(sa->sa_flags & SA_NOMASK)) 40 put_fs_long(current->blocked,tmp_esp++); 41 put_fs_long(eax,tmp_esp++); 42 put_fs_long(ecx,tmp_esp++); 43 put_fs_long(edx,tmp_esp++); 44 put_fs_long(eflags,tmp_esp++); 45 put_fs_long(old_eip,tmp_esp++); 46 current->blocked |= sa->sa_mask; 47 } 对内核态堆栈的修改 4.操作系统进入信号处理 通过上述内容,可以看到操作系统在检测到有信号传入时,首先把内核堆栈中存放返回执行点的eip(指令寄存器)保存为old_eip,然后将eip替换为信号处理函数的地址,然后将内核中保存的“原ESP”(即用户态栈地址)减去一定的值,目的是扩大用户态的栈,然后将内核栈上的内容保存到用户栈上。 之所以把EIP的值设置成信号处理函数的地址,是因为一旦进程返回用户态,就要去执行信号处理程序,所以EIP要指向信号处理程序而不是原来应该执行的地址。 5.操作系统退出信号处理 在前面介绍sigaction数据结构的时候出现了信号活动恢复函数指针sa_restroer,该指针主要用于用户态堆栈的清理,把系统调用后的返回值eax和寄存器ecx,edx以及标志寄存器eflags弹出,完全恢复系统调用后各寄存器和CPU的状态,最后通过ret指令弹出原用户程序的eip(即堆栈中的old_eip),返回执行用户程序。 但是在Linux内核代码中,并没有 给出此函数的具体定义,查看相关资料,在Linux的Libc函数库中定义有函数如下 编译程序在编译连接用户自定义的信号处理函数时,会将sa_restorer()函数插入到用户程序中。这样,用户在处理完自定义的信号处理函数后,就会继续执行用户代码了。 Liunx结课作业 高源成 1067111220 10计2班
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服