嵌入式系统原理与应用 课件 第8、9章 Linux下的Shell命令与编程、Linux下程序设计工具_第1页
嵌入式系统原理与应用 课件 第8、9章 Linux下的Shell命令与编程、Linux下程序设计工具_第2页
嵌入式系统原理与应用 课件 第8、9章 Linux下的Shell命令与编程、Linux下程序设计工具_第3页
嵌入式系统原理与应用 课件 第8、9章 Linux下的Shell命令与编程、Linux下程序设计工具_第4页
嵌入式系统原理与应用 课件 第8、9章 Linux下的Shell命令与编程、Linux下程序设计工具_第5页
已阅读5页,还剩151页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式系统原理与设计第8章Linux下的Shell命令与编程第八章01020304基本概念常用Shell命令Shell编程基础Shell编程的控制语句/01基本概念Shell简介1.什么是ShellLinux系统中,Shell就是套在操作系统内核外面的一层壳。正因为Shell的存在,才向普通用户隐藏了许多关于操作系统内核的细节,方便了用户使用计算机。2.Shell的功能Shell的基本功能是进行命令解释和执行,用来接收用户输入的命令,并传递给操作系统。Shell的扩展功能是一种程序设计语言,利用Shell规定的语法,可以设计出各种功能的程序来更方便的管理或使用计算机。Shell简介Shell的版本BourneShell:简称sh,该Shell由SteveBourne在贝尔实验室时编写。Bourne-AgainShell:简称bash,该Shell由BrianFox编写,是绝大多数GNULinux发行版的默认Shell。CShell:简称csh,该Shell由Billjoy在BSD系统上开发,由于其语法类似于C语言,因此称为CShell。ZShell:Thelastshellyou’lleverneed!Z是最后一个字母,也就是终极Shell。它集成bash、csh的重要特性,同时又增加了独有的特性。Shell简介Shell编程的应用场景在嵌入式系统开发过程中,以下场景都可以通过Shell编程简化工作:将一些复杂的命令简单化。例如:在GitHub上提交一次代码需要很多步骤,但是用Shell之后就可以简化成一步。在项目开发中,通过脚本自动实现更新最新的软件开发工具包(SDK)。能够批量处理,大部分操作过程位于后台,不需要用户进行干预。自动打包、编译、发布等功能。Linux下目录与路径Linux系统中,目录就是描述所有文件信息的树型结构,如图所示。Work目录(工作目录)Home目录(家目录)Linux下目录与路径

路径指从树型目录中的某个节点(起点)到另一个节点(终点)经过的节点次序,起点节点一般为目录,终点节点可以为目录或文件。节点和节点之间用“/”分开。绝对路径绝对路径是指从“根目录”开始到达某个节点的路径,也称为完全路径。相对路径相对路径是从某节点开始到其子节点的路径。Linux下的用户Linux是多用户操作系统,多个用户可以同时登录进行操作。超级用户指的是root用户,它是Linux默认的系统管理员,拥有管理计算机的全部权限。普通用户指的是权限受限的其它用户。Linux系统中,每个文件、目录和进程,都归属于某一个用户。通常而言,每个普通用户只能操作属于自己的文件、目录和进程,操作其他用户的文件、目录和进程需要得到别的用户的许可。例:显示文件的详细信息后,可以看到Linux下文件的权限、用户的对应关系

2408949-rwxr-xr-x1rootroot704-2112:47lsfile.sh

2408260drwxr-xr-x2rootroot4.0K04-2122:15mydir/02常用Shell命令目录和文件操作命令目录和文件操作命令改变目录:cdcd(ChangeDirectory)命令用于在Linux文件系统的不同目录之间切换。列出目录内容:lsls命令是list的简化形式,ls的命令选项非常多,下边只讨论一些最常用的选项。-a:显示所有文件及目录;-l:除文件名称外,亦将文件类型、权限、拥有者、文件大小等信息详细列出;-r:将文件以相反次序显示(原定依英文字母次序);-t:将文件依建立时间之先后次序列出;-i:显示文件的inode号;-A:同-a,但不列出"."(当前目录)及".."(父目录);-F:在列出的文件名称后加一符号,指示文件类型;例如可执行文件则加"*",目录则加"/",链接文件后加"@"。2408949-rwxr-xr-x1rootroot704-2112:47lsfile.sh

第一字段:inode(索引节点)

第二字段:文件种类(-)和权限(rwx,共9位,分别控制文件属主、用户组以及其它用户的权限);

第三字段:硬链接个数;

第四字段:属主;

第五字段:所归属的组;

第六字段:文件或目录的大小(字节);

第七字段和第八字段:最后访问或修改时间;

第九字段:文件名或目录名文件类型:-:常规文件d:目录l:链接文件b:块特殊设备c:字符特殊设备目录和文件操作命令显示当前目录:pwdpwd(PrintWorkDirectory)命令会显示当前所在的位置,即工作目录。创建和删除目录:mkdir和rmdirmkdir:创建一个或多个目录。rmdir:删除一个或多个空目录。目录必须是空目录,否则会指出这不是一个空目录,删除失败。复制文件或目录:cpcp[选项]源文件目标文件cp[选项]源文件组目标目录目录和文件操作命令移动或更名:mvmv[-f][-i]文件1文件2 #文件1是源文件,改名操作mv[-f][-i]目录1目录2 #目录1是源目录,移动目录操作mv[-f][-i]文件列表目录

#移动一组文件到目标目录下删除文件:rmrm[选项]文件列表rm-rf* #递归删除当前目录下的所有文件和子目录目录和文件操作命令创建链接:lnln[选项]目标[链接名]ln[选项]目标目录ln命令用于在文件之间创建链接,实际上是给系统中已有的某个文件指定另一个可用于访问它的名称。默认情况下,ln产生的是硬链接,若需要创建软链接则用参数-s。链接文件链接是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法。对一个目录下的该文件进行修改,就可以完成对所有目录下同名链接文件的修改。对某个文件的各链接文件,可以给它们指定不同的权限,以控制对信息的共享和增强安全性。文件的链接有两种形式:硬链接和符号链接(软链接)。硬链接:硬链接是文件的一个拷贝,其i节点号是一样的。但比复制有优势,复制只是一个简单的拷贝,是静态的;而硬链接不但是拷贝,而且是动态和资源共享的。不能对目录文件创建硬链接(root用户除外);不能在不同的文件系统之间做硬链接。软链接:符号链接也称软链接,是一个新文件。符号链接类似于windows的快捷方式,符号链接实际上是特殊文件的一种。在符号链接中,文件实际上是一个文本文件,其中包含有另一个文件的位置信息。硬链接和软链接的区别符号链接是一个新文件,具有自己的I节点号;硬链接没有建立新文件,其只是一个指针。符号链接没有硬链接的限制,可以对目录文件建立符号链接,也可以在不同文件系统之间建立符号链接。当源文件被删除后,硬链接文件同样可以被使用,而符号链接文件将无法使用。符号链接会显示为“链接文件名->指向的实际文件”,而硬链接通过文件名无法判断。例:硬链接和软链接具体实例。

$ls-lie1.sh #显示e1.sh文件的具体信息 403542-rw-r--r--1hllhll602019-11-0401:05e1.sh$lne1.she1_hard.sh #给e1.sh创建一个硬链接文件e1_hard.sh$ln-se1.she1_soft.sh #给e1.sh创建一个软链接文件e1_soft.sh$ls-lie1* #显示e1*文件的具体信息 403542-rw-r--r--2hllhll602019-11-0401:05e1_hard.sh 403542-rw-r--r--2hllhll602019-11-0401:05e1.sh 403553lrwxrwxrwx1hllhll52019-11-1104:14e1_soft.sh->e1.sh$cate1_soft.sh #显示e1_soft.sh文件内容 ThisisthesourcefileoftheHardlinkfileorSoftlinkfile.$cate1_hard.sh #显示e1_hard.sh文件内容 ThisisthesourcefileoftheHardlinkfileorSoftlinkfile.目录和文件操作命令修改文件权限:chmod该命令用于改变文件的访问许可,但是符号链接除外chmod[选项]文件和目录列表设置权限的两种方式:使用字符串设置权限使用八进制数设置权限用户类型包括:属主用户user

组用户(即文件属主用户所在的组)group

其它用户other许可类型包括:

读read,r写write,w

执行execute,x使用字符串设置权限chmodu+re1.sh#给用户设置文件e1.sh的r权限chmodugo+rwe1.sh#给用户、同组用户、其他用户设置文件e1.sh的rw权限用户类型:u表示“用户(user)”g表示“同组(group)用户”

o表示“其他(others)用户”

a表示“所有(all)用户”chmod用户类型+/-许可的种类使用八进制数设置权限执行权、写权和读权所对应的数值分别是1,2和4。可以用这几位数进行任意组合,例如:若要rwx属性则4+2+1=7;

若要rw-属性则4+2=6;

若要r-x属性则4+1=5。chmod4e1.sh #给用户设置了文件e1.sh的r权限chmod666e1.sh #给用户、同组用户、其他用户设置了文件exa2-4的rw权限目录和文件操作命令

chattr[-RV][+-=acdijsuADS]文件或目录名+表示增加某项属性,-表示取消某项属性,=设置文件或目录只具有哪些属性;

-R递归设置指定目录及其目录下的所有文件和子目录的属性;

-V详细显示目录和文件的属性设置情况。

a属性:只允许向文件追加数据,不允许任何进程覆盖重写文件的内容。

A属性:设置不允许系统更新文件的最后访问时间

i属性:不可修改属性。具有该属性的文件不能被删除、更名或修改其内容。10.设置文件的扩展属性chattr

c属性:压缩属性,写入或读取时,系统会自动进行压缩或解压缩。

s属性:安全删除属性。即在删除一个文件时,会使用0填充原文件所在的存贮区,以使恢复工具无法恢复出文件的内容。

u属性:可恢复性的删除。对于具有该属性的文件,在删除时,系统会保留其数据块以便以后能恢复该文件的内容例如:若要给/etc/rc.local文件增加不可修改属性,则实现命令为:chattr+i/etc/rc.local若要取消i属性,则实现命令为:chattr-i/etc/rc.local查看文件的扩展属性lsattr查看文件的扩展属性使用lsattr命令,命令用法:

lsattr[-adR]文件名或目录名

-a 列出目录中的所有文件(包括隐藏文件)。

-d 以与文件相同的方式列出目录的扩展属性。

-R 以递归的方式列出目录的属性及其内容。例如,若将/etc/rc.local文件设置为具有i属性和A属性,并查看设置后的属性,其实现命令为:

[root@RHEL5~]#chattr=iA/etc/rc.local

[root@RHEL5~]#lsattr/etc/rc.local

----i--A-----/etc/rc.local用户管理命令用户管理命令添加用户命令:useradd修改用户密码:passwduseradd[选项]用户名passwd[选项]用户名$useraddjack#创建的是“三无”用户,无家目录,无密码,无系统Shell$grepjack/etc/passwd#查看jack用户信息 jack:x:1003:1003::/home/jack:/bin/sh#显示jack用户创建成功$ls/home yybhll #但是,在home目录下无jack家目录$useradd-m-s/bin/bash-d/home/jack1jack1$passwdjack#修改用户jack的密码 EnternewUNIXpassword:#输入密码时,屏幕不会显示任何信息 RetypenewUNIXpassword: passwd:passwordupdatedsuccessfully用户管理命令修改用户信息:usermod修改用户密码状态:chageusermod[选项]用户名chage[选项]用户名$grepjack/etc/passwd#查看修改前的用户信息jack:x:1001:1001::/home/jack:#usermod-lmikejack#grepmike/etc/passwd#查看修改后的用户信息mike:x:1001:1001::/home/jack:#chage-ljackLastpasswordchange :Nov11,2019Passwordexpires

:neverPasswordinactive :neverAccountexpires :neverMinimumnumberofdaysbetweenpasswordchange :0Maximumnumberofdaysbetweenpasswordchange :99999Numberofdaysofwarningbeforepasswordexpires :7用户管理命令删除用户命令:userdel查看用户id命令:id删除系统中已有的用户,该命令的格式如下:userdel[选项]用户名查看系统中指定用户的id,该命令的格式如下:id用户名用户管理命令切换用户身份命令:su显示系统登录用户:whosu[选项]用户名-:只使用“-”代表连带用户的环境变量一起切换-c:仅执行一次命令,但不切换用户身份who命令显示关于当前在本地系统上的所有用户的信息。显示以下内容:登录名、终端类型(tty)、登录日期和时间。通过su命令,可以从普通用户切换到root用户,也可以从root用户切换到普通用户。从普通用户切换到root用户需要密码,从root用户切换到普通用户不需要密码。Linux还提供另一个与su相关的命令,即sudo命令。sudo可以跳过root用户登录而去执行一些特定命令。$sudopasswdjack#更改jack用户的密码当然,这条命令执行的前提是当前登录用户拥有执行sudo命令的权限,这可以通过配置/etc/sudoers文件来实现。其他常用命令其他常用命令1.find:查找文件或目录格式:find[目录列表][匹配标准]参数说明:目录列表:希望查询文件或文件集的目录列表,目录间用空格分隔。匹配标准:希望查询的文件的匹配标准或说明。随着文件的增多,使用搜索工具成了顺理成章的事情。find就是这样一个强大的命令,它能够迅速在指定范围内查找到文件,命令格式为:-name文件告诉find要找什么文件;要找的文件包括在引号中,可以使用通配符(*和?)

-perm模式匹配所有模式为指定数字型模式值的文件。不仅仅是读,写和执行,所有模式都必须匹配。如果在模式前是负号(-),表示采用除这个模式外的所有模式。

-typex匹配所有类型为x的文件。x是c(字符特殊),b(块特殊),d(目录),p(有名管道),l(符号连接),s(套接文件)……-linksn匹配所有连接数为n的文件。

-user用户号匹配所有用户序列号是前面所指定的用户序列号的文件,可以是数字型的值或用户登录名。

-atime+/-n匹配所有在n天前/n天内访问过的文件。-mtime+/-n匹配所有在n天前/n天内修改过的文件。

-newer文件匹配所有修改时间比file文件更新的文件。

-sizen匹配所有大小小于n块的文件(若k在n后,则为1K字节块),1块=512字节。

-print显示整个文件路径和名称。一般来说,都要用-print,如果没有这个参数,则find命令进行所要求的搜索是没有显示结果的。

其它常用命令34通过文件名查找

#find/root-namehttpd.conf–print2)根据部分文件名查找 #find/root–name‘*http*’-print3)根据文件的特征查询

#find/etc-size+10-size12-print$find/home/-namedays-print/home/hll/prac/daysfind:‘/home/hll/.dbus’:Permissiondeniedfind:‘/home/hll/.cache/dconf’:Permissiondenied在find文件时,如果用到通配符,需要用单引号括起来。$

find/home/yyb‘e*.sh’$find/home/yyb‘e[234].sh’其他常用命令查找文件内容:grep在很多时候,并不需要列出文件的全部内容,用户要做的只是找到包含某些信息的一行。这个时候,如果使用more命令一行一行去找的话,无疑很浪费精力。当文件内容特别多的时候,这样的做法则完全不可行了。为了在文件中寻找某些信息,可以使用grep命令$grepundaysweatherdays:Sundayweather:sunny#在文件days和weather里面找有字符串un的行其他常用命令less、more和cat命令都是用于查看文本文件内容,但less的功能更为强大。less改进了cat、more命令的很多细节,并添加了许多的特性,这些特性让less看起来更像是一个文本编辑器——只是去掉了文本编辑功能。分屏查看文件内容:lessless在屏幕底部显示一个冒号“:”等待用户输入命令。如果想向下翻一页,可以按下空格键,如果想向上翻一页,按下B键。也可以用光标键向前、后、甚至左右移动。如果要在文件中搜索某一个字符串,可以使用“/”加想要查找的内容,less会把找到的第一个搜索目标高亮显示,要继续查找相同的内容,只要再次输入“/”,并按下回车键。最后,按下Q键可以退出less程序并返回Shell提示符。其他常用命令date命令可以用来显示或设定系统的日期与时间。在显示方面,使用者可以自行设定时间显示格式,格式设定为一个加号后接数个标记。若是不以加号作为开头,则表示要设定时间。时间格式为:MMDDhhmm[YYYY][.ss]。其中

MM为月份,DD为日,hh为小时,mm为分钟,YYYY为年份,ss为秒数。显示系统时间:date$date #显示系统时间TueNov1200:38:25PST2019$date111216462019.30 #设置系统完整时间TueNov1216:46:30PST2019$date-s1651 #设置系统的时、分TueNov1216:51:00PST2019其他常用命令ps命令是processstatus的缩写,用于显示当前进程的状态。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。kill命令用来终止指定的进程的运行。通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后台进程就须用kill命令来终止。显示进程命令:ps关闭进程命令:killkill[参数][进程号]$ps-ef|grepvimroot32682884016:21pts/100:00:00viminstall.logroot33702822016:21pts/000:00:00grepvim$kill3268$kill3268-bash:kill:(3268)-Nosuchprocess#连续关闭进程3268,第2次提示错误其他常用命令init是Linux系统操作中不可缺少的程序之一。init进程,它是一个由内核启动的用户级进程,然后由它来启动后面的任务,包括多用户环境,网络等。init命令很简单,直接输入init+模式对应的编号。shutdown是系统关机命令,也可以用于关闭所有程序,并依用户的需要,进行重新开机或关机的动作。shutdown命令执行后,会以广播的形式通知正在系统中工作的所有用户,系统将在指定的时间内关闭。Init命令关机命令:shutdowninit0#停机 init1#单用户模式,只root用户进行维护init2#多用户模式,不能使用NFSinit3#完全多用户模式(标准的运行级)init4#安全模式init5#切换到图形化界面init6#重新启动shutdown常用参数有:-tseconds:设定在几秒钟之后进行关机程序;-k:将警告讯息传送给所有使用者;-r:关机后重新开机;-h:关机后停机;time:设定关机的时间。其他常用命令zip命令用于压缩文件,unzip命令用于解压文件。tar是Linux环境下最常用的备份工具之一,它可用于建立、还原、查看、管理文件,也可方便的追加新文件到备份文件中,或仅更新部分的备份文件,以及解压、删除指定的文件。熟悉其常用参数,能方便日常的系统管理工作。文件压缩命令:zip打包与解包:tarwww.islide.cc41常用选项意义-A将文档与已有的文档合并-c建立新的文档-d比较文档与当前文件的不同之处--delete从文档中删除-f使用档名,请留意,在f之后要立即接档名-t列出文档中文件的目录-v压缩的过程中显示文件

-x从文档展开文件-C转到指定的目录-k保存现有文件;从文档中展开时不进行覆盖-m当从一个文档中恢复文件时,不使用新的时间标签-z用gzip

对文档压缩或解压www.islide.cc42$tar-cvftest.tar./Scripts/#将Scripts子目录下的所有文件打包成test.tar$tar-jcvftest.tar.zip2./Scripts/#将Scripts子目录下的所有文件打包并使用

bzip2压缩,得到test.tar.zip2文件$tar-jxvftest.tar.zip2-C/home/hll#将test.tar.zip2解包到/home/hll目录下$tar-tftest.tar.zip2#显示test.tar.zip2包中的文件和目录tar使用举例其他常用命令Linux提供了丰富的帮助手册,当需要查看某个命令的参数时不必到处上网查找,只要man一下即可。此外,man还可以用于查询系统库文件中的一些函数定义和使用方法。man基本用法如下:whereis命令主要用于查找程序文件,并提供这个文件的二进制可执行文件、源代码文件和使用手册页存放的位置。常用参数包括-b、-m和-s,分别对应查找二进制可执行文件、使用手册和源代码文件。此外,也可以通过-B、-M和-S等参数在指定目录下查找对应文件。获得帮助命令:man查找特定程序:whereisman[参数][命令]。 #详细的命令用法命令–help #简单的命令用法命令行高级技巧Tab键自动补齐文件名是命令中最常见的参数,然而每次完整输入文件名是一件很麻烦的事情,特别是当文件名特别长的时候。所以,bash提供了这样一种特性——命令行补全。在输入文件名的时候,只需要输入前面几个字符,然后按下Tab键,Shell会自动把文件名补全。如果以所键入的字符开头的文件不止一个,那么可以连续按下Tab键两次,Shell会以列表的形式给出所有以键入字符开头的文件。

命令行高级技巧通配符使用Shell有一套被称作通配符的专用符号,分别是*、?、[]。这些通配符可以搜索并匹配文件名的一部分,从而大大简化了命令的输入。也可以使用短线“-”来指定一个字符集范围。所有包括在上下界之间的字符都会被匹配。“*”用于匹配文件名中任意长度的字符串。和“*”类似的通配符是“?”。但和“*”匹配任意长度的字符串不同,“?”只匹配一个字符。“[]”用于匹配所有出现在方括号内的字符命令行高级技巧重定向a)输出重定向符>、>>“<<”为此处操作符,该操作符在从键盘读取内容时,读到指定的字符串时,便停止读取动作,然后将所读的内容输出。

“<”标准输入重定向符用于改变一个命令的输入源。>和>>的区别在于:>重定向符每次都是以覆盖的方式重写后面的文件内容,若指定的文件不存在,系统会自动创建。若要将内容以追加的方式添加到后面的文件中,则应采用>>重定向符。输出重定向符能实现将一个命令的输出重定向到一个文件中。b)输入重定向符<、<<

cat<<end>file.txt命令行高级技巧组合命令组合命令的基本方法是采用命令栈的形式。所谓命令栈,就是将所有需要运行的命令放到Shell的一行上,再用分号“;”隔开每个命令。接着依次顺序执行每个命令,只有一个命令结束运行(无论成功与失败)后,才会运行下一个命令。$cdEmbedded;ls-l;mkdirScript;mv*.shScript分割命令的另一个办法是用&&。它同样是依次执行每个命令,但只有当前面一条指令运行成功后,才能执行下一条指令。如果前面命令运行失败,后续命令都不会被执行。$mv*.sh..&&cd..&&rm–rfScript&&ls-l命令行高级技巧48使用“$()”可将一个命令的输出插入到另一个命令,这就是所谓的命令替换。$ls #显示当前目录内容

#无内容,空目录$mkdir$(date"+%Y-%m-%d")&&ls #创建目录并显示目录内容2019-10-20 #有一个以日期命名的目录使用“|”可以将一个命令的输出作用于另一个命令的输入。$ls-l|grepconf|less

上例中,先将ls命令的结果输入给grep命令,实现查找文件名中含conf的文件的目的;然后将grep命令的结果输入给less命令,实现分屏显示。/03Shell编程基础Shell脚本的执行Shell脚本本质上只是普通文本文件,由bash对其进行解释执行。因此,凡是可以在bash提示符后输入的命令,都可以出现在脚本文件里。Shell脚本执行有三种方法:标准方法将下列文本加到脚本文件的顶端(第一行靠左对齐):#!/bin/bash然后通过下面命令改变文件访问模式,使其成为可执行文件(这里假设脚本名为myscript):$chmod+xmyscript$./myscriptShell脚本的执行用bash命令执行脚本用source命令执行脚本对于会影响shell环境的脚本,应该交给当前的shell,即loginshell去运行。此时执行方式为“source脚本名”或“.脚本名”的方式。$sourcemyscriptbash会将它的参数视为脚本文件的名称,并予以运行。$bashmyscript

采用第3种方式,脚本中的变量会添加到当前登录用户的环境变量中。Shell脚本的输入输出输入用read命令来实现,它每次从stdin(标准输入,一般指键盘)读入一行数据,并将其存入一个变量中。具体来说,read命令用于一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数(如变量的个数),则多出的词组将被作为整体为最后一个参数接收。由printf和echo命令来实现,这两个命令的功能基本类似,都可以用于字符串或变量的输出,默认输出设备都是stdout(标准输出,一般指屏幕)。使用printf的脚本比使用echo移植性更好。在进行输出时,printf和echo最大的不同在于printf不像echo那样会自动提供一个换行符号,必须显式地将换行符号指定成“\n”。输出Shell变量变量命名Shell变量命名必须遵循如下规则:命名只能使用英语字母,数字和下划线,首字符不能以数字开头;中间不能有空格,可以使用下划线“_”;不能使用标点符号;不能使用bash里的关键字(可用help命令查看保留关键字)。Shell变量变量赋值在Shell编程中,通常情况下变量并不需要专门的定义和初始化。一个没有初始化的Shell变量被认为是一个空字符串。用户可以通过变量的赋值操作来完成变量的声明并赋予一个特定的值,也可以通过赋值语句为一个变量多次赋值,以改变其值。默认为字符串变量。在Shell中,变量的赋值使用以下语法:v_name=value。其中,v_name表示变量名,value表示将要赋给变量的值;中间的等号“=”称为赋值符号,赋值符号的左右两边不能直接跟空格,否则Shell会将其视为命令。

Shell变量变量引用当变量赋值完成之后,就需要使用变量的值。在Shell中,用户可以通过在变量名前加上“$变量名”或“${变量名}”来获取该变量的值。实际上,在前面的许多例子中,已经多次使用这个符号来获取变量的值。通常情况下,“$变量名”或“${变量名}”没有差别。但是,当在一串字符串中引用变量构成新的字符串时,建议采用“${变量名}”这种方法进行变量引用。$Str1=“Hello”$Str2=$Str1World!$Str2=${Str1}World!Shell变量除用$符号引用变量外,在Shell脚本中也经常用到其它4种引用符号,这些引用符号的作用如下表所示。假设变量x1=Windows,则下面命令执行结果如下:$echo"${x1}10"Windows10

$echo'${x1}10'${x1}10$echo\'${x1}10\''Windows10'$echo`pwd`/home/hllShell变量变量作用域与其它程序设计语言一样,Shell中的变量也分为全局变量和局部变量两种。下面分别介绍这两种变量的作用域。(1)全局变量(2)局部变量Shell编程中,全局变量可以在脚本中定义,也可以在某个函数中定义。实际上,只要不是用local关键字定义的变量,都可以视为全局变量,其作用域为从被定义的地方开始,一直到Shell脚本结束或者被显示地删除。局部变量通常仅限于某个程序段访问,例如函数内部。在Shell编程中,可以在函数内部通过local关键字来定义局部变量。另外,函数的参数也是局部变量。Shell变量www.islide.cc58#!/bin/bashfunc() #定义函数{ echo"$x" #输出变量x的值 x=10 #修改变量x的值}x=20 #在脚本中定义变量xfunc #调用函数echo"$x" #输出变量x的值1. #!/bin/bash2. func() #定义函数3. {4. echo"$x" #输出变量x的值5. localx=10 #定义局部变量x6. echo"$x" #输出变量x的值7. }8. x=20 #在脚本中定义变量x9. func #调用函数10. echo"$x" #输出变量x的值Shell变量默认变量不需要用户定义,可以直接使用的变量,包括环境变量和自动变量。(1)环境变量(2)自动变量环境变量用于用户登录系统时建立Shell运行环境,它由一系列环境变量及其值组成。运行环境包括用户Home目录、系统提示符、用户名、搜索路径等。

自动变量由Shell自动根据上下文环境确定其值,用户只能引用这些变量,不能对其值进行重新设置。Shell变量www.islide.cc60常用环境变量常用自动变量算术运算算术运算符Shell中的算术运算符主要包括加、减、乘、除、求余,以及幂运算等。下表列出了常用的基本算术运算符及其使用方法。算术运算算术运算命令虽然Shell支持算术运算,但不能直接使用上表中的符号,需要配合下面的命令才能完成算术运算。expr命令let命令语法格式:exprexpression。运算符左右要有空格语法格式:letvar=expression。运算符两边不能有空格1. #!/bin/bash2. letm=23. letn=184. echo"m=$m,n=$n"5. echo'exprm+n='`expr$m+$n`6. echo'exprn%m='`expr$n%$m`7. echo'exprm-n='`expr$m-$n`8. echo'exprm/n='`expr$m/$n`9. letx=$m+$n10. echo"letm+n=$x"11. letx=$n%$m12. echo"letn%m=$x"13. #end算术运算位运算所谓位运算,即对变量每个位进行操作。BashShell支持的位运算符如下表所示。语法格式:$[expression]或let"expression"。算术运算641. #!/bin/bash2. letm=23. letn=44. echo"m=$m,n=$n"5. echo"leftshift,n<<m="$[$n<<$m] #位运算符两边有空格6. echo"rightshift,n>>m="$[$n>>$m]7. echo"and,n&m="$[$n&$m] #位运算符两边无空格8. echo"or,n|m="$[$n|$m]9. echo"not,~n="$[~$n]条件测试条件测试的基本语法条件测试包括test命令和[]命令。条件测试的语法:testexpression或[expression]。其中,参数expression表示需要进行测试的条件表达式,可以由字符串、整数、文件名,以及各种运算符组成。在使用[expression]进行条件测试时,条件表达式与左右方括号之间都必须有一个空格。条件测试字符串测试在任何程序设计语言中,字符串都是最常见的数据类型之一。在Shell中,用户可以通过5种运算符来对字符串进行条件测试操作,如下表所示。条件测试str1="abc"str2="cba" #可以在同一行中定义两个变量echo"str1=$str1,str2=$str2"test$str1

#测试变量str1是否非空echo$? #显示上条测试命令的结果,0为真,1为假test$str1=$str2

#测试字符串相等,等号两边有空格echo$?test$str1="abc" #测试变量str1是否等于abcecho$?[-z$str1]

#测试变量str1是否为空串echo$?[-n$str1]

#测试变量str1是否为非空串echo$?条件测试整数测试整数测试的语法:testnum1opnum2或者[num1opnum2]。其中,num1和num2分别表示参与比较的两个整数,可以是常量或者变量,op表示条件运算符,常用整数测试的条件运算符如表所示。letv1=2v2=4echo"v1=$v1,v2=$v2"test$v1-eq$v2echo$?[$v1-ne$v2]echo$?test$v1-gt$v2echo$?[$v1-lt$v2]echo$?test$v1-ge$v2echo$?[$v1-le$v2]echo$?条件测试文件测试语法格式:testopfile或者[opfile]在上面的语法中,op表示文件条件测试运算符,file为测试文件名。常用的文件条件测试运算符如右表所示。$test-ee6.sh$[-re1.sh]

条件测试逻辑测试在Shell编程中,经常遇到同时判断多个条件是否成立或部分成立的情况,此时,就可以利用Shell的逻辑运算符将多个不同的条件组合起来,从而构成一个复杂的条件表达式。常用的逻辑运算符如表所示。$test"$x"-gt20-a"$x"-lt30

#判断20<x<30是否成立$[-eexam-1-a-wexam-1] #判断文件exam-1是否存在且可写/04Shell编程的控制语句条件判断语句if结构条件判断语句使用if结构来实现,其结构如下:在上面的语法中,expression通常代表测试某个条件,但是也可以是Shell命令。ifexpressionthen

statement......fiifexpression1thenstatement...elifexpressionthenstatement

...elsestatement...fi73通过if-elif-else结构,将学生的百分制成绩转换成优(≥85)、通过(60-85之间)、不通过(<60),代码如下:#!/bin/bashecho"Pleaseenterascore:" #输出提示信息readscore #读取用户输入数据if[-z"$score"] #如果用户没有输入数据,提示错误thenecho"Youenternothing.Error!"elif["$score"-lt0-o"$score"-gt100]#如果分数不在0-100,提示错误thenecho"Youenterwrongdata.Error!"elif["$score"-ge85] #如果≥85分,提示优秀thenecho"Congratulation.Thegradeisexcellent!"elif["$score"-ge60] #如果在60-85之间,提示通过thenecho"Youpassedinthistest."else

#如果小于60分,提示未通过echo"Sorry,youfailedinthistest."fi多条件判断语句2.case结构,实现多条件判断在左面的语法中,variable是一个变量,case语句会将该变量的值与value1~valueN中的每一个值相比较,如果与某个value的值相等,则执行该value所对应的一组语句。当遇到“;;”符号时,就跳出case语句,执行esac语句后面的语句。对于变量名variable,可以使用双引号,也可以不使用。每个case子句中的条件测试部分,都以右括号“)”结束。每个case子句都以一对分号“;;”作为结束符。casevariableinvalue1) statement-body-1 ;;value2) statement-body-2 ;;…valueN) statement-body-N ;;*) statement-body-N+1 ;;esac通过case结构,判断用户输入的4种字符类型,代码如下:75#!/bin/bashecho"Hitakey,thenhittheenterkey." #提示输出信息readkeypress #读取用户按下的键case"$keypress"in #case语句开始

[[:lower:]]) #小写字母,涉及了正则表达式的内容echo"Lowercaseletter.";;[[:upper:]]) #大写字母echo"Uppercaseletter.";;[0-9]) #单个数字echo"Digit.";;*) #*代表缺省条件,这里代表其他字符echo"otherletter.";;esac循环结构3.for循环结构在上面的语法中,variable称为循环变量,in后面是变量取值。do和done之间的所有的语句称为循环体,即循环结构中重复执行的语句。forvariablein{list}dostatement...doneforvariablein{start..end..step}dostatement...doneforvariablein${array[*]}dostatement...done采用for循环结构,找出数组的元素个数及最小值。77#!/bin/basharray=(1-47-82034) #Shell中,用()来定义数组letn=0forvarin${array[*]} #对数组中的每个元素doif[$n-eq0] #初始值设为数组的第一个值thenletmin=$varelseif[$var-lt$min] #如果比已知的最小值还小,保存新的最小值thenmin=$varfifiletn=n+1 #处理序号doneecho"Theminvalueinthearrayis$min."echo"Thenumberofelementsinthearrayis$n."循环结构4.while循环结构while循环结构的格式如下:在上面的语法中,expression表示while循环体执行时需要满足的条件,do和done这两个关键字之间的语句构成了循环体。当while循环结构在执行时,会首先计算expression表达式的值,如果表达式的值为0,则执行循环体中的语句;否则,退出while循环,执行done关键字后面的语句。当循环体中的语句执行完成之后,会重新计算expression的值,如果仍然是0,则继续执行下一次的循环,直至expression的值为非0。whileexpressiondostatement...done采用while循环结构,实现猜数字的游戏。79#!/bin/bashletcorrect=75n=1echo"Pleaseenteranumberbetween1and100."#提示用户输入数字readvar #读取用户输入的数字while[$var-ne$correct] #while循环开始doif[$var-lt$correct] #提示用户输入数字太小thenecho"Toosmall.Tryagain."readvarelse[$var-gt$correct] #提示用户输入数字太大

echo"Toobig.Tryagain."readvarfiletn=n+1doneecho"Congratulation!Youinputthecorrectnumber$correctin$ntimes."循环结构5.until循环结构until循环的功能是不断地重复执行循环体中的语句,直至某个条件成立。在上面的语法中,expression是一个条件表达式。当该表达式的值不为0时,将执行do和done之间的语句;当expression的值为0时,将退出until循环结构,继续执行done语句后面的其他语句。实质上,until循环结构和while循环结构的差别就在于一个是条件为假时执行循环体,一个是条件为真时执行循环体。因此,这两个循环结构可以互相转换。untilexpressiondostatement...doneuntil循环的语法格式如下:循环结构6.利用break和continue控制循环在Shell的循环结构中,break语句与continue语句的作用与C程序设计中的break与continue的作用完全一样。具体来说,break用来跳出当前循环,即结束本层循环体;continue用来结束本次循环,因而它的作用不是退出循环体,而是跳过当前循环体中该语句后面的语句,重新从循环语句开始的位置执行。此外,在默认情况下,break语句仅仅退出一层循环,如果用户想要退出多层循环,可以在break语句的后面增加一个数字作为参数,用来指定要退出的循环的层数。比较下面脚本的输出:82#!/bin/bash #!/bin/bash forxin1234 forxin1234do do

echo"hello" echo"hello"

continue

break

echo"shell" echo"shell"done done嵌入式系统原理与设计第9章Linux下程序设计工具第XX章0102030405Vi编辑器GCC编译器GDB调试Make项目管理器Makefile编程/01Vi编辑器Vi编辑器图形界面编辑器的代表是gedit文本界面编辑器的代表是Vi,它没有采用图形界面,因而运行效率很高,缺点在于需要记住众多的命令。Linux下的编辑器可以分为图形界面编辑器和文本界面编辑器。Vi的启动与退出启动:在Linux终端命令提示符下输入vi(或vi文件名),即可启动vi编辑器。#vifilename退出:要退出Vi,必须先按“Esc”键回到命令行模式,然后输入“:”,此时光标会停留在最下面一行(底行模式),再输入“q”,最后按“Enter”键即可退出。Vi工作模式Vi工作模式命令行模式:也叫做“普通模式”,它是启动Vi编辑器后的初始模式。在该模式下主要是使用隐式命令(命令不显示)来实现光标的移动、复制、粘贴、删除等操作。在该模式下,编辑器并不接受用户从键盘输入的任何字符作为文档的编辑内容。插入模式:在该模式下,用户输入的任何字符都被认为是编辑到文件中的内容,并直接显示在Vi的文本编辑区。底行模式:在该模式下,用户输入的任何字符都会在Vi的最下面一行显示,按“Enter”键后便会执行该命令(当然前提是输入的命令正确)。Vi使用实例练习参考教材中三种模式的常用命令,编辑源代码并将其命名为vi_test.c/*vi_test.c*/#include<stdio.h>intmax(inta,intb);main(){inta,b;printf("Enterab:");scanf("%d%d",&a,&b);printf("max=%d\n",max(a,b));}intmax(inta,intb){intp;p=a>b?a:b;return(p);}Vi使用实例练习在编辑完vi_test.c后完成以下操作:(1)为了方便查看代码,在Vi编辑器中显示行号(2)将第5-8行的内容复制到第8行行首(3)删除此时光标所在行(4)将源代码每行的第一个字符“i”替换成字符“n”。(5)撤销上一步操作/02GCC编译器GCC编译器GCC全称是GNUCCompiler,它是GNU组织推出的符合ANSIC标准的功能强大、性能优越的多平台编译器。经过几十年的发展,GCC已经成为Linux下最重要的免费软件开发工具,它不仅支持C语言,还支持C++语言、Java语言、Objective语言、Ada语言、Pascal语言、COBOL语言等。因此,GCC也被成为GNU编译器集合。此外,GCC还是一个交叉平台编译器GCC编译器交叉编译器:在一个CPU平台上编译另一个CPU平台的程序,这两个CPU平台的指令体系结构不一样GCC目前支持所有主流CPU平台,可以完成从C、C++、Java等源文件向运行在特定CPU硬件平台上的目标代码的转换。GCC编译器所能支持的部分源程序的格式后缀名所对应语言后缀名所对应语言.cC语言源程序.s/.S汇编语言源程序.C/.cc/.cxxC++源程序.h预处理文件(头文件).mObjective-C源程序.o目标文件.i已经经过预处理的C程序.a/.so编译后的文件.ii已经经过预处理的C++程序

GCC编译流程预处理(Pre-Processing)编译(Compiling)汇编(Assembling)链接(Linking)GCC编译流程下面以一个简单的“Hello,World”实例程序来说明,/*hello.c*/#include<stdio.h>intmain(){printf("Hello!Thisisourembeddedworld!\n");return0;}return(p);}预处理阶段预处理阶段主要完成3个功能:1)将源文件中以“#include”格式包含的文件复制到编译的源文件中;2)用实际值替换用“#define”定义的字符串;3)根据“#if”后面的条件确定实际需要编译的源代码。注:实例代码中仅需将stdio.h复制到源文件预处理阶段GCC中,“-E”选项用来指示仅做预处理,预处理结束后停止编译过程。[root@localhostgcc]#gcc–Ehello.c–ohello.i在上面命令中,选项“-o”用来指定输出的目标文件名称,“hello.i”为已经过预处理的C源程序typedefint(*__gconv_trans_fct)(struct__gconv_step*,struct__gconv_step_data*,void*,__constunsignedchar*,__constunsignedchar**,__constunsignedchar*,unsignedchar**,size_t*);…#2"hello.c"2intmain(){printf("Hello!Thisisourembeddedworld!n");return0;}编译阶段在编译阶段,GCC首先要检查经过预处理后的源代码的规范性(是否有语法错误等),检查无误后再把源代码翻译成目标CPU平台的汇编语言。[root@localhostgcc]#gcc–Shello.i–ohello.sGCC中,“-S”选项用来指示仅做编译、生成汇编代码,汇编代码生成后结束编译过程。编译阶段.file"hello.c".section.rodata.align4.LC0:.string"Hello!Thisisourembeddedworld!".text.globlmain.typemain,@functionmain:push1%ebpmovl%esp,%ebpsubl$8,%espandl$-16,%espmovl$0,%eaxaddl$15,%eaxaddl$15,%eaxshrl$4,%eaxsall$4,%eaxsubl%eax,%espsubl$12,%esppushl$.LC0callputsaddl$16,%espmovl$0,%eaxleaveret.sizemain,.-main.ident"GCC:(GNU)4.0.020050519(RedHat4.0.0-8)".section.note.GNU-stack,"",@progbits汇编阶段汇编阶段是把编译阶段生成的“.s”文件转成目标文件。GCC中,可以使用选项“-c”将汇编代码转化为以“.o”结尾的二进制目标代码。[root@localhostgcc#gcc–chello.s–ohello.o注:由于hello.o为二进制文件,不能用文本编辑器打开;如果用文本编辑器强制打开,显示为一堆乱码。链接阶段上面生成的hello.o并没有定义“printf”函数的实现,而预编译中包含进的“stdio.h”中也只有该函数的声明,无该函数的实现。那么,是在哪里实现“printf”函数的呢?通俗的讲,链接就是找到函数的实现处,也就是函数库。而函数库按时间、空间需求可分为静态库与动态库链接阶段静态库:指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件,其后缀名一般为“.a”。(“以空间换时间”)动态库:在链接时并没有把库文件的代码加入到可执行文件中,因而生成的文件比较小,但在程序执行时需要动态加载库文件的代码,其后缀名一般为“.so”。(“以时间换空间”)链接阶段在GCC中,“printf”函数实现被放到名为“libc.so.6”的库文件中,它是一个动态库。在没有特别指定时,GCC会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数“printf”,而这也就是链接的作用。GCC编译实际源程序编译过程中,不需要分步运行上述命令来生成可执行文件,可以利用下面命令一步到位,生成可执行文件hello。[root@localhostgcc]#gcc–Shello.i–ohello.s运行生成的可执行文件hello,得到运行结果:[root@localhostgcc]#./helloHello!Thisisourembeddedworld!常用的GCC编译选项选项含义-E只进行预编译,不做其他处理-c只编译不链接,生成目标文件“.o”-S只编译不汇编,生成汇编代码-ofile指定输出文件名称为file-g在可执行程序中包含标准调试信息-v打印出编译器内部编译各过程的命令行信息和编译器的版本-Idir在头文件的搜索路径列表中添加dir目录-Ldir在库文件的搜索路径列表中添加dir目录-static链接静态库-llibrary链接名为library的库文件告警和出错辅助选项选项含义-ansi支持符合ANSI标准的C程序-pedantic允许发出ANSIC标准所列的全部警告信息-pedantic-error允许发出ANSIC标准所列的全部错误信息-w关闭所有告警-Wall允许发出GCC提供的所有有用的报警信息-werror把所有的告警信息转化为错误信息,并在告警发生时终止编译过程/03Gdb调试器Gdb调试Linux下C程序开发主要用到的调试工具是Gdb调试器。Gdb是一款由GNU开发并发布的自由软件,是UNIX/Linux下的功能强大的程序调试工具。虽然,它没有图形化的友好界面,但是它强大的功能也足以与微软的VC工具等媲美。一般来说,Gdb主要提供以下功能:(1)设置断点(可以是条件表达式),使程序在指定的代码上暂停执行。(2)单步执行程序,便于调试。(3)查看程序中变量值的变化。(4)动态改变程序执行环境。(5)分析崩溃产生的core文件。Gdb的调用Gdb的使用非常简单,只要在Linux的命令提示符下输入gdb,系统便会启动Gdb,并打印出Gdb的相关信息。也可以在gdb后面给出文件名,直接指定想要测试的程序,Gdb就会自动调用这个可执行文件进行调试,命令格式如下:注:为了使Gdb正常工作,程序在编译的时候必须包含调试信息,这需要在GCC编译时加上-g或者-ggdb选项。[root@localhostGdb]#gdbGNUgdb(Ubuntu7.11.1-0ubuntu1~16.5)7.11.1Copyright(C)2016FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3orlater<http:gnu="gnu">Thisisfreesoftware:youarefreetochangeandredistributeit.ThereisNOWARRANTY,totheextentpermittedbylaw.Type"showcopying"and"showwarranty"fordetails.ThisGDBwasconfiguredas"x86_64-linux-gnu".Type"showconfiguration"forconfigurationdetails.Forbugreportinginstructions,pleasesee:<http:///software/gdb/bugs/>.FindtheGDB

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论