如何做怎么才能免root使用自己的脚本学好Shell脚本的经验总结

关于如何学习shell脚本,该怎么写_百度知道
关于如何学习shell脚本,该怎么写
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
1. Linux 脚本编写基础1.1 语法基本介绍1.1.1 开头程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh符号#!用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用/bin/sh来执行程序。当编辑好脚本时,如果要执行该脚本,还必须使其可执行。要使脚本可执行:编译 chmod +x filename 这样才能用./filename 来运行1.1.2 注释在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。1.1.3 变量在其他编程语言中您必须使用变量。在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:#!/bin/sh#对变量赋值:a=&hello world&# 现在打印变量a的内容:echo &A is:&echo $a有时候变量名很容易与其他文字混淆,比如:num=2echo &this is the $numnd&这并不会打印出&this is the 2nd&,而仅仅打印&this is the &,因为shell会去搜索变量numnd的值,但是这个变量时没有值的。可以使用花括号来告诉shell我们要打印的是num变量:num=2echo &this is the ${num}nd&这将打印: this is the 2nd1.1.4 环境变量由export关键字处理过的变量叫做环境变量。我们不对环境变量进行讨论,因为通常情况下仅仅在登录脚本中使用环境变量。1.1.5 Shell命令和流程控制在shell脚本中可以使用三类命令:1)Unix 命令:虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。常用命令语法及功能echo &some text&: 将文字内容打印在屏幕上ls: 文件列表wc –l filewc -w filewc -c file: 计算文件行数计算文件中的单词数计算文件中的字符数cp sourcefile destfile: 文件拷贝mv oldname newname : 重命名文件或移动文件rm file: 删除文件grep 'pattern' file: 在文件内搜索字符串比如:grep 'searchstring' file.txtcut -b colnum file: 指定欲显示的文件内容范围,并将它们输出到标准输出设备比如:输出每行第5个到第9个字符cut -b5-9 file.txt千万不要和cat命令混淆,这是两个完全不同的命令cat file.txt: 输出文件内容到标准输出设备(屏幕)上file somefile: 得到文件类型read var: 提示用户输入,并将输入赋值给变量sort file.txt: 对file.txt文件中的行进行排序uniq: 删除文本文件中出现的行列比如: sort file.txt | uniqexpr: 进行数学运算Example: add 2 and 3expr 2 &+& 3find: 搜索文件比如:根据文件名搜索find . -name filename -printtee: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand | tee outfilebasename file: 返回不包含路径的文件名比如: basename /bin/tux将返回 tuxdirname file: 返回文件所在路径比如:dirname /bin/tux将返回 /binhead file: 打印文本文件开头几行tail file : 打印文本文件末尾几行sed: Sed是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。该命令采用正则表达式(见参考)进行搜索。不要和shell中的通配符相混淆。比如:将linuxfocus 替换为LinuxFocus :cat text.file | sed 's/linuxfocus/LinuxFocus/' & newtext.fileawk: awk 用来从文本文件中提取字段。缺省地,字段分割符是空格,可以使用-F指定其他分割符。cat file.txt | awk -F, '{print $1 &,& $3 }'这里我们使用,作为字段分割符,同时打印第一个和第三个字段。如果该文件内容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令输出结果为:Adam Bor, IndiaKerry Miller, USA2) 概念: 管道, 重定向和 backtick这些不是系统命令,但是他们真的很重要。管道 (|) 将一个命令的输出作为另外一个命令的输入。grep &hello& file.txt | wc -l在file.txt中搜索包含有”hello”的行并计算其行数。在这里grep命令的输出作为wc命令的输入。当然您可以使用多个命令。重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。& 写入文件并覆盖旧文件&& 加到文件的尾部,保留旧文件内容。反短斜线使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。命令:find . -mtime -1 -type f -print用来查找过去24小时(-mtime –2则表示过去48小时)内修改过的文件。如果您想将所有查找到的文件打一个包,则可以使用以下脚本:#!/bin/sh# The ticks are backticks (`) not normal quotes ('):tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`3) 流程控制1.if&if& 表达式 如果条件为真则执行then后面的部分:if ....; then....elif ....; then....else....fi大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…通常用& [ ] &来表示条件测试。注意这里的空格很重要。要确保方括号的空格。[ -f &somefile& ] :判断是否是一个文件[ -x &/bin/ls& ] :判断/bin/ls是否存在并有可执行权限[ -n &$var& ] :判断$var变量是否有值[ &$a& = &$b& ] :判断$a和$b是否相等执行man test可以查看所有测试表达式可以比较和判断的类型。直接执行以下脚本:#!/bin/shif [ &$SHELL& = &/bin/bash& ]; thenecho &your login shell is the bash (bourne again shell)&elseecho &your login shell is not bash but $SHELL&fi变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。快捷操作符熟悉C语言的朋友可能会很喜欢下面的表达式:[ -f &/etc/shadow& ] && echo &This computer uses shadow passwors&这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在则打印” This computer uses shadow passwors”。同样或操作(||)在shell编程中也是可用的。这里有个例子:#!/bin/shmailfolder=/var/spool/mail/james[ -r &$mailfolder& ]' '{ echo &Can not read $mailfolder& ; exit 1; }echo &$mailfolder has mail from:&grep &^From & $mailfolder该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的&From& 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:-打印错误信息-退出程序我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。2.casecase :表达式可以用来匹配一个给定的字符串,而不是数字。case ... in...);esac让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:file lf.gz这将返回:lf.gz: gzip compressed data, deflated, original filename,last modified: Mon Aug 27 23:09:18 2001, os: Unix我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:#!/bin/shftype=`file &$1&`case &$ftype& in&$1: Zip archive&*)unzip &$1& ;;&$1: gzip compressed&*)gunzip &$1& ;;&$1: bzip2 compressed&*)bunzip2 &$1& ;;*) echo &File $1 can not be uncompressed with smartzip&;;esac您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。也就是说,当我们运行:smartzip articles.zip$1 就是字符串 articles.zip3. selsectselect 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。select var in ... ; dobreakdone.... now $var can be used ....下面是一个例子:#!/bin/shecho &What is your favourite OS?&select var in &Linux& &Gnu Hurd& &Free BSD& &Other&; dobreakdoneecho &You have selected $var&下面是该脚本运行的结果:What is your favourite OS?1) Linux2) Gnu Hurd3) Free BSD4) Other#? 1You have selected Linux4.looploop表达式:while ...; do....donewhile-loop 将运行直到表达式测试为真。will run while the expression that we test for is true.关键字&break& 用来跳出循环。而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。for-loop表达式查看一个字符串列表 (字符串用空格分隔) 然后将其赋给一个变量:for var in ....; do....done在下面的例子中,将分别打印ABC到屏幕上:#!/bin/shfor var in A B C ; doecho &var is $var&done下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息:#!/bin/sh# list a content summary of a number of RPM packages# USAGE: showrpm rpmfile1 rpmfile2 ...# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpmfor rpmpackage in $*; doif [ -r &$rpmpackage& ];thenecho &=============== $rpmpackage ==============&rpm -qi -p $rpmpackageelseecho &ERROR: cannot read file $rpmpackage&fidone这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。如果您运行showrpm openssh.rpm w3m.rpm webgrep.rpm此时 $* 包含了 3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.5. 引号在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓扩展的意思是程序会把通配符(比如*)替换成合适的文件名,它变量替换成变量值。为了防 止程序作这种替换,您可以使用引号:让我们来看一个例子,假设在当前目录下有一些文件,两个jpg文件, mail.jpg 和tux.jpg。1.2 编译SHELL脚本#ch#!/bin/sh mod +x filenamecho *.jpg ∪缓螅 梢酝ü 淙耄?./filename 来执行您的脚本。这将打印出&mail.jpg tux.jpg&的结果。引号 (单引号和双引号) 将防止这种通配符扩展:#!/bin/shecho &*.jpg&echo '*.jpg'这将打印&*.jpg& 两次。单引号更严格一些。它可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。#!/bin/shecho $SHELLecho &$SHELL&echo '$SHELL'运行结果为:/bin/bash/bin/bash$SHELL最后,还有一种防止这种扩展的方法,那就是使用转义字符——反斜杆:echo *.jpgecho $SHELL这将输出:*.jpg$SHELL6. Here documents当要将几行文字传递给一个命令时,here documents(译者注:目前还没有见到过对该词适合的翻译)一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果我们四有那个 here documents就不必用echo函数一行行输出。 一个 &Here document& 以 shift by 2--); # end of options-*) echo &error: no such option $1. -h for help&;exit 1;;*);esacdoneecho &opt_f is $opt_f&echo &opt_l is $opt_l&echo &first arg is $1&echo &2nd arg is $2&您可以这样运行该脚本:cmdparser -l hello -f -- -somefile1 somefile2返回的结果是:opt_f is 1opt_l is hellofirst arg is -somefile12nd arg is somefile2这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数.第2部分 实例现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。并且写一个伪脚本(framework.sh),该脚本包含了大多数脚本都需要的框架结构,是一个非常不错的主意。这时候,在写一个新的脚本时我们只需要执行一下copy命令:cp framework.sh myscript然后再插入自己的函数。让我们再看两个例子:二进制到十进制的转换脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子:#!/bin/sh# vim: set sw=4 ts=4 et:help(){cat &b2h -- convert binary to decimalUSAGE: b2h [-h] binarynumOPTIONS: -h help textEXAMPLE: b2h 111010will return 58HELPexit 0}error(){# print an error and exitecho &$1&exit 1}lastchar(){# return the last character of a string in $rvalif [ -z &$1& ]; then# empty stringrval=&&returnfi# wc puts some space behind the output this is why we need sed:numofchar=`echo -n &$1& | wc -c | sed 's/ //g' `# now cut out the last charrval=`echo -n &$1& | cut -b $numofchar`}chop(){# remove the last character in string and return it in $rvalif [ -z &$1& ]; then# empty stringrval=&&returnfi# wc puts some space behind the output this is why we need sed:numofchar=`echo -n &$1& | wc -c | sed 's/ //g' `if [ &$numofchar& = &1& ]; then# only one char in stringrval=&&returnfinumofcharminus1=`expr $numofchar &-& 1`# now cut all but the last char:rval=`echo -n &$1& | cut -b 0-${numofcharminus1}`}while [ -n &$1& ]; docase $1 in-h)shift 1;; # function help is called--); # end of options-*) error &error: no such option $1. -h for help&;;*);esacdone# The main programsum=0weight=1# one arg must be given:[ -z &$1& ] && helpbinnum=&$1&binnumorig=&$1&while [ -n &$binnum& ]; dolastchar &$binnum&if [ &$rval& = &1& ]; thensum=`expr &$weight& &+& &$sum&`fi# remove the last position in $binnumchop &$binnum&binnum=&$rval&weight=`expr &$weight& &*& 2`doneecho &binary $binnumorig is decimal $sum&该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..),比如二进制&10&可以这样转换成十进制:0 * 1 + 1 * 2 = 2为了得到单个的二进制数我们是用了lastchar 函数。该函数使用wc –c计算字符个数,然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。文件循环程序或许您是想将所有发出的邮件保存到一个文件中的人们中的一员,但是在过了几个月以后,这个文件可能会变得很大以至于使对该文件的访问速度变慢。下面的 脚本rotatefile可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为outmail)为outmail.1,而对于outmail.1就变成了outmail.2 等等等等...
采纳率:92%
来自团队:
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。往事不堪回首,唯有继续前行!
shell脚本学习总结
看完了书《shell脚本学习指南》,顺便总结一下:
看了整本书,全部都是命令,但也确实很难记得命令的选项,所以学习方法就变了。
学习嘛,要考虑到遗忘的可能,既然会忘,还不如不去记,能做的就是但用到的时候再去学,那么现在学习的目的就是为了缩短以后用到时再去学习的学习时间,所以现在所应该学的,是将书本上的命令记住,选项则查手册页(man),也需要记住一些常用的选项,现在要做的就是熟悉手册页,懂得标准化,命令是在不断升级的,手册页才是包含了最全部的命令的参考,没人会规定你在linux系统行输入命令行时,不准查看手册页,不过看英文确实是件痛苦的事。第二,就是猜测,比如在使用过程中,碰到一个应用,好像没学过,这是要猜测其最可能会作为哪条命令的选项出现的,然后去查对应的手册,学完shell脚本这本书,最多也就熟悉这些命令的大概50%的选项,其他不熟悉的选项肯定要猜测和查手册的。
每个人的记忆力有所不同,最少应该记住每个命令是做什么的,最大是记住命令的每个选项。
学完shell脚本要将shell脚本当做一个程序来看到,而不仅仅只是一个脚本,作为程序是可以被进程内exec函数族调用执行的,这样脚本和C语言就互通了,可以相互调用。
shell脚本作为程序,要有完备的选项处理机制(case,getopts),信号处理机制(trap),输入和输出接口(read,printf),shell的执行环境(环境变量处理),shell的安全性考虑。
进行全局性的考虑之后,才能进入具体的内部设计。
shell内部最难理解的,也最容易让人犯错的,应该是引用,双引号引用,单引号引用,不带引号的引用,搞清楚shell的内部执行机理还是非常重要的
理解清楚此图,就算理解shell的运行机理了,双引号内部只做变量替换、命令替换、算术表达式替换,单引号内部则什么也不做,不带引号的还要进行token分割,波浪号展开,通配符展开,看到这个图就应该能明白awk的程序部分为什么加单引号了,sed的命令部分为什么加单引号了,为什么有些命令要加eval重新执行一遍了。
另外,碰到不懂shell内部执行情况的,可以使用trace类(strace)的命令跟踪一下系统调用:strace -f sh 这样启动一个shell,在此shell内执行你不理解的命令,并跟踪子进程的所有系统调用的执行情况,这个碰到问题时的一个解决办法。
sort,sed,awk,find,正则,这几个是必须要熟练使用的,尤其是awk中的关联数组,就是散列表,C++中的关联对象,处理字符串是极其方便的。
最后,我不得不说,shell的启动,会调用两个脚本文件:
test -r /etc/profile
/etc/profile
test -r $HOME/.profile
. $HOME/.profile
我在工作中就碰到过需要定制不同的shell启动情况的,可以修改$HOME/.profile
没有更多推荐了,Bash&Shell脚本学习小结
简介: 今天写一个自动打包 gentoo 编译出的 package 的脚本,发现不会遍历处理所有输入参数, google
到了这个文章,总结的很不错。
今天需要写一个Shell脚本。很简单,判断一个日志文件是否大大于2G,如果大于2G则删除。久了没有写bash,竟然一点都想不起来写了。于是复习了一下,下面对今天的学习做个小结:
1.字符截断:
如果是一般路径的字符截断可以用basename和dirname这两个工具:
basename可以从一个文件路径中截一个文件名
$&basename&/home/file.tar
dirname可以从一个文件路径中截到一个目录路径
$&dirname&/home/file.tar
不使用外部工具进行字符截断
bash有自带的功能来对变量进行字符截断,一般使用"##", "#", "%%", "%", "*" 组合来实现。例如:
$&string=hellowbashshell
$&echo&${string##*sh}
$&echo&${string#*sh}
$&echo&${string%%sh*}
$&echo&${string%sh*}
hellowbash
"#"表示从字符开始部分除去,一旦匹配则立即除去
"##"表示从字符开始部分除去,会搜整个字符串最长的和的匹配来除去
"%"表示从字符结束的部分除去,一旦匹配成公则立即除去
"%%"表示从字符结束的部分开始除去,会搜寻整个字符穿中最长的匹配来除去
"*"统配符,一般与“##”或"#"联用时放在搜索字符串的左边,例如:${String#*sh}(在sh的左边),与"%%"或"%"联用时会放在匹配字符串的右边,例如:${String%%sh*}
常用技巧:
在路径中取文件名:${path##*/}(与basename相同功能)
在路径中取目录路径:${path%/*}(与dirname相同功能)
取文件的扩展名:${path##*.}
2.自变量的接收
接收来自命令行传入的参数,第一个参数用$1表示,第二个参数$2表示,。。。以此类推。注意:$0表示脚本文件名。另外一个在shell编程中经常用到的是“$@”这个代表所有的参数,。你可以用一个循环来遍历这个参数。如果用java来类比的话,可以把$@看作是man函数中定义的那个数组
if&[&condition&]
&&&&action
de&注意:“if”和“[”之间需要空格,如果你不空格,shell会报告语法错误的。我就被这个浪费了好一阵时间
conditon测试类型对照表
文件比较运算符
-e filename
如果 filename存在,则为真
[ -e /var/log/syslog ]
-d filename
如果 filename为目录,则为真
[ -d /tmp/mydir ]
-f filename
如果 filename为常规文件,则为真
[ -f /usr/bin/grep ]
-L filename
如果 filename为符号链接,则为真
[ -L /usr/bin/grep ]
-r filename
如果 filename可读,则为真
[ -r /var/log/syslog ]
-w filename
如果 filename可写,则为真
[ -w /var/mytmp.txt ]
-x filename
如果 filename可执行,则为真
[ -L /usr/bin/grep ]
filename1-nt filename2
如果 filename1比 filename2新,则为真
[ /tmp/install/etc/services -nt /etc/services ]
filename1-ot filename2
如果 filename1比 filename2旧,则为真
[ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
如果 string长度为零,则为真
[ -z "$myvar" ]
如果 string长度非零,则为真
[ -n "$myvar" ]
string1= string2
如果 string1与 string2相同,则为真
[ "$myvar" = "one two three" ]
string1!= string2
如果 string1与 string2不同,则为真
[ "$myvar" != "one two three" ]
算术比较运算符
num1-eq num2
[ 3 -eq $mynum ]
num1-ne num2
[ 3 -ne $mynum ]
num1-lt num2
[ 3 -lt $mynum ]
num1-le num2
小于或等于
[ 3 -le $mynum ]
num1-gt num2
[ 3 -gt $mynum ]
num1-ge num2
大于或等于
[ 3 -ge $mynum ]
感觉bash 中的if相比其他的一些语言智能多了,在bash中,测试一个文件的存在跟比较两个数字的大小没有什么两样 ;)
4.for语句bash里的语句总是那么的人性化,十分的接近自然语言,在for语句中几乎可以迭代任何类似与集合的数据类型(或许这样个说法不对,但我确实想不到更好的词来代替)。
看一个例子:
#!/bin/bashfor&args&in&$@
&&&&&&&&echo&$args
把上面这段代码录入保存为showargs.sh设置为可执行(chmod +x showargs.sh)执行:
$&./showargs.sh&arg1&arg2&arg3&arg4
这个例子中,我们用到了之“$@”,它代表了所有的命令行参数。在这里用for对其进行遍历,系统迭代地从$@中取出命令行参数把他放到args中,最后使用echo
$args进行输出。
for更经常用到的是遍历目录,下面的例子用于列出当前目录下的所有文件和文件夹的名称
$&for&file&in&*
&&do&&echo&$file&&done
这里用*代表当前目录,列出的是所有的文件和文件夹的名称,在这里,文件夹和文件你是分不出来的,如果你需要,你应该用if [-d
${file}]来做一下判断。
对于文件遍历,更有趣的是,你可以在 “in” 后面接上多个表达式。也就是说,你可以一次在遍历多个目录。
下面这段代码能把当前目录下go文件夹和do文件夹里的文件复制到fo文件夹下
#!/bin/bashfor&args&in&./go/*&./do/*
&&cp&${args}&./fo
&&echo&"copying&${args}&to&./fo/${args}"
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。学习shell编程方向心得
忙于各种杂事一年多没发文章,先发感慨:来现在公司一年,之前有底层C基础,一点点shell命令(基本很low的ls和rm)外加半吊子 C++ C#还有一两天的bat、vbs脚本基础就开始倒腾shell,一年下来,居然还似模似样的开始倒腾起架构,嗯,可以写写粗浅跟各位share
首先,接触过shell都知道,shell语言极难说学到很精通,当然也可能我处于层级很浅,经过很长你可能只掌握了一些命令,而已,其实放开来说,我现在这个层级;有一些东西你可能觉得特别难,比如grep ,比如awk ,比如fifo,比如管道,比如一些莫名其妙调不通的暗坑,来,梳理梳理方向
1、基本命令,别告诉我你不知道那些基本(文件文件夹类操作、chmod wget host netstat等等),需要弄懂深入一点,比如某些参数 wget -P -O echo -e -n等等
2、基本语法,if for while等等,别告诉我不知道怎么学,百度会帮你
3、高级命令:grep awk等等顺便加个正则,其实也是基础,处理文件字符串类,大大的
4、不断的用用,基本的使用环境,围绕一堆c++编译而成的bin做调用
5、写函数,这是面对过程的函数化的思路,至少复用能减少一些代码写入
6、注意异常,在写的函数化的东西基础上加一些异常处理,考虑够不够全面,可以high level的大牛给你review下代码,果断会受益匪浅
7、注意框架化,你会发现框架化之后很多代码都会很好看
其他命令什么的基础我就懒得提醒了
学习shell心得
shell编程心得体会
shell编程其实真的很简单(三)
Linux-3 shell编程总结及感悟
Linux Shell编程学习笔记一:shell简介
熟悉学习shell编程
shell编程心得
Shell编程入门总结(二)
shell 学习心得之awk篇
linux shell 学习心得
没有更多推荐了,【Linux】Shell脚本学习总结篇
【Linux】Shell脚本学习总结篇
shell学习分为下面3个部分:
shell基本命令回顾
shell基本语法学习
awk/sed 工具学习
关于shell的介绍之类的在这里不做赘述!
shell基本命令回顾
1.1 最基础的常用命令
(注:命令选项直接 man 查看,不做说明)
1.1.1 查看文件和目录的命令
ls : 列出目录下的清单;
cat: 连接显示文件内容
less/more: 分页显示文件内容,建议使用less,相比于more更方便;
head: 显示文件头部,可指定行数,默认显示10行;
tail: 显示文件尾部,可指定行数,默认显示10行;
file: 显示文件类型;
wc: 查看文件或统计信息;
find: 查找文件或目录(选项比较多,前面有博客专门介绍过)
部分演示:
1.1.2 操作文件和目录
touch:创建新文件(可以直接使用vim/vi/gredit等编辑器直接创建)
mkdir:创建目录,可以利用 -r选项递归创建
cp: 拷贝命令,拷贝目录时可以使用 -r 选项
ln: 创建链接命令,分为软连接和硬链接(有专门的文章介绍)
mv: 移动文件或者目录的命令,同时也是改名命令
rm: 删除命令,-r 删除目录, 谨慎使用;
1.1.3 管理文件或者目录的权限
ls -l : 可以列出文件和目录的权限信息;
chmod: 修改文件和目录的权限(需要了解字母及数字权限表示)
chown/chgrp: 改变属组和属主
setuid/setgid:设置用户或组权限位;
1.1.4 文本处理命令
sort : 文本排序
uniq : 文本去重
tr : 替换命令
grep : 查找字符串
diff: 文件对比,找出文件差异
部分演示:
解释: history 命令列出用户的历史使用命令,然后通过awk 过滤出第二列,因为第一列是文件的行数标号, 接着进行一个sort排序,将所有相同的命令都放在一起方便接下来的uniq -c命令去重并且统计出每个命令出现的次数,再然后是 sort -nr
-n选项的意思是按照数字的大小即uniq统计出的次数进行排序 -r 则是反向的意思,即本来是正序变为逆序;然后取其前十,即最常用的前十个命令,最后用一下 tr
命令将小写字母替换为大写字母;
对于命令的选项,我一贯的思想都是记住命令和常用的选项即可,太多的选项不需要强行去记忆,用的时候 man
看一下即可;
1.1.5 其它常用的命令
hostname : 查看主机名
w, who : 列出系统登录的用户
uptime : 查看系统运行时间
uname : 查看系统信息
date : 显示和设置系统日期和时间
: 显示用户属性
shell命令进阶
paster : 合并文本
dd : 备份和拷贝文件(和vim 和剪切命令一样)
tar : 打包和解包文件
mount, umount : 挂载和卸载存储介质
df : 报告文件系统磁盘空间利用率
du : 评估文件空间利用率
ps : 查看系统的进程
pidof : 列出进程的pid
top : 相当于 Linux 的任务管理器
& : 将作业后台运行
jobs : 查看作业
bg : 让挂起的进程在后台继续执行
fg : 将后台进程放入前台
fdisk: 查看系统的磁盘信息
部分演示:
前后台切换演示:
解释: 先执行 sleep 100 &
让这个进程在后台执行,然后我们先使用 ps 配合 grep
命令查看一下 sleep 进程的信息,接着 jobs 查看一下后台运行的作业, 使用 fg
命令使其继续在前台执行,我们可以看到显示了sleep 100 , 接着我们又不想让他继续执行了,使用 ctrl + z 使其挂起,我们用jobs查看,可以看出其处于 stopped 状态,接着使用 bg 命令使其继续在后台执行,查看状态, 处于running状态;
至此,shell的基本命令回顾完毕,这些都是脚本中常用的命令;
shell基本语法学习
这部分学习编写shell脚本的基本语法,估计篇幅比较长,因为要敲很多代码,所以,有瑕疵的地方请指出;
2.1 shell 语法篇
(这是回顾与复习的过程,所以不是小白教程,起码都吃过猪肉,看过猪跑)
2.1.1 shell 编程基础
上面刚说过,得吃过猪肉,看过猪跑,那么最基本的shell脚本的编写格式应该知道;
#!/bin/bash
echo "hello world"
分析:还是 hello world 起步,第一行的 #!叫做 Shebang(我也不知道为什么这么叫), 然后后面的 /bin/bash
则是指定解释器,既然shell是门解释性语言,自然需要解释器,类似的,如果是 python脚本,则是 #! /bin/python
可能还需要一些编码格式的规定(utf - 8),如果没有指定解释器,默认选择 sh ;
同时还需要给文件可执行权限,否则会报错,虽然我们一般把shell 脚本文件命名为 .sh 的文件(在Linux中文件后缀只能起到标识的作用,没有实际意义);
shell 中的注释,在shell中注释的符号是 “#”;
shell 的变量
在shell中设置变量和平时在命令行设置变量是一样的,可以直接定义一个变量,例如: a=10
不需要声明类型,不需要分号;
如果需要明确指定变量的类型的话,可以只用declare的选项指定类型;
变量的作用域: 在shell 中,变量默认都具有全局属性,如果需要局部的变量则需要在变量的声明处加 local 关键字。如: local
变量的操作:
3.1 获取变量的值
在命令行获取变量的值是通过 echo ${a}
打印变量的值到终端的,那么echo的作用是打印,'${}' 的作用不言而喻(花括号可省略,起分割的作用)。
3.2 变量的运算
即使用 let 命令,当然除了 let 命令还有 '(())' 双括号,都可以进行变量的运算;
3.3 参数变量
说到shell的参数,有两个点,一个是命令行参数,一个是函数的参数,这里先说明命令行参数,函数的参数在后面学习函数的时候补充;
首先,记住这几个特殊符号: $# $@ $* $1 $2 ...
在运行程序的时候,经常需要带一些初始的参数,那么这些命令行参数到底是怎么传递进来的呢?
$# : 除$0以外的参数的个数(文件名,命令除外,它们用$0查看);
$@/*: 表示所有参数的集合
$0,1,2...: 表示参数
注:取消变量的定义 unset
这里既然说到了变量,就顺带提一下环境变量和普通变量;
shell环境变量和普通变量
首先,明确两点,第一点即环境变量和普通变量在虚拟地址空间的存放位置,环境变量在栈顶的位置(高地址处),而普通变量是在数据段存放的;第二点,子进程会继承父进程的环境变量;
普通变量的命令行声明: a=10
将普通变量变为环境变量:export a
如何验证?
在父bash 中声明变量 a=10, 命令行敲 'bash' 命令相当于起了一个子bash, 在子 bash 中查找是否有 a变量;
(set 命令查看所有变量, env 命令查看所有环境变量,exit或者ctrl + d 退出子bash)
在父bash 中将变量 a 声明为环境变量 'export a', 在子bash 中查看变量
shell 的条件执行
shell的条件执行其实和C差不多,具体的差异就在于语法格式的一些差别;
1& if 条件执行
不同于C的是,bash的条件测试不单单只是可以通过if进行判断,还要结合一些特殊的符号,命令和参数;
先列出基本的if语句的使用格式:
echo "hello world!"
echo "see you world!"
:这就是 if 语句的基本使用格式,当然,中间还可以有 ’ elif ’ 相当于 C 的
值得注意的是开始的 then
和 最后的 fi , 每个 if 都必须有一个fi 与之对应代表结束,因为没有了 ’ {} ‘;
前面说了,shell的条件判断需要结合一些命令,符号,选项来配合使用;
2.1 '[]' 和 test
'[]' 和 test 都被用作测试,如:
if [ -f install.log ]
echo "hello"
test -f install. echo "hello"
和 test 有很多选项,这里我就不一一演示,需要的话直接
( 注意: 使用 ‘[ ]’ 时, 需要两个空格,‘[’的后面, ‘]’的前面各一个);
不但这些,还有比较的符号;其中又分字符串和算数的不同;
(注: $? 查看上一条命令的返回值 )
追加一个知识点: 因为字符串的比较使用 ‘[]’ 时需要对 &&进行转义,所以shell提供 ’ [[ ]] ’ 符号,则不再需要转义,对于算术,shell提供 ’ (( )) ’
则可以直接使用比较符进行比较(这在后面的例子中有体现);
&& : &&符号的前面的表达式为真才会执行 &&后面的表达式;
|| : || 符号前面的表达式为假才会执行 || 后面的表达式;
'!': 逻辑非
通常 && 和 || 配合使用,如:
的 case 语句
shell的case语句的格式如下:
case $1 in
上面就是case语句的格式,这里刚好提醒一点,就是在shell中,不允许出现空语句,如果非要有空语句,则必须写上一个 冒号 ’ : ‘;
2.1.5 Bash 循环
shell的循环:for/while/until
下面只演示前两种,until不太用到;
for i in $(seq 10)
echo -n $i
for (( i=0; i&10; ++i ))
echo -n $i
注: seq 是生成连续序列的命令,而shell中执行命令的话,会用 ’ $() ‘;
echo -n 选项则是取消换行,每个echo语句都会带一个换行,直接一个echo则代表换行;
值得一提的是break和continue关键字在shell中依然有效;
while true
if [ $i -gt 2 ];then
continue语句不做演示;
2.1.6 shell的函数
首先,shell函数的定义:
if [ $# -ne 2 ];then
local a=$1
local b=$2
let c = a + b
echo "hello $c"
if [ $? -ne 0 ];then
echo "arguments fault!"
echo "used right"
上面就是一个简单的脚本,起作用是调用一个fun函数,判断调用是否正确;
分析: 从这个脚本中我们可以看出shell脚本函数的使用方式,从定义到参数的获取,再到返回值;最后还有函数的调用方式其实和命令的执行方式是一样的;
(注: function关键字可以省略但不建议,return 可以返回的值是 0-255)
额外知识点:在shell脚本中 双引号 和 单引号是有区别的,虽然在大部分场景中它们是一致的,但是如果含有特殊字符的话,双引号是没有对特殊字符进行转义的,所以上面的脚本中 “hello
$c”可以顺利执行,但是单引号的话默认会对特殊字符转义的,例如:
(注:shell函数对于参数的处理还有 shift 和 getopts 的处理方法,后期补充)
2.1.7 shell 重定向
说起重定向,估计不少同学都想到了管道;
但是,管道并不是重定向,重定向是将一个命令的输出结果作为下一个命令的输入,而重定向是将输出和文件相链接的;
重定向分为输入重定向和输出重定向,其中又有追加和覆盖的区别,总的来说就是下面四个符号:
’ & ‘, ’ && ‘,
, ’ & ‘;
举例来说:
当然,不仅可以这样,还可以将标准错误也重定向到文件;
ls l 2&test.sh
输入重定向:
例如: tr a-z
注: 这里的END不是固定的,只是起一个标签的作用,代表下次遇到END就结束输入;
重定向的这种用法还被用到项目中的configure文件,使configure文件可以自动生成Makefile文件,例如:
2.1.8 shell 脚本从标准输入读取
这个其实只是一个read的使用,在shell中使用read从标准输入读取数据;
当然,read还有很多其他的使用方法,这里就不列了;
shell的基本语法复习到这,写的比较粗,中间还有一些遗漏,以后会更完善!
工具的简单使用
sed 的背景我就不在这百科了,直接上手一些sed工具的基本使用规则,和一些简单的例子即可,不管是sed和awk工具在以后的工作中都肯定是常用的工具,但是,作为大学的学生,想熟练使用这两个工具估计得下挺大功夫,毕竟不常用;
所以我也只学习了一些简单的用法;
sed 是一个文本处理工具,它为我们提供了很多的方便,刚开始知道sed这个工具的时候,其实挺害怕,觉得好复杂,估计用不了,而且在尝试了几次之后发现过几天就忘了,也就不了了之,这很正常,因为这些工具的使用就是唯手熟尔;现在只要了解它就够了;
学习sed和awk工具还有一个前提就是正则表达式的学习,这也是很多同学望而却步的原因,这里我就不对正则表达式进行百科了,不会就查,用的时间长了就记住了;
()sed的工作方式
sed是一行一行处理文本的,还有需要知道sed有一个HOLD空间和模式空间,HOLD用来作为文档处理的暂存空间,不能有任何的操作,所有的操作只能在模式空间进行;
sed常用的选项:
-e: 它告诉sed将下一个参数解释为sed指令,即需要连续多个处理时使用;
-f : 指定由sed指令组成的脚本的名称;
-i : 直接在读取的内容进行修改,如果没有—i,不会源文件造成任何修改;
-n: 静默模式,即只输出匹配的行,如果没有-n则匹配行会和源文件全部输出;
现在先不做演示,等把下面的编辑命令也复习完毕,一块做演示;
sed的编辑命令有24个之多,在这里只学习常用的几个:
追加(a),更改(c),删除(d),插入(i),替换(s),打印(l),打印行号(=),转换(y);
部分演示:
这些小的编辑命令多练习一下就熟悉了,接下来练习一个模式空间和HOLD空间的切换的例子,结束sed的复习;
下面这些选项则是需要用到暂存空间时要用到的选项:
+ g:[address[,address]]g 将hold space中的内容拷?贝到pattern space中,原来pattern space?里的内容清除
+ G:[address[,address]]G 将hold space中的内容append到pattern space\n后
+ h:[address[,address]]h 将pattern space中的内容拷?贝到hold space中,原来的hold space?里的内容被清除
+ H:[address[,address]]H 将pattern space中的内容append
hold space\n后
+ d:[address[,address]]d 删除pattern中的所有?行,并读?入下?一新?行到pattern中
+ D:[address[,address]]D 删除multiline pattern中的第?一?行,不读?入下?一?行
+ N,添加下一行至pattern space内;
+ x:交换保持空间和模式空间的内容
求1~100的和
两种方式:
分析:第一个例子利用了暂存空间和模式空间的特点进行求和,其中 $ 代表最后一行; ‘^’ 代表第一行; 然后利用选项H 和
其中利用sed的s编辑命令和正则表达式把换行换为加号,最后通过管道把表达式交给bc计算器,得到最终结果;
第二个例子则是利用sed的标签,没有用到暂存空间; 其中 :a是设置了一个 a标签, ba的作用是跳转到a标签;
感觉这种工具只有自己去实践了才能领会,反正我是写的晕晕的;
awk工具的简单使用
awk可是厉害了,awk严格说也是一门语言,语法很多,也很强大,在这里我只学了个皮毛,也就只负责皮毛的这块了;
既然有了sed为什么还要有awk呢?
肯定是因为awk比sed更加强大,就最明显的一点,sed只能一行一行处理数据,不能处理一列一列的数据,而awk就可以做到,而且awk还可以利用类C的语法结构,简直强大,可是我用的还是不熟;
关于awk的使用,在前面复习shell语法的时候其实都用到了,就是找出你在Linux上最常用的十个命令:
history | awk '{print $1}' | sort | uniq -c | sort -nr |head
awk 的默认的列分割符是空格,我们也可以指定分割符,利用 -F选项;
awk 还有一个特点就是它的 BEGIN 块和 END 块;
BEGIN块的作用是在awk执行匹配之前先执行的语句,END自然就是awk处理完之后执行的语句;
awk和sed简单的使用就写到这了,感觉烂尾了,写的好累写不下去了,也是这俩个工具要掌握的话需要很多篇幅的,总之就这样了,下一篇,mysql数据库的学习!
Shell脚本学习(三)注释的用法
Shell编程总结及感悟
shell脚本总结
shell脚本归纳总结(一)
《Shell脚本学习指南》学习笔记
【Linux基础】为什么要学shell
linux下shell脚本学习
Shell脚本初步学习-鸟哥Linux私房菜基础学习篇
linux _shell学习
没有更多推荐了,

我要回帖

更多关于 简述怎样才能写好总结 的文章

 

随机推荐