月份:2017年11月


shell习题-自定义rm


linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:

1. 简单

假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一同同步

2. 复杂

不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够的空间备份并提示是否放弃备份,如果用户选择y,则直接删除文件或者目录,如果选择n,则提示未删除,然后退出脚本。

 

参考答案:

1.  简单
#!/bin/bash
filename=$1
d=`date +%Y%m%d%H%M`
read -p “Are U sure delete the file or directory $1? y|n: ” c
if [ $c == “y” ] || [ $c == “Y” ]
then
    mkdir /data/.$d
    rsync -aR $1/ /data/.$d/$1/
    /bin/rm -rf $1
elif [ $c == “n” ] || [ $c == “N” ]
then
    exit 0
else
    echo “Please input ‘y’ or ‘n’.”
fi
2.  复杂
#!/bin/bash
filename=$1
d=`date +%Y%m%d%H%M`
f_size=`du -sk $1|awk ‘{print $1}’`
disk_size=`LANG=en; df -k |grep -vi filesystem|awk ‘{print $4}’ |sort -n |tail -n1`
big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk ‘{print $NF}’`
if [ $f_size -lt $disk_size ]
then
    read -p “Are U sure delete the file or directory: $1? y|n: ” c
    if [ $c == “y” ] || [ $c == “Y” ]
    then
        mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/ && /bin/rm -rf $1
    elif [ $c == “n” ] || [ $c == “N” ]
    then
        exit 0
    else
        echo “Please input ‘y’ or ‘n’.”
    fi
else
    echo “The disk size is not enough to backup the files $1.”
    read -p “Do you want to delete “$1″? y|n: ” c
    if [ $c == “y” ] || [ $c == “Y” ]
    then
        echo “It will delete “$1″ after 5 seconds whitout backup.”
        for i in `seq 1 5`; do echo -ne “.”; sleep 1;done
    echo
        /bin/rm -rf $1
    elif [ $c == “n” ] || [ $c == “N” ]
    then
        echo “It will not delete $1.”
        exit 0
    else
        echo “Please input ‘y’ or ‘n’.”
    fi
fi

shell习题-转换字符串


请把下面的字符串:

zhangsan

y97JbzPru

lisi

5JhvCls6q

xiaowang

Nnr8qt2Ma

laoma

iqMtvC02y

zhaosi

9fxrb4sJD

改为如下:

zhangsan:y97JbzPru

lisi:5JhvCls6q

xiaowang:Nnr8qt2Ma

laoma:iqMtvC02y

zhaosi:9fxrb4sJD

 

参考答案:

sed 'N;s/\n/:/g'  filename

java程序员学习linux的感受


作者:23期陈旭

“哇 Linux系统操作起来怎么这么麻烦的!”,这是我第一次成功安装最小化CentOS7系统,初体验后的感叹(手动滑稽)。那时候我还没有报名猿课,仅仅是看着鸟哥的书和百度到的教程安装的。

因为我是学Java的,所以自然安装好后第一件事情就是安装JDK,那时候还不知道有远程终端这么个神器。所以下载JDK安装包的时候,只能在虚拟机里一点点地把那一长串的下载地址给敲进去。

两小时过后终于折腾完毕,于是开头的第一句话,就是这时候说出来的。在这之后就想着需要系统地从基础开始学习一下Linux,于是乎就抱着广为流传的“鸟哥的Linux私房菜”吃了起来,真的很厚很多字而且还是从最基本的硬件开始讲起,个人感受啃这一段跟啃砖头一样难啃和无趣(并没有黑这本书的意思,后面章节写的还是很不错的)。

由于啃书进度太慢,而且书上都是CentOS5的版本,也算是有点老旧了,所以就去网络上找一些视频教程看。在腾讯课堂上看到阿铭老师的课程视频,试听了两节后感觉还不错,然后就去咨询报名事宜,接着我就成为了23期2班的一员。

刚开始感觉阿铭老师挺严格的,学习安排也很有计划性,像笔记、专贴的格式、规则也挺多,后来习惯之后就好了很多,而且这样有严格的要求也让我养成了一些好习惯,学习上也不敢怠惰,如果不是听阿铭老师介绍,我还不知道那么多辅助工具的使用和拥有一个自己的技术博客。

到现在学到第二阶段,终于没有之前那么菜了,学到现在的感受就是阿铭老师的授课方式适合初学者,每个视频都不超过二十分钟,把每个知识点都分作一个个模块去讲解,而且讲解的过程中还能屏蔽一些暂时没必要深入的知识点,因为对于初学者来说附带这些知识点只会增加压力。

在扩展方面也为我们收集了很多资料,每天公众号上面都有shell的练习题,并且还有个考试平台,让我们能去测试自己的水平分数。

相信每一期的同学都有经常听到阿铭老师强调笔记的重要性,在这里我也要喊一下:笔记真的要记得详细!笔记真的要记得详细!笔记真的要记得详细!重要的事情说三遍。当你认真并把笔记做详细了,把出现的错误总结、记录起来了,有时候真的比练习还重要。

当学完一个阶段去复习时效率上要高很多,出错的时候也能从笔记中找到解决的办法。除此之外搜索引擎也很重要,我学习过程中遇到的许多错误都是在网络上找到解决办法的,出现问题后先自己尝试着去解决,相信这一点也不需要多说了。

除以上两点外就是练习,但是练习不要死记硬背命令,而是去理解命令的用法和技巧,记住技巧和理解命令最重要,死记硬背就像只懂得吃,不懂得消化一样。命令单词在日常中使用多了就自然而然的记下了,即便是一些冷僻的命令,你已经理解了它的用法的话,你只需要瞄一遍就又掌握了。

以上就是我学习过程中的一些心得和感受,在下是没读过书的人文笔不好辞藻不华丽,希望大家多多指教不要打脸。

0基础3个月找到工作


作者:23期小明

先自我介绍一下,我是23期学员,在大学学的是数控技术,我在工厂实习的时候,不喜欢用劳动力时间换来的金钱,所以我就决定辞职报名阿铭linux,在我报名之前从未听过linux,我相信绝大数人的基础比我要好,所以大家都要对自己有信心,天下无难事,只怕你坚持不下。

在我们报名的时候,我相信大家都是激情澎湃,但是学习入门是无趣的。每天面对一些基础的命令专业知识。但是大家一定一定不要放弃。

经过两个半月的学习我就开始找工作了,因为在找工作的过程中,很清晰明了的知道自己哪里不足,在面试中出现的问题,和自己回答不出甚至是从未听到过的专有名词,回家后一定要多学习。

由于我在长沙找工作,招聘运维岗位不是多,所以我面试了很多技术支持的工作,面试技术支持的岗位对技能要求很低,所以对我们以后面试运维工程师在技术方面没有太多用,但是可以增加你的面试经历。

我的面试总结

1、在面试的时候无论如何,一定要有一个非常积极的心态去面试,一定要把自己一颗学习的心态体现出来,特别是像我这种非科班转行的,这一点尤为重要。

 

2、在面试过程中,有90%的面试官会问:你对以后的职业生涯有什么规划。在说自己的规划时,我觉得最好是回答:在工作中中不断的学习进步,能成为公司的技术骨干,我自己认定我**岗位是我一生的追求。千万不能体现自己有跳槽的想法。

 

3、在面试过程中,只要有了解过的专业技能知识,面试官问你会不会,你就回答会,反正不要你具体操作,笔试的时候有机会就把题目发到群里,我相信只要大家有时间一定会帮你的,但是不能说着说着不能把自己带到坑里去了。

 

4、最重要的就是总结前面面试遇到的问题,回家总结形成文档,只要你每次把前面面试中遇到的问题,和回答不出的问题在下次面试中不再出现,我相信你一定会找到工作。

 

关于专业知识的回答阿铭论坛中有非常多,自己耐心寻找总结。

linux shell命名管道FIFO


在shell脚本中,我们想要实现多进程高并发,最简单的方法是把命令丢到后台去,如果量不大的话,没问题。 但是如果有几百个进程同一时间丢到后台去就很恐怖了,对于服务器资源的消耗非常大,甚至导致宕机。

那有没有好的解决方案呢? 当然有!

我们先来学习下面的常识。

1 文件描述符

文件描述符(缩写fd)在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。每一个unix进程,都会拥有三个标准的文件描述符,来对应三种不同的流:

除了上面三个标准的描述符外,我们还可以在进程中去自定义其他的数字作为文件描述符,后面例子中会出现自定义数字。每一个文件描述符会对应一个打开文件,同时,不同的文件描述符也可以对应同一个打开文件;同一个文件可以被不同的进程打开,也可以被同一个进程多次打开。

我们可以写一个测试脚本/tmp/test.sh,内容如下:

#!/bin/bash

echo “该进程的pid为$$”

exec 1>/tmp/test.log 2>&1

ls -l /proc/$$/fd/

执行该脚本 sh /tmp/test.sh,然后查看/tmp/test.log内容为:

总用量 0

lrwx—— 1 root root 64 11月 22 10:26 0 -> /dev/pts/3

l-wx—— 1 root root 64 11月 22 10:26 1 -> /tmp/test.log

l-wx—— 1 root root 64 11月 22 10:26 2 -> /tmp/test.log

lr-x—— 1 root root 64 11月 22 10:26 255 -> /tmp/test.sh

lrwx—— 1 root root 64 11月 22 10:26 3 -> socket:[196912101]

其中0为标准输入,也就是当前终端pts/3,1和2全部指向到了/tmp/test.log,另外两个数字,咱们暂时不关注。

2 命名管道

我们之前接触过的管道“1”,其实叫做匿名管道,它左边的输出作为右边命令的输入。这个匿名管道只能为两边的命令提供服务,它是无法让其他进程连接的。

实际上,这两个进程(cat和less)并不知道管道的存在,它们只是从标准文件描述符中读取数据和写入数据。

另外一种管道叫做命名管道,英文(First In First Out,简称FIFO)。

FIFO本质上和匿名管道的功能一样,只不过它有一些特点:

1)在文件系统中,FIFO拥有名称,并且是以设备特俗文件的形式存在的;

2)任何进程都可以通过FIFO共享数据;

3)除非FIFO两端同时有读与写的进程,否则FIFO的数据流通将会阻塞;

4)匿名管道是由shell自动创建的,存在于内核中;而FIFO则是由程序创建的(比如mkfifo命令),存在于文件系统中;

5)匿名管道是单向的字节流,而FIFO则是双向的字节流;

有了上面的基础知识储备后,下面我们来用FIFO来实现shell的多进程并发控制。

需求背景:

领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。

需求分析:

由于数据量比较大,单个库备份时间少则10几分钟,多则几个小时,我们算平均每个库30分钟,若一个库一个库的去备份,则需要3000分钟,相当于50个小时。很明显不可取。但全部丢到后台去备份,100个并发,数据库服务器也无法承受。所以,需要写一个脚本,能够控制并发数就可以实现了。

控制并发的shell脚本示例:

#!/bin/sh

function a_sub {
    sleep 2;
    endtime=`date +%s`
    sumtime=$[$endtime-$starttime]
    echo "我是$i,运行了2秒,整个脚本已经执行了$sumtime秒"
}

starttime=`date +%s`
export starttime

##其中$$为该进程的pid
tmp_fifofile="/tmp/$$.fifo"

##创建命名管道
mkfifo $tmp_fifofile

##把文件描述符6和FIFO进行绑定
exec 6<>$tmp_fifofile

##绑定后,该文件就可以删除了
rm -f $tmp_fifofile

##并发量为8,用这个数字来控制并发数
thread=8

for ((i=0;i<$thread;i++));
do
    ##写一个空行到管道里,因为管道文件的读取以行为单位
    echo >&6
done

##循环100次,相当于要备份100个库
for ((i=0;i<100;i++))
do
    ##读取管道中的一行,每次读取后,管道都会少一行
    read -u6
    {
        a_sub || {echo "a_sub is failed"}
        ##每次执行完a_sub函数后,再增加一个空行,这样下面的进程才可以继续执行
        echo >&6
    } & ##这里要放入后台去,否则并发实现不了
done

##这里的wait意思是,需要等待以上所有操作(包括后台的进程)都结束后,再往下执行。
wait

##关闭文件描述符6的写
exec 6>&-

 

中年懒癌患者的学习之路


背景年龄:35岁

性别:男

籍贯:湖南张家界

现居住地:四川成都

婚否:已婚

目前供职于川内一家农牧企业,在信息中心做基础架构运维专员,主要负责自建数据中心的服务器、存储、网络、灾备、应用交付、虚拟化等规划运维工作,空闲时间不算多,但也不是忙的不可开交,甲方公司不同于乙方,有问题去解决就好,基于之前乙方的工作经验,基本上现在的工作都能轻松应对。每天都是用游戏和其他消耗时间,相对于在乙方的日子懒惰多了,也许这就是人们口中的“养老”吧。

动机  

12年的时候就因为当时的公司里除了技术总监,只有我一个人会调试 F5,我的工资就比同期高1K。没错,f5的内核就是基于 linux 的 kernel,后来自学 Vmware Vsphere到 Openstack,也发现它的内核是 Linux,我接触的所有高大上的设备就很少不和 Linux 沾边的,我觉得学习 Linux已经势在必行了,然后就开始留意 Linux的培训,

2015年4月跳槽到现在的甲方,通过在网上查找资料知道了猿课,然后关注了一下,断断续续的下了猿课的公开教材和鸟哥的私房菜开始自学。如果说鸟哥私房菜是高深莫测的私房菜的话,那铭哥的阿铭Linux就是让你快速上手并爱上的蛋炒饭,浅入深出,用通俗的概念来让我们爱上学习 Linux,再用他的实际工作经验告诉我们那些坑,那些弯;能在6个月时间内成为 Linux运维老鸟,我觉得这才是业界良心。于是,当年8月就报名了成为8期的一员。

过程  

一开始因为定位不一样,导致我学习坚持没多长时间就坚持不下去了,今年开年后也一直下决心学好Linux,但是又把女儿从老家接到身边自己带,这样业余时间又被压缩。对的,无心学习的人总有很多很多的借口来躲避学习。直到那天看到铭哥发消息说老学员可以跟24期同步学习。我当即找阿铭老师报名,通过这段时间的跟班学习,我发现阿铭老师还是一如既往的认真负责,我也收拾起贪玩的心,开始按照学习大纲的要求进行再一次的学习。

时间安排

一般我的时间安排是这样的,上午处理工作任务和巡检,留1个小时时间看猿课视频,中午休息,下午如果没有紧急的工作要做,都尽量安排给视频和实验,记笔记,因为我住宿舍,所以省去了交通时间,下班后一般花1-2小时看白天的笔记和快速过一遍视频,收集问题准备在课上问老师。21点之后基本都是预习下一天的课程、整理笔记,看看IT行业咨询。23点前必须睡觉!!!

体会  

第1周的学习最难受。因为我一开始的博客笔记是按照自己能看懂目的去写,后来阿铭老师要求“让小白看懂,按操作一步一步能做出来”,当时有点不理解,怎么阿铭老师这样要求,我的笔记我自己肯定看得懂。因为怕被扣分,后面还是照做,但是不明白目的。

有一天我有个问题需要去看自己的笔记。我发现,我当时以为看得懂的笔记竟然要花很长的时间才能回忆起来,这时,我才恍然大悟,原来阿铭老师不是吹毛求疵,真的是为了我们好。阿铭老师,请受我一拜!!!

总结  

笔记!笔记!笔记!贯穿整个职业生涯的一条主线任务,大家还是要好好做,你会发现你的效率越来越高!!!!

时间会不停地走,不管你学没学


一转眼,3个月就过去了,linux运维工程师,已顺利转正。坐标:深圳   薪资:9K,偏低

现在回想当初每天晚上拼命学习的时光,真的是很佩服自己的勇气和毅力。我,20期学员,16年10月,报名参加阿铭linux。一路下来,学习也还算踏实,但结课时,总不够自信,因为没有实操的经验,再加上春节放松一段时间,错过了前年3、4月份招聘高峰期(没有勇气)。

4月底,陆续开始尝试投递简历,可能是写的不好吧,有机会,但是不多。而且是在职期间,偶尔才能请假去面试。虽然面试失败,但我心理反而更踏实,通过不断总结,让我知道重点复习哪些范围。面试宝典、以及扩展视频对扩宽自己的知识面、笔试、面试感觉都很有用。

5月份,终于按捺不住了,因为延期实在太久了,担心找不到工作,就每天不停刷简历,修改简历。机会虽然没有3、4月份多,但是竞争也少了。通过不断修改简历之后,收到的电话确实多了。

在这里,我想说下怎么筛选面试机会——运维岗只配一人的不去、业务太简单的不去、外包公司不去。第一份工作嘛,尽量选择业务结构复杂一点、运维人员多一点的公司,毕竟可以取经,学的多学的的快。这也是我最后妥协了薪资较低的这份工作的原因。

再说说我当前工作的感受,之前铭哥教的东西真的太有用了,大部分都是工作中用得到的,除了lnmp、zabbix、nosql等这些外,扩展的git、elk等也是非常有用,而且笔记也非常重要,因为要经常翻看,配置各种东西。

最后说一句对自己觉得有感悟的话:时间会不停地走,不管你有没有学习!

shell习题-截取字符串


利用你学过的知识点,想办法根据要求截取出字符。

字符串var=http://www.aaa.com/root/123.htm

1.取出www.aaa.com/root/123.htm

2.取出123.htm

3.取出http://www.aaa.com/root

4.取出http:

5.取出http://

6.取出www.aaa.com/root/123.htm

7.取出123

8.取出123.htm

 

参考答案:

#!/bin/bash

var="http://www.aaa.com/root/123.htm"

echo "##1 取出www.aaa.com/root/123.htm"
echo $var | awk -F"//" '{print $2}'
echo $var | grep -o "www.*"

echo "##2 取出123.htm"
echo $var | awk -F"/" '{print $5}'
echo $var | grep -o "[0-9]*\.htm"

echo "##3 取出http://www.aaa.com/root"
echo $var | sed 's|\(.*//.*/.*\)\(/.*\)|\1|'
echo $var | grep -o http.*root

echo "##4 取出http:"
echo $var | awk -F '//' '{print $1}'
echo $var | sed 's/\/\/www.*//'

echo "##5 取出http://"
echo $var | awk -F "w" '{print $1}'
echo $var | sed 's/www.*//'

echo "##6 取出www.aaa.com/root/123.htm"
echo $var | awk -F '//' '{print $2}'
echo $var | sed 's|http://||'

echo "##7 取出123"
echo $var | tr -c -d '0-9\n'
echo $var | grep -o '[0-9]\{3\}'

echo "##8 取出123.htm"
echo $var | awk -F '/' '{print $5}'

shell习题-打印三角形


之前咱们打印过正方形,也打印过乘法口诀,那今天来打印一个三角形(正三角形,元素用*表示)。

 

参考答案:

#!/bin/bash

read -p "please input the lenth:" n

for i in `seq 1 $n`
do
 for j in `seq $n -1 $i`
 do
 echo -n " "
 done
 for m in `seq 1 $i`
 do
 echo -n "* "
 done
 echo
done

shell习题-shell多线程


上一篇文章(http://mp.weixin.qq.com/s/AiKTWf7Y4mGwwOwJyysQtw)我们介绍了命名管道FIFO,利用里面的知识点,实现这个需求。

需求背景:

领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。

需求分析:

由于数据量比较大,单个库备份时间少则10几分钟,多则几个小时,我们算平均每个库30分钟,若一个库一个库的去备份,则需要3000分钟,相当于50个小时。很明显不可取。但全部丢到后台去备份,100个并发,数据库服务器也无法承受。所以,需要写一个脚本,能够控制并发数就可以实现了。

 

参考答案:

#!/bin/sh

##假设100个库的名字存到了一个文件里,文件名字为/tmp/databases.list
##其中备份数据库用了mysqldump,这里你可以换成xtrabackup,更快

function bak_data {
    dbname=$1
    d=`date +%y%d`
    mysqldump -uroot -pxxxxx $dbname > /backup/$1.$d
}

mkfifo $tmp_fifofile
exec 1000<>$tmp_fifofile
rm -f $tmp_fifofile

thread=10
for ((i=0;i<$thread;i++));
do
    echo >&1000
done

for d in `cat /tmp/databases.list`
do
    read -u1000
    {
        bak_data $d 
        echo >&1000
    } & 
done

wait
exec 1000>&-