分享

Shell学习线路:可以应用于工作及面试

问题导读

1.Shell该如何学习?
2.Shell和传统编程语言有哪些相同之处?
3.Shell和传统编程语言有哪些不同之处?
4.你认为Shell还有哪些便捷的地方?

由于行业的发展,对程序员的要求越来越高,原先我们只会一门语言就可以找到工作,现在我们需要会的东西越来越多,会一门语言只是入门开发而已,目前你会大数据更好,会算法、机器学习那已经成为佼佼者。所以我们这个行业需要不断的学习、成长和进步。

这里我们所说的Shell,其实无论是大数据、云技术、还是其它等,其实很多都可以用到。但是作为传统开发程序员来讲,对它可能还是停留在简单的使用阶段。比如根据文档可以安装部署大数据组件,比如Hadoop、Spark等。但是这距离我们使用Shell编程,还是有一定距离的。

本文主要针对零基础、面试Shell不知道该如何补充这方面的知识,以及工作中想学习Shell的老铁。

零基础Shell
对于零基础的老铁,其实只要经常使用Linux即可熟悉基本的Linux操作。例如复制文件cp、移除文件mv、创建文件夹mkdir、编辑文件vi、查看文件cat、授权chmod、chown等,当然比如网络配置、开机、关机等这些也是在我们安装部署集群所必备的。对于这些常用的命令或则shell,我们只要多安装集群,会变的比较熟悉。

更多可参考

解决遇到Linux网络配置,从熟悉网络配置文件入手

linux入门大全:包括零基础入门,Linux详细介绍

Linux重启方式init 0 init1 init 3 init 5 init 6 这几个启动级别都代表什么意思?

Ubuntu常用命令总结及修改DNS的多种方法总结

Linux关机各种关机命令总结

Linux基础必懂:eth0,eth1,eth2,lo是什么意思?

linux中pwd命令详解

linux之vi编辑器

linux yum命令详解

Linux下chkconfig命令详解


Shell编程

Shell编程,这里对很多人来说就有点难度了,如果我们掌握了Shell编程,会让我们在职场中更有优势,面试亦是亮点。一些企业包括很多的名企,招聘中都提到了Shell。
2.png

3.png

1.png


我们可以看到无论是Java高级工程师,还是大数据工程师,都要求会使用Shell。那么我们该如何补充这方面的知识。

Shell与传统编程语言比较

1.相同点
Shell已经被视为一种编程语言,既然是编程,那么它和其它编程语言有什么相同之处?
我们在学习Shell的时候,大多都是觉得Shell是比较难学的,其实如果我们确实深入了解下,它和我们的其它编程语言,有太多的相似之处。

在编程中,流程控制,我们知道条件判断if else,case ,循环比如for,while等是基本的编程结构,那么在Shell中其实也是同样存在的,数组、函数在shell亦是存在的,当然在实现细节方面略有不同。
比如shell中的if else,如下面格式
[mw_shl_code=bash,true]if condition
then
    command1
    command2
    ...
    commandN
else
    command
fi[/mw_shl_code]
我们可以看到其实就两点区别:多了两个单词,一个then,以及以fi结尾。这样我们就掌握了shell中if else的用法,看是非常简单的。

对于shell编程更多内容可参考

Shell 变量

Shell 传递参数

Shell 数组

Shell 基本运算符

Shell echo命令

Shell printf 命令

Shell 流程控制

Shell 函数

Shell 输入/输出重定向

Shell 文件包含


2.不同点
Shell既然为Shell,那么和其它编程语言也有不同的地方。比如管道符。

管道符
管道符我们或许听说过或则没有听说过,但是我们会被它的名字所迷惑,管道符到底是什么?它的作用是什么?当然我们看到下面例子的时候,一看就会变的非常简单。

这里举例比如我们遇到问题,想查看Linux进程
ps -aux | grep ***   查询***进程的详细信息;

对于上面|即为管道符。那么为什么称之为管道符?
原因为:管道符是将第一个命令的结果传递给第二个命令作为输入。这是不是比较神奇,而且作用非常大。

比如我们上面命令查看进程,进程的结果进一步过滤,我们通过管道符+grep实现了对结果的进一步过滤。

在比如:
把原本要输出到屏幕的用户信息列表再交给 wc 命令作进一步的加工

[mw_shl_code=bash,true]grep "/sbin/nologin" /etc/passwd | wc -l[/mw_shl_code]

比如用翻页的形
式查看/etc 目录中的文件列表及属性信息(这些内容默认会一股脑儿地显示到屏幕上,根本看不清楚):

[mw_shl_code=bash,true][root@linuxprobe ~]# ls -l /etc/ | more
total 1400
drwxr-xr-x. 3 root root 97 Jul 10 17:26 abrt
-rw-r--r--. 1 root root 16 Jul 10 17:36 adjtime
-rw-r--r--. 1 root root 1518 Jun 7 2013 aliases
-rw-r--r--. 1 root root 12288 Jul 10 09:38 aliases.db
drwxr-xr-x. 2 root root 49 Jul 10 17:26 alsa
drwxr-xr-x. 2 root root 4096 Jul 10 17:31 alternatives
-rw-------. 1 root root 541 Jan 28 2017 anacrontab
-rw-r--r--. 1 root root 55 Jan 29 2017 asound.conf
-rw-r--r--. 1 root root 1 Jan 29 2017 at.deny
drwxr-xr-x. 2 root root 31 Jul 10 17:27 at-spi2
drwxr-x---. 3 root root 41 Jul 10 17:26 audisp
drwxr-x---. 3 root root 79 Jul 10 17:37 audit
drwxr-xr-x. 4 root root 94 Jul 10 17:26 avahi
--More--[/mw_shl_code]

除了管道符,还有两个非常重要的工具,这两个的使用,直接影响了别人认为我们是否熟悉shell的一个标识。一个是sed,一个是awk。
既然这两个这么重要,那么我们来认识下这两个工具。

sed使用
什么情况下使用sed,比如我们想偷懒,不想打开文件然后在各种操作,那么这时候我们就可以使用sed了。
sed可以完成的操作很多,比如sed截取文件
[mw_shl_code=bash,true]sed -n ‘1,6p’ filename >newfilename
[/mw_shl_code]
使用sed加“-n”参数来完成对文件某几行的截取,上述sed命令就可以截取文件中的1到6行然后输出到新文件中。

sed替换文件内字符

[mw_shl_code=bash,true]sed -i ‘s/old/new/’filename
[/mw_shl_code]
其中-i表示在本地直接对源文件中的内容作出修改

还有其他功能比如删除文件的某些特征行,某些变量前添加内容。关于sed使用更多可参考
Linux sed工具命令详解
https://www.aboutyun.com/forum.php?mod=viewthread&tid=28389

awk使用
awk跟sed差不多,也可以操作文件。而且说它是一门编程语言也不为过。

我们来看它的简单的使用。在举例之前,需要说下,shell中有默认的变量,比如一个文件如下:
a   b   c
a1 b1 c1
a2 b2 c2



如果我们使用语言api,该如何获取第一列数据,相信这个不同的语言实现有所不同,可是awk那太简单了,只需要一个变量即可实现,$1:表示第一列,$2表示第二列,$3表示第三列。对滴这就是Shell的便捷之处,我们可能使用大量的语言编程,在shell中可能一行代码就可以搞定了。我们接着来看。

比如我们查看某个目录的文件:
[mw_shl_code=bash,true] ls -lh
[/mw_shl_code]
[mw_shl_code=bash,true]total 136K
-rwxr-xr-x 1 root root  766 Jul 22  2011 colorls.csh
-rwxr-xr-x 1 root root  727 Jul 22  2011 colorls.sh
-rw-r--r-- 1 root root   92 Feb 23  2012 cvs.csh
-rwxr-xr-x 1 root root   78 Feb 23  2012 cvs.sh
-rwxr-xr-x 1 root root  192 Mar 25  2009 glib2.csh
-rwxr-xr-x 1 root root  192 Mar 25  2009 glib2.sh
-rw-r--r-- 1 root root  218 Jun  6  2013 krb5-devel.csh
-rw-r--r-- 1 root root  229 Jun  6  2013 krb5-devel.sh
-rw-r--r-- 1 root root  218 Jun  6  2013 krb5-workstation.csh
-rw-r--r-- 1 root root  229 Jun  6  2013 krb5-workstation.sh
-rwxr-xr-x 1 root root 3.0K Feb 22  2012 lang.csh
-rwxr-xr-x 1 root root 3.4K Feb 22  2012 lang.sh
-rwxr-xr-x 1 root root  122 Feb 23  2012 less.csh
-rwxr-xr-x 1 root root  108 Feb 23  2012 less.sh
-rwxr-xr-x 1 root root   97 Mar  6  2011 vim.csh
-rwxr-xr-x 1 root root  293 Mar  6  2011 vim.sh
-rwxr-xr-x 1 root root  170 Jan  7  2007 which-2.sh[/mw_shl_code]

awk的使用,例如只打印第一列:
[root@localhost profile.d]# ls -lh | awk '{print NR " " $1}'
1 total
2 -rwxr-xr-x
3 -rwxr-xr-x
4 -rw-r--r--
5 -rwxr-xr-x
6 -rwxr-xr-x
7 -rwxr-xr-x
8 -rw-r--r--
9 -rw-r--r--
10 -rw-r--r--
11 -rw-r--r--
12 -rwxr-xr-x
13 -rwxr-xr-x
14 -rwxr-xr-x
15 -rwxr-xr-x
16 -rwxr-xr-x
17 -rwxr-xr-x
18 -rwxr-xr-x


上面我看到awk确实使用起来非常方便,而且如果我们稍微学习下,其实也不难的,更多awk可参考
https://www.aboutyun.com/home.php?mod=space&uid=61&do=blog&id=4338

3.Shell便捷之处
有了传统编程语言,为何会有shell编程。让我们来看看做同样的事情,Shell到底有多便捷。
我们就以数据清洗为例:
如果我们使用语言API,那么首先我们需要有开发环境,比如IDEA,Eclipse等,这个如果你不熟悉就够麻烦的了。有了环境之后,我们还需要会使用语言API,API编程,我们知道要有类,有入口函数Main以及功能实现等。

我们就以日志清洗,我们可以看到通过api的实现。
[mw_shl_code=scala,true]import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.{Seconds, StreamingContext}

import scala.util.matching.Regex

/**
  * Created by PeersLee on 2017/2/8.
  */
object ExtractFromLocal {
        def main(args: Array[String]): Unit = {
                //创建SparkConf,设置AppName和Master
                // var:声明变量,val:声明常量
                val conf = new SparkConf().setAppName("ExtractFromLocal").setMaster("local")
                // 创建一个具有n个线程10秒间隔时间的本地StreamingContext
                val ssc = new StreamingContext(conf, Seconds(10))
                // 上面我们已经创建一个DStream(连续的数据流),这个ssc可以从TCP源(ip : localhost, port : 9999) 获取流数据,
                // 开始获取数据
                val hostname = "192.168.1.10"
                val port = 9999
                val lines = ssc.socketTextStream(hostname, port, StorageLevel.MEMORY_AND_DISK_SER)
                // 处理逻辑
。。。。。
                 words.print()
                //开始执行,并在控制台等待
                ssc.start()
                ssc.awaitTermination()
        }
}
[/mw_shl_code]
更多可参考:
about云日志分析项目准备10-3:Spark Local模式之Log文本清洗
https://www.aboutyun.com/forum.php?mod=viewthread&tid=21135


上面我们先不管逻辑,就可以看到需要大量的代码,那么用Shell,该如何实现:
下面一行代码即可实现
[mw_shl_code=bash,true]awk '($7 !~ /^\/static\//){print $0}' access_2013_05_30.log > clean_2013_05_30.log
[/mw_shl_code]
解释:
清洗去除URL中以/static/开头的URL

上面我们看到Shell是非常简练的。

Shell面试题

面试题,其实只要我们打好基础,面试题难不倒我们的。特别是我们所讲的sed和awk的使用。有些老铁为了面试只是背面试题,而不去往基础和知识的源头去学习,那只能是会了这个,忘了那个。所以即使我们针对面试,我们亦应该针对经常出现的面试题,去总结经常被问的知识点,如果这些知识点熟悉了,那么对于它所对应的所有问题,也就迎刃而解了。下面是关于Shell的面试题,如果上面我们知识点都熟悉了,你会发现下面的面试题不在困难。

一、取出/etc/passwd文件中shell出现的次数

问题:
下面是一个/etc/passwd文件的部分内容。题目要求取出shell并统计次数,shell是指后面的/bin/bash,/sbin/nologin等,如下面/bin/bash出现12次,/sbin/nologin出现3次。
hyn:x:525:500::/home/hyn:/bin/bash ljlxx:x:526:500::/home/ljlxx:/bin/bash lzj:x:527:500::/home/lzj:/bin/bash wfly:x:528:500::/home/wfly:/bin/bash squid:x:23:23::/var/spool/squid:/sbin/nologin wyj:x:529:500::/home/wyj:/bin/bash qemu:x:107:107:qemu user:/:/sbin/nologin radvd:x:75:75:radvd user:/:/sbin/nologin dungbee:x:530:500::/home/dungbee:/bin/bash mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash scidb:x:531:531::/home/scidb:/bin/bash postgres:x:532:532::/home/postgres:/bin/bash crane:x:533:533::/home/crane:/bin/bash test:x:534:534::/home/test:/bin/bash hguser:x:535:535::/home/hguser:/bin/bash

参考答案:
cat /etc/passwd|awk -F: '{print $7}'|sort|uniq -c

解析:
使用awk根据冒号分割内容,打印输出分割后的第7列,也就是shell所在列。然后调用sort命令排序并使用uniq -c统计每个shell出现的次数。

二、文件整理

问题:
employee文件中记录了工号和姓名
employee.txt: 100 Jason Smith 200 John Doe 300 Sanjay Gupta 400 Ashok Sharma
bonus文件中记录工号和工资
bonus.txt: 100 $5,000 200 $500 300 $3,000 400 $1,250
要求把两个文件合并并输出如下
处理结果:
400 ashok sharma $1,250 100 jason smith $5,000 200 john doe $500 300 sanjay gupta $3,000

参考答案:
paste employee.txt bonus.txt | awk '{print $1,$2,$3,$5}'|tr '[:upper:]' '[:lower:]'|sort -k 2

解析:
这里用到好几个命令,包括paste,awk,tr以及sort。paste命令用于合并多个文件的同行数据,如上面两个文件employee和bonus调用paste后合并成
100 Jason Smith 100 $5,000 200 John Doe 200 $500 300 Sanjay Gupta 300 $3,000 400 Ashok Sharma 400 $1,250
paste命令可以使用-d指定合并时加入的符号。比如paste -d : employee bonus则结果变成类似100 Jason Smith :100 $5,000 等。默认合并符号为tab符号,更多paste命令请参照http://snailwarrior.blog.51cto.com/680306/144462/
awk用于提取除了tab符号的其余4列。
tr命令用于将字符串中所有大写字符转换为小写字符。更多选项参见https://blog.csdn.net/zxnm55/article/details/19040135
sort命令对字符排序。sort -k 2表示按文件第2个域排序,这里第二个域为姓名,所以是按姓名升序排序。如果要降序排列,则要用sort -k 2r。更多sort命令参见http://www.360doc.com/content/10/0925/15/1107705_56263541.shtml

三、打印本机交换分区大小

问题:打印本机交换分区大小,输出如下
Swap:1024M

参考答案:
top -n 1|grep Swap|sed 's/k.*//'|awk '{print $1,$2/1000"M"}'

解析:
top 命令显示系统资源占用情况,-n 1表示只调用1次。
grep Swap选取Swap所在行。grep命令执行后结果可能如下:
Swap: 16779884k total, 0k used, 16779884k free, 3268200k cached
sed命令用于字符串的一些正则匹配,这里使用了替换参数,将第1个k以及后面的字符替换成了空白。这样,sed执行后,结果为:
Swap: 16779884
awk命令输出内容,对第二个参数除以1000.

四、用户清理

问题:
清除本机除了当前登陆用户以外的所有用户。

参考答案:
kill $(who -u|grep -v `whoami`|awk '{print $6}'|sort -u)

解析:
who -u显示所有当前用户。grep -v选取当前登录用户以外的所有用户。awk打印用户进程ID。sort -u会删除相同的行。最后用kill命令终止。

五、百度脚本面试题

问题:
1)写脚本实现,可以用shell、perl等。在目录/tmp下找到100个以abc开头的文件,然后把这些文件的第一行保存到文件new中。

参考答案1:
#!/bin/sh for filename in `find /tmp -type f -name "abc*"|head -n 100` do sed -n '1p' $filename>>new done


解析:第一,用到了find命令,其中-type f表示选取普通文件,-name用于设定文件名;第二,head -n 100命令用于取出前100项。第三,sed -n ’1p’用于取出文件的第一行内容。第四,>>new表示追加到文件new中。

参考答案2:
find /tmp -type f -name “abc*” | head -n 100 | xargs head -q -n 1 >> new

问题:
2)写脚本实现,可以用shell、perl等。把文件b中有的,但是文件a中没有的所有行,保存为文件c,并统计c的行数。

参考答案:
grep -vxFf a b | tee c | wc -l

解析:grep选取-v表示不选择匹配的行,-F表示匹配的模式按行分割,-f a表示匹配模式来自文件a,最后表示目标文件b。即grep命令从b中选取a中不存在的行。
            tee c命令创建文件c,wc -l命令统计行数。


如果你想搜集更多面试题,可参考下面内容:

shell编程-百度面试题
https://www.doc88.com/p-6542593799085.html

shell编程面试题
https://www.doc88.com/p-9953411882649.html

linux-shell面试题
http://zhangbin.junxilinux.com/?p=724

Shell面试题
https://juejin.im/entry/5bead00151882537347579fa

Shell脚本面试题Top50

https://www.jianshu.com/p/7a08d193cf79

Shell脚本面试题Top50

https://www.doc88.com/p-9952889361809.html

更多学习资料:
有的同学,不喜欢看文章,这里给大家推荐套视频,是阿里的完全免费的,不过需要登录才可以看。

70-个经典的shell-脚本面试问题及解答
70-个经典的shell-脚本面试问题及解答.zip (16.55 KB, 下载次数: 14)

已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条