shell 学习笔记 LinuxShell脚本攻略(第2版)
1 注释用#号;多条命令通过分号或回车来分隔 2 echo会自动换行,若不想换行,则加上-n参数,如 echo -n "nice to meet you"
grep 'test' d* 显示所有以d开头的文件中包含test的行。
scp sourecFile romoteUserName@remoteIp:remoteAddr 远程拷贝
切换用户:su -username
tail -f exmaple.log 这个命令会自动显示新增内容,屏幕只显示10行内容的(可设置)。
netstat -tln | grep 8080 查看端口8080的使用情况
或 netstat -antp | grep 8080
查看指定进程打开的文件:lsof -p $pid 【lsof一般用来查看进程打开的文件:list open file】
远程登录:ssh userName@ip
echo后面的内容可以不带引号,可以带单引号,也可以带双引号
1 对于进程来说,其运行时的环境变量可以使用下面的命令来查看:cat /proc/$PID/environ 2 若输出的结果连在一起了,说明结果之间由null字符(\0)分隔,为了每个结果占一行,可以进行替换操作,如:cat /proc/12501/environ | tr '\0' '\n' 3 注意, var = value不同于var=value。把var=value写成var = value是一个常见的错误,但前者是赋值操作,后者则是相等操作。
4 在变量名之前加上$前缀就可以打印出变量的内容 5 定义环境变量用export ;给已有环境变量追加值,也用export,如 export PATH="$PATH:/home/bin" 6 获取变量值的长度 # :echo ${#haha}
整数运算:no1=4;no2=5
[alauda@ip-10-140-10-186 temp]$ let cc=no1+no2 [alauda@ip-10-140-10-186 temp]$ echo $cc 9 [alauda@ip-10-140-10-186 temp]$ zz=$[no1+no2] [alauda@ip-10-140-10-186 temp]$ echo $zz 9
文件描述符
echo "sdfsdf">bb 覆盖式写入,文件里原来的东西会被清空
echo "what's wrong" >>bb 追加式写入
============
定义数组:sdf=(11 22 33) ----元素之间通过空格分隔
访问所以成员:echo ${sdf[*]}
打印数组长度:echo ${#sdf[*]}
=========调试========
打印出所执行的每一行命令以及当前状态:/bin/bash -x aa.sh
使用set -x和set +x对脚本进行部分调试 :
#!/bin/bash sdf=1 echo $sdf set -x if [ $sdf = 1 ] then echo "nice to meet you" set +x else echo "not equal" fi
=================函数
6 #!/bin/bash 7 myfun() ----定义函数 8 { 9 echo $@; 10 echo $2; 11 return 10; 12 } 13 myfun "aa" "bb" ; --调用函数 14 echo $? ---打印函数返回值
===============
从输入中读取n个字符并存入变量xx:read -n 3 xx
用特定的定界符作为输入行的结束: read -d ";" xx
echo -n 'ni;hao;ma;' |xargs -d ';' ni hao ma
=====================
如将分隔符定义成换号符:IFS=$OLDIFS
将字符串用逗号分隔,逐个打印 IFS存放的是 定界符,
aiya() { echo $1; OLDIFS=$IFS; IFS=","; for item in $1; do echo item:$item; done IFS=$OLDIFS; echo "over over"; } aiya "ni,hai,hao,ma"
结果:
ni,hai,hao,ma
item:ni
item:hai
item:hao
item:ma
over over
================循环
若在if后面放的不是命令,则要通过test或 [ ] 实现,如判断变量是否有值、判断是否相等,都需要[]
myfun() { item="" if [ $item ] --------[] 第一个方括号之后和第二个方括号之前必须加上一个空格
then echo "have" else echo "not have" fi }
输出是 not have
aiya() { echo $1; if [ $1 == 21 ] then echo '11111'; elif [ $1 == 2 ] then echo '22222' else echo '3333' fi } aiya 12 ; ---调用
myfun() { for item in $1; do echo $item done echo "ooooooooo" }
==========条件语句=================
[ $1 == 1 ] && echo "success"
===============
添加行号:cat -n lines.txt
忽略名字大小写进行查找:find . -iname aa*
多条件查询:find . \( -name "*.txt" -o -name "*.sh" \)
用“!”否定参数的含义 :find . ! -name "*.sh"
只对当前目录进行查找:find . -maxdepth 1 -name "*.txt"
-atime、 -mtime、 -ctime 的单位是天,- 表示小于, + 表示大于
-amin -mmin -cmin的单位是分钟
删除查找到的匹配文件:find . -name "*.txt" -delete
查找除zz目录之外的所有文件:find . \( -path "*zz*" -prune \) -o \( -type f -print \)
find的常用参数:-name -path -maxdepth -type -mtime -size -delete
=====================
xargs擅长将标准输入数据转换成命令行参数
将多行文本转换成单行文本:
将单行输入转换成多行输出
将cat的返回值逐一传给sh脚本: cat bb | xargs -n 1 ./hanshu.sh
cat bb | xargs -I {} ./hanshu.sh {}
将cat的返回值和其他参数按顺序传给sh脚本:
cat bb | xargs -I {} ./hanshu.sh -p {} -s 【-I {} 指定了替换字符串。对于每一个命令参数,字符串{}都会被从stdin读取到的参数替换掉】
只要我们把find的输出作为xargs的输入,就必须将 -print0与find结合使用,以字符null('\0')来分隔输出 ,从而统一定界符
find . -type f -name "*.txt" -print0 | xargs -0 rm -f
==============
tr只能通过stdin(标准输入),而无法通过命令行参数来接受输入
ls | tr set1 set2
如果两个字符集的长度不相等,那么set2会不断重复其最后一个字符,直到长度与set1相同。如果set2的长度大于set1,那么在set2中超出set1长度的那部分
字符则全部被忽略。
======交互式的脚本==============
#!/bin/bash
myfun()
{
read -p "your name : " name;
read -p "your age : " age;
echo "hello $name,your age is $age"
if [ $age -gt 18 ]
then
echo "you are ault"
else
echo "you are too young"
read -p "your fave: " fave;
echo "you like $fave"
fi
}
myfun
==================
建立空白文件:touch aa.txt
统计文件行数:wc -l aa.sh
对目录下的文件进行搜索:grep -rn 'bash' ./ 【-r递归目录搜索,-n显示行号】
对多个文件进行搜索:grep "if" aa.sh hanshu.sh
列出匹配文件位于哪些文件中:grep -l "else" aa.sh hanshu.sh
打印出行号:grep -n "if" aa.sh
忽略大小写的搜索:grep -i "IF" aa.sh
同时搜索多个关键词:grep -e "if" -e "else" aa.sh
对于sed有多个关键词时,用一个e就行了,分号隔开:sed -e "s/111/aaa/;s/222/bbb;" sd.txt
排除某些文件进行搜搜:grep "else" . -r --exclude 'aa.sh' 排除某个目录进行搜索:grep "else" . -r --exclude-dir zz
打印匹配结果的后几行用-A,前几行用-B,前后几行用-C :例如 grep "else" . -r -B 3
替换文件中的内容:sed -i 's/you/You/g' hanshu.sh
打印第2列:ll | awk '{print $2}'
====================
tar可以将多个文件和文件夹保存为单个文件
创建压缩文件 : tar -cf tst.tar aa.sh hanshu.sh bb 列出压缩文件中的文件列表:tar -tf tst.tar 解压:tar -xf tst.tar -C zz/bb ---大写的C
gzip只能压缩单个文件或数据流,而无法对目录和多个文件进行归档。因此我们需要先创建tar归档文件,然后再用gzip进行压缩。
gzip tst.tar
gunzip tst.tar.gz
压缩率有9个等级,1~9,压缩等级越高,压缩速度越慢
=============
当然也可以用tar 直接压缩:tar -czf tst.tar.gz file1 file2 file3 解压:tar -xzf tst.tar.gz
======================
rsync -av /home/test/ /home/backups 这条命令将源目录(/home/test)中的内容(不包括目录本身)复制到现有的backups目录中
rsync -av /home/test /home/backups 这条命令将包括源目录本身(/home/test)在内的内容复制到新创建的目录backups中
如果我们在源路径末尾使用/,那么rsync会将sourch_path尾端目录中的所有内容复制到目的端。
如果没有使用/, rsync会将sourch_path尾端目录本身复制到目的端。
0 */10 * * * rsync -avz /home/code user@IP_ADDRESS:/home/backups ---每10小时执行一次,从本地同步到远端,-a表示要进行归档 ;-v表示在stdout上打印出细节信息或进度 ;z表示压缩
=============对文件逐行进行处理
myread() { while read line; do echo $line ; done } myread < ./aa.txt ;
===========/etc/resolv.conf的示例
domain 51osos.com //定义本地域名 search www.51osos.com 51osos.com nameserver 202.102.192.68 //定义DNS服务器的IP地址
nameserver 202.102.192.69 //定义DNS服务器的IP地址
如果不使用DNS服务器,也可以为IP地址解析添加符号名,这只需要向文件 /etc/hosts中加入条目即可
===========
一个网络中的设备如果想同另一个网络中的设备进行通信,就需要借助某个同时连接了两个网络的设备。这个特殊的设备被称为网关
route -n 【-n指定以数字形式显示地址。如果使用-n, route会以数字形式的IP地址显示每一个条目;否则,如果IP地址具有对应的DNS条目,就会显示符号形式的主机名。】
ifconfig输出的最左边一列是网络接口名, 可以在ifconfig后加上某一个接口名,查看此接口的详细信息
============
tst() { for ip in 10.4.5.{1..5} ; --像{start..end}这种记法会由shell
对其进行扩展
do echo $ip; done } tst ;
=======判断是否能ping通
&> /dev/null用于将stderr和stdout重定向到 /dev/null,使对应的信息不会在终端上打印出来。
==============
MAC地址欺骗,机器重启后会失效 ifconfig eth0 hw ether 00:1c:bf:87:25:d5
获取IP地址最简单的方法就是ping给定的域名,然后查看回应信息
在远程主机中执行命令,并将命令输出显示在本地shell中,使用下面的语法:ssh user@host "command1 ; command2 ; command3"
通过FTP传输文件可以使用lftp命令,通过SSH连接传输文件可以使用sftp
只有远程主机上安装有FTP服务器才能使用FTP。
SFTP是一个类似于FTP的文件传输系统,它运行在SSH连接之上并模拟成FTP接口。它不需要远端运行FTP服务器来进行文件传输,但必须安装并运行OpenSSH服务器。
列出端口以及运行在端口上的服务:lsof -i 或者 netstat -tnp
===========
iptables -A OUTPUT -d 8.8.8.8 -j DROP
-A表明向链(chain)中添加一条新的规则,使用的是OUTPUT链,它可以对所有出站(outgoing)的流量进行控制。-d指定了所要匹配的分组目的地址。随后使用-j来使iptables丢弃(DROP)符合条件的分组。
iptables -A OUTPUT -p tcp -dport 21 -j DROP
-p指定该规则是适用于TCP, -dport指定了对应的端口
清除对iptables链所做出的所有改动:iptables --flush
==============
查看内存使用情况:free -h
========
列出文件大小:du file.txt
列出目录大小:du -a DIRECTORY
以标准单位KB、 MB或GB显示磁盘使用情况 ,加上-h 即可 :du -h QH-0.0.77.tar.gz
打印以KB为单位的文件大小: du -k FILE(s)
打印以MB为单位的文件大小: du -m FILE(s)
统计多个文件的大小,加上 -c 即可
du -ch aa.sh hanshu.sh 4.0K aa.sh 4.0K hanshu.sh 8.0K total
=================
只统计当前目录大小:du -h --max-depth 0 ./
统计当前目录及1级子目录大小:du -h --max-depth 1 ./
============== 最大的3个文件
du -ak | sort -nrk 1 |head -n 3
a所有文件; 按k单位计算大小; -n 依照数值的大小排序 ; -r 逆序; -k 1 指定按第几列排序;
[alauda@ip-10-140-10-186 temp]$ du -ak | sort -nrk 1 |head -n 3 1556 . 1528 ./QH-0.0.77.tar.gz 4 ./zz/aa.sh
==================
du提供磁盘使用情况信息,而df提供磁盘可用空间信息。 df的-h选项会以易读的格式打印磁盘空间信息。
============
统计命令执行时间:time command
上次重启时间:last reboot
用uniq去重时,要先排序再去重,如:last |awk '{print $1}' | sort | uniq
每隔2s执行一次ls命令:watch -n 3 ls ./app
===============
查看进程信息 ps -ef 或 ps -afx
========================
打印版本:uname -a Linux cloud2 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
打印主机名: uname -n
cloud2
==============
编辑crontab:crontab -e
查看:crontab -l
删除:crontab -r
星号(*)指定命令应该在每个时间段执行。也就是说,如果*是写在cron作业中的小时字段中,那么命令就会每小时执行一次
在分钟字段使用*/5,可以每5分钟运行一次命令
执行cron作业所使用的权限同执行crontab命令所使用的权限相同。如果你需要执行要求更高权限的命令,例如关闭计算机,那么就要以root用户身份执行crontab。
在cron作业中指定的命令需要使用完整路径。
要在启动时运行命令,请将下面一行加入crontab: @reboot command 【如果需要以root用户的身份运行命令,需要编辑root用户的crontab。 】
==========
创建用户:useradd USER -p PASSWORD
将用户添加到组:addgroup USER GROUP
删除用户:deluser USER
修改密码:passwd USER
添加组:addgroup GROUP
删除组:delgroup GROUP
===========
监视磁盘I/O的工具就叫做iotop ,没有预装,需要自行安装