Linux shell的使用和几个常见的实例解析
本文由发表于6年前 | 操作系统 | 评论数 3 |  被围观 10,533 views+

如果对实例中涉及的相关Linux命令不了解,可以参考:Linux下sed,awk,grep,cut,find等常用命令介绍
什么是shell

文字操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理你与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。shell提供了你与操作系统之间通讯的方式。这种通讯可以以交互方式(从键盘输入,并且可以立即得到响应),或者以shell script(非交互)方式执行。shell script是放在文件中的一串shell和操作系统命令,它们可以被重复使用。本质上,shell script是命令行命令简单的组合到一个文件里面。Shell基本上是一个命令解释器,类似于DOS下的command.com。它接收用户命令(如ls等),然后调用相应的应用程序。较为通用的shell有标准的Bourne shell (sh)和C shell (csh)。

 

 

编写一个名为nf的程序,显示当前目录中的文件数。键入程序并测试


解决方法:

ls | awk '{files++} END {print files}'

相关解释:

使用ls把当前目录下的所有文件信息送入管道,使用awk进行累加计算文件个数。

 

 

编写一个名为whos的程序,显示排好序的已登录用户清单。只显示用户名,不要有其他信息。键入程序并测试。


解决方法:

who | sort -nrk1 | awk '{print $1}'


关于who命令:

who命令主要用于查看当前在线上的用户情况。这个命令非常有用。如果用户想和其他用户建立即使通讯,比如使用talk命令,那么首先要确定的就是该用户确实在线上,不然talk进程就无法建立起来。


关于sort命令

Sort命令的功能是对文件中的各行进行排序。Sort命令有许多非常实用的选项,这些选项最初是用来对数据库格式的文件内容进行各种排序操作的。实际上,Sort命令可以被认为是一个非常强大的数据管理工具,用来管理内容类似数据库记录的文件。
-n按照数字方式排序。不加-n参数时排序结果根据最左面的数字开始,等同于字母的比较方式。按算术值对数字字段排序。数字字段可包含前导空格、可选减号、十进制数字、千分位分隔符和可选基数符。对包含任何非数字字符的字段进行数字排序会出现无法预知的结果。

-r 颠倒指定排序的顺序。
-k作用是根据某个列来排序,默认是第1列(从1开始)。
-t表示分割符,以:分割,默认情况下以空格分割
-nrk 5即是按照数字方式倒序排序,根据文件属性的第5列即是文件大小排序


相关解释:

使用who吧当前在线用户情况送入管道,然后使用sort进行排序, -k1表示按照第一列即是用户名来排序。然后使用awk处理输出$1。$1即是使用制表符或者空格作为分隔符分隔用户信息得到的第一个字段,即是用户名(全字段对应为$0)。

 

 

在终端上显示  <<< echo $x >>> displays the value of x,which is $x
显示的时候,第2个$x的值应该被替换,比如如果x=3,显示:  <<< echo $x >>> displays the value of x,which is 3


解决方法:

x=3
echo "<<< echo \$x >>> displays the value of x,which is $x"


关于shell编程中特殊字符$的含义:

$#表示脚本所带的参数数量
$0表示脚本名称,如./hello.sh
$1表示第一个参数
$2表示第二个参数,并依次类推
$a表示取得变量a的值
$?上一个语句的执行结果值,如使用exit等语句
$* 传递给shell script的参数

相关解析:
$x表示取得变量x的值 。

 

依次执行下面三条命令,分析结果。
filename=/home/arthinking/express
filename=$(echo $filename | tr “$(echo $filename | cut –c1)” “^”)
echo filename


解决方法:

输出为 filename


关于tr命令:

通过使用 tr,可以非常容易地实现 sed 的许多最基本功能。可以将 tr 看作为 sed 的(极其)简化的变体。使用tr命令可以用一个字符来替换另一个字符,或者可以完全除去一些字符,也可以用它来除去重复字符。

tr的命令格式为:

tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] < input-file

-c
用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d
删除字符串1中所有输入字符。
-s
删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
string1_to_translate_from
要转换的原字符串
string2_to_translate_to
想要转换成的字符串


关于cut命令:

cut命令可以从一个文本文件或者文本流中提取文本列,具体的说就是在文件中负责剪切数据用的。cut是以每一行为一个处理对象的,这种机制和sed是一样的。

cut -d'分隔字元' -f fields

参数∶
-d ∶后面接分隔字元。与 -f 一起使用;
-f ∶依据 -d 的分隔字元将一段讯息分割成为数段,用 -f 取出第几段的意思;
-c ∶以字元 (characters) 的单位取出固定字元区间,c1表示取出第一个字符。


相关解释:

首先filename=/home/arthinking/express是给变量赋初值
filename=$(echo $filename | tr “$(echo $filename | cut –c1)” “^”)
这句中c1表示取出第一个字符,即是”/”
tr “$(echo $filename | cut –c1)” “^”即是把”/”转换成”^”
echo filename中的filename是一个字符串,并不是变量,所以这里只能输出filename
如果使用echo $filename则输出 ^home^arthinking^express

 

 

shell编程里的$(…)结构是什么作用,举例说明。

作用:把一个命令的标准输出插入在一个命令行中任何位置
例如:上一个实例中的 $(echo $filename | cut –c1)

 

 

编写一脚本,打印出所有的参数。


解决方法:

创建一个文件test,在里面编写如下命令:
echo the following parameters below are transmitted: $*
在终端进入rename所在的目录,运行./test 12 23 34


相关解释:

$* 传递给shell script的参数

 

 

编写一个脚本,统计参数的总数。


解决方法:

echo statistics: $# parameters passed


相关解释:

$# 表示传递给shell script的参数个数

 

 

编写一个名为rename的程序,给第1个参数所给定的文件更名,在原名后添加第2个参数包含的一串字符。即
rename memol .sv
应该将文件memol更名为memol.sv


解决方法:

创建一个rename的文件,在里面编写:
mv $1 $1$2
在终端进入rename所在的目录,运行./rename a   .txt
	其中a为需要修改的文件名


关于mv命令:

mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中。该命令等同于DOS系统下的ren和move命令的组合。它的使用权限是所有用户。本例中是使用该命令进行修改文件名

mv [options] 源文件或目录 目标文件或目录。本例中对应为源文件名,目标文件名。


相关解释:

mv $1 $1$2,中$1对应第一个参数,$2对应第二个参数,即是把$1对应的文件名更改为由$1$2组成的文件名

 

 

编写一个名为unrename的程序,从第1个参数指定的文件名的后部去掉第2个参数包含的字符串,即
unrename memol.sv .sv
应该把文件memol.sv更名为memol。要保证从尾部去掉字 符串,如
unrename test1test test
应该将tes1test更名为test1(提示:用sed和命令替换)


解决方法:

mv $1 $(echo $1 | sed "s/$2$//")


相关解释:

修改文件名命令mv中的参数$1为需要的文件名,$(echo $1 | sed "s/$2$//")为想要修改的格式。其中$(echo $1 | sed "s/$2$//")表示把$1中的变量送入管道,使用sed的替换功能s/re/string将$1中匹配到$2$($2$表示匹配第二个域的内容直到结尾的)替换为空,即是去掉。

 

 

编写名为valid 的程序,如果参数是合法的shell 变量名,则显示“yes”,否则显示“no”。


解决方法:

创建一个名为valid的文件,在其中编写:
if echo "$1" | grep -q '^[a-zA-Z_][a-zA-Z_0-9]*$'
then
    echo "yes"
else
    echo "no"
fi


关于shell脚本的if语句格式:

if 条件测试命令
then
命令序列
fi


相关解释:

把$1送入管道,使用grep匹配判断,其中-q表示取消显示,只返回退出状态,即是不输出。^[_a-zA-Z][_a-zA-Z0-9]*$表示匹配以字母开头并以字母或者数字结尾。

 

 

编写一个shell脚本,使用循环语句将当前目录下的.c文件更名为.cpp。


解决方法:

for loop in $(ls)
do
    if echo "$loop" | grep -q '\.c'
    then
        mv $loop $(echo $loop | sed "s/\.c$/\.cpp/")
    fi
done


关于shell脚本的for循环语句格式:

for循环语句格式如下:
for 变量名 in 取值列表
do
命令列表
done


相关解释:

for loop in $(ls)表示变量loop从ls命令得到的列表中取值。
if echo "$loop" | grep -q '\.c'中-q表示取消显示,整句表示判断是否找到以.c结尾的文件,找到则执行then里面的语句。
mv $loop $(echo $loop|sed "s/\.c$/\.cpp/")表示把.c换成.cpp

 

 

source命令和exec命令有什么区别?举例说明。

shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行。

因 此,如果你在一个shell里面,执行exec ls那么,当列出了当前目录后,这个shell就自己退出了,因为这个shell进程已被替换为仅仅执行ls命令的一个进程,执行结束自然也就退出了。为 了避免这个影响我们的使用,一般将exec命令放到一个shell脚本里面,用主脚本调用这个脚本,调用点处可以用bash a.sh,(a.sh就是存放该命令的脚本),这样会为a.sh建立一个sub shell去执行,当执行到exec后,该子脚本进程就被替换成了相应的exec的命令。

source命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。

 

 

将当前目录下的所用文件打包成一个文件。


解决方法:

tar czvf arthinking.tar.gz $(ls)


关于tar命令:

-c :建立一个压缩文件的参数指令(create 的意思);
-x :解开一个压缩文件的参数指令!
-t :查看 tarfile 里面的文件!
-z :是否同时具有 gzip 的属性?亦即是否需要用 gzip 压缩?
-j :是否同时具有 bzip2 的属性?亦即是否需要用 bzip2 压缩?
-v :压缩的过程中显示文件!这个常用,但不建议用在背景执行过程!
-f :使用档名,请留意,在 f 之后要立即接档名喔!不要再加参数!
-p :使用原文件的原来属性(属性不会依据使用者而变)
-P :可以使用绝对路径来压缩!
-N :比后面接的日期(yyyy/mm/dd)还要新的才会被打包进新建的文件中!

除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/linux-shell-of-a-few-common-examples-of-the-use-and-analysis.html
关键字: ,
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2011 6/11
文章评论
    3条评论
  1. www.cmboy.com 2011年06月15日02:15:35  #-49楼 回复 回复

    修改文件名命令mv中的参数$1为需要的文件名,$(echo $1 | sed “s/$2$//”)为想要修改的格式。其中$(echo $1 | sed “s/$2$//”)表示把$1中的变量送入管道,使用sed的替换功能s/re/string将$1中匹配到$2$($2$表示第二个参数的内容)替换为空,即是去掉。

    这里的$2$是表示以$2结尾吧。

    • arthinking 2011年06月15日02:18:26 回复 回复

      恩,$2表示第二个域的内容,$2$表示匹配第二个域的内容直到结尾的。

给我留言

有人回复时邮件通知我
操作系统的相关文章
随机文章 本月热门 热评
1 The Knowledge About Protected Mode Must Be Master During Learning The Operating System 2011/5/10
2 ExecutorService常用方法和newFixedThreadPool创建固定大小的线程池 2012/7/30
3 Java基础笔记 – 线程的生命周期 线程的状态 优先级和常用方法 2011/10/24
4 Hibernate加载数据失败failed to lazily initialize a collection of role 2011/5/31
5 JVM笔记 – 自动内存管理机制(调优案例分析与实战) 2014/11/30
6 JavaScript设计模式 源代码 2012/10/21
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.