shell的内容平时多多少少会使用到,说道底是经验积累问题,虽然每次总能找到最后的答案,但是总不能每次一用到就一句一句去搜索吧,还是按照场景整理在一起比较方便,先整理在这,然后持续更新。
用于“生存”的基本命令
变量定义相关
export
export可以将临时定义的变量定义成环境变量,比如在一个shell中临时定义的一个变量就没法在新打开的那个shell中继续再使用。使用export之后,这个变量就变成了环境变量,就可以在子进程中(新开的shell貌似不是子进程)再进行使用。具体的Linux中环境变量的分类可以参考之前写的linux env一篇
echo
用于显示环境变量 echo $变量名 可以显示出具体的变量来
unset 变量名
这个用于取消刚才已经设置好的变量 unset之后 刚才已经定义好的变量就不在了
文件处理相关
cp
是在同一台linux上互相拷贝文件 而scp是在不同linux系统之间互相拷贝文件 复制文件或目录 cp [参数] 源文件 目标文件
重要参数 –a(相当于-pdr组合在了一起) 复制过去之后文件属性的参数也是一样的 默认情况 属性是不一样的
scp
一种使用方式是将本地文件传输到远程服务器上,或者远程服务器上的文件传回到本地。认证时候的方式与ssh类似,参数格式是:
scp -i <私钥地址> 本地文件的路径 用户名@远程服务器的ip:远程服务器上的路径 |
另一种是进行端口映射,比如把本机上的一个端口映射到远程的服务器的某个服务上:
scp -p 4588 remote@www.abc.com:/usr/local/sin.sh /home/administrator |
tar
可以用来压缩或者解压缩 具体的命令比较多 可以参考鸟叔p254
一般对tar.gz文件解压的时候 采用-xzvf参数 –x 表示使用解打包或解压缩的功能 –z表示通过gzip的方式进行解压 此时文件后缀最好是*.tar.gz –v表示在解压的过程中将处理的文件名显示出来 –f表示 filename后面接的是实际要进行处理的文件名
tar 用于打包的时候要这样使用
tar -czvf 打包之后所生成的文件名 需要打包的文件或目录
具体命令含义可以参考鸟叔p254
–z是打包成.tar.gz -j是打包成.tar.bz2
mv
移动文件或者重命名
rm
删除文件或目录
-f 强制删除 –r递归删除 –i产生交互的信息
注意删除文件的时候一定要谨慎使用-rf的参数
文件/关键字查找
grep
在当前目录下找某些关键的代码都在哪些地方被使用了
grep -r "<keyworkd>" ./ |
或者有的时候grep 与 cat 组合起来一起使用,比如查看log文件中的某些关键字:
cat <logfile> | <keyword> |
strings
这个命令可以将二进制文件中的内容通过human readable的方式打印出来,比如有一次查看libstdc++.so.6
中所支持的GLIBC的版本,就使用如下的方式进行操作:
strings ./libstdc++.so.6 | grep GLIBC |
find
可以用来查找某个目录下是否包含指定的文件,比如以下的命令:
find ./ -name "db.json" |
就是用来查看当前目录下是否含有 db.json 这个文件并且把相关的目录都打印出来
locate
locate 相当于是find -name的另一种写法,但是它的速度比find -name要快因为是从一个指定的db中进行搜索,这个指定的db(/var/lib/locatedb)会由系统进行定期的更新。
可以参考这个to get more detailed info.
查看磁盘的使用情况 处理空间不足的问题
df
查询目录的挂在情况 以及使用到的文件系统 以及基本的可用空间
du
查询到了哪个挂载的目录比较大的话,进入对应的那个挂载的目录,之后使用 du -ah –max-depth=1 . 可以查询当前目录下每一个子目录的大小。
进程相关
ps
查看当前进程 具体参数较多 常用的有
ps –af查看全部的进程并且以全格式的方式显示出来
service start/status/restart
service –status-all 这个命令可以列出全部的可以用供求service来使用的脚本
service命令可以使用的启动脚本或者服务 都要是在/etc/init.d文件夹下已经存在的?
pgrep
pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行
-l 列出程序名和进程ID;
-o 进程起始的ID;
-n 进程终止的ID;
od命令
这个命令可以用来查看某个文件中的详细信息,主要是可以根据不同的进制将每个字节的信息显示出来,文件内容可以通过管道的方式传过来,也可以直接跟在后面用od打开。
注意几个具体的参数,w是表示每列可显示的字符数,d 表示十进制 o 表示八进制(系统默认值)x 表示十六进制 n表示不打印位移值
网络相关
查看端口的占用情况
lsof -i tcp:port |
lsof可以列出系统当前某个端口所打开的文件
nc –zv hostip 80 |
这个命令可以检查以hostip主机的80端口 看是否这个端口已经被打开
比如 nc –zv localhost 80
这个可以查看主机的80端口是否正常被打开
netstat
也可以查看网络相关的状态信息
重启网络服务(ubuntu)
sudo /etc/init.d/networking restart
service network-manager restart
其他
ssh
这个是使用security,shell远程登录其他的终端,关于ssh具体要了解的内容比较多,比如证书的原理以及地址,比如如何将本地端口映射到远程端口。具体可以参考之前的ssh tips一篇。
terminal相关的快捷键
ctrl+D 用户注销 并且按两下会关闭terminal
ctrl+alt 弹出新的terminal(in ubuntu)
ctrl+shift+T 在同一个大的Terminal窗口中生成新的小的窗口 这样切换比较方便 看起来比较好
shift+ctrl+v 将剪贴板中的内容粘贴到terminal中
linux 的terminal中比较通用的几个快捷键(经常用到的)
ctrl+A 跳转到整行的前面
ctrl+E 跳转到整个命令行的末尾
ctrl+W 删除下一个分隔符之前的字符串
几种常用到的shell脚本
每次要写一个shell sacripts就各种google各种查看以前资料,搞得很心烦,其实感觉shell能做的事情python都能做而且还能比较简单,于是能用python的情况下就尽量不用shell,这些内容还是先整理在这里省的时间又被白浪费。
脚本写在一行
在使用docker或者使用k8s启动对应pod的时候,相应的启动参数通常都是一个string类型的数组。前两个参数通常是[“sh”,”-c”],第三个参数应该是所要执行的shell脚本,这个时候需要把平时看起来很长的脚本写到一行中。其实也很简单,只需要在换行的地方采用;
隔开即可。具体的一些例子可以参考这个(https://prayogshala.wordpress.com/single-line-shell-scripting/)。
在k8s中注意args与command的使用与docker有区别,具体可以参考这个(https://github.com/kubernetes/kubernetes/issues/8235),仅仅通过docker方式启动的话,只需要使用args的参数而非command的参数。
判断某个文件/变量是否存在
-z
可以判断这个变量的取值的长度是不是为0,如果存在,说明值的长度是不为0的。if [ ! -z “$JRE_HOME” ]
表示的是变量存在(内容长度不为0)。 类似的根据参数的不同可以判断文件夹(-d),文件(-f)是否存在,注意每个字符中间的空格,否则shell在解析的时候容易发生错误。
#!/bin/bash |
关于循环
直接参考这个
让许多台机器使用ssh的方式进行通信
实际case是这样的,需要帮实验室的多台虚拟机搭建同样的测试环境,肯定是要脚本来执行了,先是在一台机器上把整个流程走通之后,再使用ssh的操作复制到其他的机器上来执行,按理说也不是很复杂的操作。
一般有两个脚本,第一个是使用ssh-key的方式,将本机生成的ssh-key的公钥放到其他机器上,ok之后,再将其他命令都用ssh的方式执行就不用用户名和密码了,用到了spawn与expect,整理类似的脚本还是比较折腾的。
#set -e |
这个脚本主要是中间那段,在/bin/bash 脚本中插入一段/usr/bin/expect 脚本来执行交互,这里要注意的是EOF的使用结尾的那个EOF要放到正行的开头这里坑了好久,最后还是在同学的帮助下完成的。还要注意下expect对于多种情况时候的处理,以及exp_continue的使用。
最后通过setsid方式后台运行命令,并且将标准输入和输出记录到log中。
在后台静默运行某个程序
主要的有三种方式,采用sesid、nohup以及&,可以参考这个
比如下面这个例子,启动etcd并且把对应的日志信息输出到指定的文件夹。
$ setsid ./etcd -name infra0 -data-dir infra0 -cert-file=server.crt -key-file=server.key -advertise-client-urls=https://127.0.0.1:2379 -listen-client-urls=https://127.0.0.1:2379 1>stdout.log 2>stderr.log |
有一次采用&的方式静默启动,但是应用不定时地就自动关闭了,也没有什么特殊日志,总是就是很奇怪,还是采用service的方式比较好,实在不行也得用个docker吧,要不应用挂了也不知道,所谓的进程监控了。
关于linux中的输出重定向的问题可以参考这个
通过grep命令判断是否截取出相关的内容
首先是grep的那一套操作,如果不需要grep的内容输出,可以将输出结果重定向到null中。
之后通过if_exist=$?
返回上一条命令,也就是grep那个命令的状态码,之后再用一个if操作来判断状态码是0还是1,如果是1的话,说明grep操作的确截取到了相关的内容,如果为0的话,说明grep命令并没有截取到相关的内容。注意有的时候ps命令与grep结合,希望搜索出特定的进程信息,这个时候容易吧grep本身的进程也显示出来,此时可以使用-v参数,在这个搜索命令的最后部分加上|grep -v grep
把含义grep关键字的内容从搜索结果中去掉。
检查log中的关键字段
比如server会把文件写到log中,每个server process 可能需要完成一些load的操作 当所有的process把这些操作完成后,client才能启动,script需要不断检查log中的关键字段,看所有的scripts是否都启动完成,
SERVERNUM=8 |
零碎的知识点
脚本中开头部分
一般比较常用的是写成 #!/bin/bash ,其中“#!”表示要位这个shell脚本指定一个解释器,当然后面还可以添加其他的内容,具体可以参考这个
set使用
set -x 这个通常是于 set +x放在一起来使用的,开启调试模式。
set -x # activate debugging from here |
在”set -e”之后出现的代码,如果返回值是非0的,整个脚本就会立即退出,这个有时候会比较奇怪,有的时候可能脚本退出会引发一些奇怪的事情。一般命令正常就会返回0,命令异常就会返回其他的值。可以通过 echo $? 命令来查看上一条命令执行的状态码。
脚本中的空格问题
在给某个变量赋值的时候,等于号要和变量名紧挨在一起,不可以多一个空格出来,要不然系统会以为用户是在执行某个命令,这个实在是太容易错了,特别是对于像自己这样的新手而言。
单引号双引号反引号
网上相关的介绍内容较多。使用双引号,可引用除了字符$、`、\外的任意字符或字符串。用单引号括起来的特殊字符串将没有意义,最常见的是,使用了 ‘$varname’ 之后,$varname就会以字面值的形式出现。可以在双引号字符串中嵌套单引号。shell会将反引号中的内容作为一个系统命令来输出。
寻找固定后缀的文件
找固定后缀的文件
find [path] -name .pyc
递归查找
find [path] -name ‘.pyc’
希望将json以格式化的方式输出
输出格式比较好的json信息,需要用到python的-m参数,加载一个库之后将内容输出
echo ‘{“foo”: “lorem”, “bar”: “ipsum”}’ | python -m json.tool
脚本中传入参数
关于脚本中参数的传递问题
脚本名称叫test.sh 入参三个: 1 2 3
运行test.sh 1 2 3后
$*为”1 2 3”(一起被引号包住)
$@为”1” “2” “3”(分别被包住)
$#为3(参数数量)
更多传入参数的处理方式可以参考这里。
Here Document
Here document相关的内容,希望将一些内容写入到某个文件中,执行类似的操作时,可以使用重定向。
字符串的拼接
关于字符串的拼接,直接 $command=string1’xxxx’ 之后再echo $command就是可以的。
或者$command=${var1}${var2}这样也是可以拼接起来的。
命令替换与变量替换
区别命令替换与变量替换 $()这种方式与${}这种方式的区别。具体可以参考shell十三问之8。
关于sed的使用
一般是用来替换一个配置文件中的某些内容
http://stackoverflow.com/questions/9366816/sed-unknown-option-to-s
注意:替换掉的字符串可能在其中含有”/“,这样在最后的串中就有多个“/”
变量分配时候的默认值
直接看别人整理的
http://unix.stackexchange.com/questions/122845/using-a-b-for-variable-assignment-in-scripts
其他参考资源
shell 十三问
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=218853
这里找到了一个简体版
http://www.eefocus.com/haijiaoyouzi/blog/11-05/210795_9d1d9.html
这个分开整理的shell十三问,也比较好
https://blog.csdn.net/ancky_zhang/article/details/4583579
原帖
http://bbs.chinaunix.net/thread-218853-1-1.html
google的shell书写规范
http://zh-google-styleguide.readthedocs.io/en/latest/google-shell-styleguide/background/
bash编程基础总结
https://blog.csdn.net/marcky/article/details/7549513