作者:fbysss
QQ:溜酒酒吧酒吧吾散
blog:blog.csdn.net/fbysss
声明:本文由fbysss原创,转载请注明出处
前言:
linux基本命令就不在这里列出。本文记录的主要是
1.容易忘记的知识点
2.常用的、需求强烈的技巧
3.疑难杂症
旨在备忘、提高工作效率。希望我的总结对你有所帮助
一、vi技巧:
vi的时候,如果内容里面有注释,在某些终端里面,贴进去就是格式错乱的。
解决:vi中输入:set paste回车,然后粘贴就可以了。
vi
大文件,半天打不开,而且如果是在线的服务器,几个G的大文件可能直接撑爆服务器,影响服务。
解决:用less替代。v进入编辑模式。
有时候使用普通用户身份编辑了一个需要
root权限读写的文件,无法保存。使用 :w !sudo tee %可保存——保存后,然后q!退出。
vi中复制:(n)yy复制n行,p粘贴,d$删除当前光标到行尾y$复制到行尾
特殊字符处理:遇到一个奇怪的问题。在sublime中,或者apple的文本编辑中,制作纯文本,也同样会有问题,后来用vi发现文本中包含了一大堆怪异的字符,显示为<200b>
查找200是查不到的。这是一个字符。原来是unicode字符。使用
/\%u200b可以查到。
清除::%s/\%u200b//g
二、压缩相关:
tar zxvf 解压 gz文件 tar xvf解压tar文件
tar cvf 加压
tar tvf 不解压查看文件列表
unzip解压 zip文件
unzip -l 不解压查看文件列表
解压单独的文件,并覆盖现有文件。unzip -j -o test.zip “WEB-INF/classes/validator.xml”
unzip -j test.zip "WEB-INF/classes/validator.xml"
加压并排除某些文件,用-x
cd test && zip -o ../../test.zip -r ./* -x ./WEB-INF/lib/*.*
注意:曾经出现过,感觉排除总是无效,原因是原来的zip没有删除,结果写进去只是更新,原来的东西不会被删掉。
注意这个 -o 参数,并不是覆盖的意思,而是:-o make zipfile as old as latest entry,
将压缩文件内的所有文件的最新变动时间设为压缩时候的时间
三、进程及端口相关
查找某个进程参数并杀死。假设进程参数中包含 -a schedule ,kill:kill -9 $(pgrep -f " -a schedule")
其中,-f 是从进程的参数中找关键字。因为往往我们需要的是精确的匹配,比如如果不加-f,就是只查找进程名称。java可能有多个。
那就相当于killall
=======================
附windows下常用命令
=======================
netstat -ano |findstr "端口号" 查看端口号占用进程信息
tasklist |findstr "任务编号" 查看任务名称
tskill 程序名 杀掉进程
ntsd -c p -q pid 杀掉进程
=======================
netstat -tlnp |grep 8080 查看进程号
netstat -tlnpa |grep 22|grep 公网IP 查看哪些外网机器连接了本服务器,用于诊断木马
netstat -A inet -p |grep 8080 可以用host显示ip地址。sudo
netstat -ano
lsof -i:8080查看端口号所在进程
top按内存消耗排序:按大写M
有时候一个端口,希望多个ip都能绑定它。则么办呢,比如内网和外网都想绑定。
解决:直接使用0.0.0.0地址。
当然,真正在生产环境的时候,要注意安全性,反而要缩小其绑定范围。
四、查找相关
grep 有时候需要打印出前后几行,怎么办?使用-C参数即可。
grep Exception -C 10 logs/catalina.out
grep -v 不包括某个keyword 非常实用。
如果有很多的结果,只想看前n个,用
grep Exception -C 10 logs/catalina.out|head -n
统计的话,自然是加上 |wc -l
查找,并逐条进行处理的例子
find ./ -name "*.c" | awk -F "." '{print $2}' | xargs -i -t mv ./{}.c ./{}.h
find / -iname "*.log" |xargs grep "keyword"
如果是要查找某个目录下的
所有文件,用*.*是不行的。用空格" "即可,但这样的问题还会查出来子目录,并总提示xxx is a directory,很烦人。
解决:指定文件类型为普通文件而不是子目录。find . -type f |xargs grep hello 查找子目录的名字,则find . -type d -iname dirname
查找时排除某些目录
find . -type f -name "*config*" ! -path "./tmp/*" ! -path "./scripts/*" ! -path "./node_modules/*"
Explanation:
find . - Start find from current working directory (recursively by default)
-type f - Specify to find that you only want files in the results
-name "*_peaks.bed" - Look for files with the name ending in _peaks.bed
! -path "./tmp/*" - Exclude all results whose path starts with ./tmp/
! -path "./scripts/*" - Also exclude all results whose path starts with ./scripts/
查找文件,并将gbk转换为utf 8,批量处理
find . -iname "*.txt" |xargs -i{} iconv -f gbk -t utf8 -o {}.utf8 {}
注意*.txt一定要引号引起来。
sudo find /home -mtime -1 ! -path "/home/xxx/*"
查找里面排除某些文件夹。可以连续使用多个! -path,注意排除路径最后一定要加*。
在gz文件中查找,用
zgrep,不用解压
五、curl相关
curl 有时候获取不到数据。用—verbose查看详细信息。
curl 默认参数获取网页,如果有跳转,会返回302,得不到内容。此时应该加-L参数,就OK了。牛!
curl -x ip:port http://xxxxx.html -x是加代理服务器。
六、统计相关
df -k -h 查看分区大小。注意-h要在后面
du -h update --max-depth=1 查看文件夹update大小。 命令较长不好记。其实打一遍之后,以后!du就可以。
du -hs 目录 查看某个目录的size。
sort -k列号 -r反序
ls -Sr -h能够按大小顺序排序显示
ls -Sr -h |awk {'print $5'}只打印大小列
查看某一列加和:文件大小加和
ll *.jpg |awk '{sum+=$5} END {print "total = ", sum/1024/1024}'
删除最后一行 awk '{$NF="";print}' test.txt >test.txt
查看剩余内存
free -m |grep "Mem" | awk "{print $2}"
查看进程,按内存从大到小
ps -e -o "%C : %p : %z : %a"|sort -k5 -nr
查看进程,按CPU利用率从大到小排序
ps -e -o "%C : %p : %z : %a"|sort -nr
查看最近一周修改过的文件
find /usr/bin/ -ctime -7
查重复请求
需要看18日0点的数据,在日志文件中,有多少重复的请求--同一url不同时间。
grep "18\/Jan\/2017:00" access.log |awk '{print $7}' |sudo tee xxx.log
然后需要使用
sort
和
uniq
sort
xxx.log |uniq|wc -l就能得到排重后的条数。
查找nginx中,除了最后一列,其他都相通的行,并打印重复次数,按次数大小排列
cat access.log | cut -d" " -f 1-13 | sort | uniq -c | sort -rn | head -100
求符合条件的行数有多少
cat access.log-20170515 | cut -d" " -f 1-13 | sort | uniq -c | sort -rn | awk '{if($1>=2){print $0}}' |wc -l
对第一列求和
cat access.log-20170514 |grep pull| cut -d" " -f 1-13 | sort | uniq -c | sort -rn | awk '{if($1>=2){print $0}}' |awk '{a+=$1}END{print a}'
./access.log-20170522:1.180.214.23 - - [21/May/2017:06:36:12 +0800] "POST /user/reg?os=1&v=1.0.0.052003.222&net=1&appname=xxx&dcid=1000&tempid=temp-939de0c4f578427 HTTP/1.1" 200 67 uid=temp-939de0c4f578427&did=864184030957283&lang=1&pmodel=M5Note&osversion=6.0&vendor=%E4%B8%AD%E5%9B%BD%E8%81%94%E9%80%9A "-" "okhttp/3.4.1" "-" 10.25.161.131:8080 "200" "0.016
查出所有的pmodel
cat reg.log |sed -E 's/.*pmodel=([[:alnum:]]*).*/\1/'
nl filename | sort -nr | cut -f2 倒序行输出
17:38:00 - 17:42:59 这5分钟的接口访问统计
sed -n '746137,754459p' /var/log/nginx/access.log | awk '{ print $7 }' | cut -d? -f1 | sort | uniq -c | sort -rn
七、重命名
批量修改扩展名:希望把所有mp4文件扩展名修改为data
rename mp4 data *.mp4
八、定位
which 命令 查看文件所在路径
whereis
cd - 回到上一个目录(通过cd切换过来的上一个位置)
获取正在执行的脚本的绝对路径
basepath=$(cd `dirname $0`; pwd)
echo $basepath
九、重定向相关
> xxx.log清空某个log ,在sudo用户下,前面的命令不能用。需要使用echo ""|sudo tee xxx.log
tee 命令的 “-a” 选项的作用等同于 “>>” 命令,如果去除该选项,那么 tee 命令的作用就等同于 “>” 命令。
只输出错误信息到日志文件
nohup ./program >/dev/null 2>log &
什么信息也不要
nohup ./program >/dev/null 2>&1 &
十、服务相关
/etc/init.d下,可以放置脚本,用chkconfig --add servername安装成linux服务,用service servicename start的形式启动
十一、alias
在root用户环境下:vi ~/.bashrc
会看到:
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
当然,使用alias查看,还有其他的别名
linux下cp被alias为cp -i,如何才能拷贝的时候忽略提示?
命令前面加一个斜杠,就是原生命令了。
\cp xxxxx yyy -rf
十二、sudo相关
sudo source /etc/rc.local出现错误。
sudo: source: command not found
解决:
sudo bash或者sudo -s 切换到root用户登录。然后执行。
原因是source这个命令, 是一个shell builtin command
十三、引号
单引号如何嵌套?
比如本意是echo 'select * from user where birthday=\'19800101\'' ,但实际不好使。
解决:分段输出。
echo 'select * from user where birthday='\'19800101\'
或者
echo 'select * from user where birthday='\''19800101'\'
另外:变量在单引号中是无效的。双引号中OK。
比如current=`date "+%Y-%m-%d %H:%M:%S"`
echo '$current' 结果是$current
echo "$current" 结果是2016-05-08 23:34:34
十四、常用服务相关
Nginx:
当修改了hosts文件之后,如果nginx.conf中涉及到解析hosts文件,需要nginx -s reload一下才生效。
alias 和root的重要区别:
如果是location /
必须使用root 。否则会报错:403
iterm2
iterm2块操作:
Command + Option + Left Mouse
iterm快速连接:相信其他终端也有类似的功能。
iterm如何快捷安全的使用的ssh?这样设置就没必要每次输入密码:
vi ~/.ssh/config
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
ControlPersist yes
Host de
HostName xxx.com
User design
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 80
Host gd
HostName www.xxx.com
User fbysss
IdentityFile ~/.ssh/id_rsa
ServerAliveInterval 80
如果网络断开之后出现连接不上,可尝试pkill master然后再试
ssh
问题:主机ping的速度很快,但是ssh连接非常慢。
sudo vi /etc/ssh/ssh_config
#GSSAPIAuthentication yes 设置为no
再连接会变得更快。
如果这台机器报错:
Unsupported option GSSAPIAuthentication
则直接注释该行。
http://www.2cto.com/os/201410/343244.html
这里提到,实际上是要修改客户端的这个设置。所以嘛改了服务器之后,在服务器上ssh提示有问题。
不过,为啥改了就感觉快很多呢?待探究
十五、前后台相关
通常,一个普通的耗时命令或者服务程序,前面加nohup ,后面加&,确保在后台运行
bg命令和fg命令可以让shell命令在前台后台切换。比如rsync一个大文件,不能直接用&来弄,因为要输入用户密码,否则就一点都传不了。
正确的做法是,先输入命令,回车
输入用户名密码。
然后CTRL+Z,就切换到后台并挂起(暂停)。bg则让后台程序继续执行。——以前还以为ctrlz直接换后台运行呢
然后运行bg可以看到在后台运行的命令行
fg可切换回来。
http://www.jb51.net/LINUXjishu/65800.html
我们看实例:rsync -avzP xxx0413.sql.tar.gz sss@sg1:/home/fbysss/xxx0413.sql.tar.gz这个命令行,回车之后,输入用户名密码
然后按CTRL+Z,显示
[1]+ 已停止 rsync -avzP xxx0413.sql.tar.gz sss@sg1:/home/fbysss/xxx0413.sql.tar.gz
实际上,就是告诉我们,编号为1的进程已经挂起,到目标主机上看这个文件,的确不再变化大小,说明确实挂起了。
然后,运行bg 1或者bg,因为只有一个,所以bg==bg1
就又开始了。
在目标主机上,要使用ls -a才能看到,是隐藏的文件。
十六、常用脚本
经常需要年月日时分秒这样的文件名
日期:获取下一天,前一天
date -d 'next day'
date -d '1 day ago'
currentTime.sh:
today=`date +%Y%m%d`
current=`date "+%Y-%m-%d %H:%M:%S"` #获取当前时间,例:2015-03-11 12:33:41
timeStamp=`date -d "$current" +%s` #将current转换为时间戳,精确到秒
currentTimeStamp=$((timeStamp*1000+`date "+%N"`/1000000)) #将current转换为时间戳,精确到毫秒
echo $today-$currentTimeStamp
有时候会报错:
数值计算提示数值太大不可为算数进制的基
解决:
http://forum.ubuntu.com.cn/viewtopic.php?f=21&t=468838
注:$是将括号中的内容变成一个表达式。
改进版:
today=`date +%Y%m%d`
current=`date "+%Y-%m-%d %H:%M:%S"` #获取当前时间,例:2015-03-11 12:33:41
timeStamp=`date -d "$current" +%s` #将current转换为时间戳,精确到秒
ntime=$(echo `date "+%N"`|sed -r 's/^0+//')
#echo "ntime:"$ntime
currentTimeStamp=$((timeStamp*1000+$ntime/1000000)) #将current转换为时间戳,精确到毫秒
echo $today-$currentTimeStamp
startbak.sh
basepath=$(cd `dirname $0`; pwd) #得到当前shelljiao'b所在的目录
timestamp=`$basepath/currentTime.sh`
mysqldump -uxxxx -pxxxx xxxdbname >$basepath/commonsec$timestamp.sql
监控tomcat并发送报警邮件的脚本:
monitor_tomcat.sh
#!/bin/sh
basepath=$(cd `dirname $0`; pwd)
PATH=/usr/sbin:/usr/bin:$PATH
export PATH
#注意,在crontab中运行,path是不生效的,需要重新定义一下。
n=`ps -ef|grep java|grep -c apache-tomcat-7.0.65`
if [ $n -eq 0 ];then
# cd /opt/tomcat/bin #跳转到tomcat的bin目录
# ./startup.sh & #启动
echo `date`":api server has down." >> $basepath/error.log
echo "===================catalina error log================" >> $basepath/error.log
echo `tail -1000 $CATALINA_HOME/logs/catalina.out` >> $basepath/error.log
echo `tail -1000 $CATALINA_HOME/logs/catalina.out` > $basepath/error_now.log
echo `date`":api server has down."|mail -s appserverdown -a $basepath/error_now.log
[email protected]
service tomcat start
exit
else
#echo $n
exit
fi
bash 的if语句,要注意中括号里面左右都要有空格,if和中括号之间要有空格。
字符串和字符串比较用等号,数字使用-eq
integer expression expected
定期在凌晨删除n天以前的文件
remove_bak.sh
find /datadisk1/dbbackup -name 'xxdb*' -mtime +n -exec rm -rf {} \;
定时器
sudo crontab -e
01 01 * * * /home/fbysss/autobackup/start.sh && echo `date`:" auto backup database script." >>/home/fbysss/autobackup/backup.log
*/5 * * * * /home/fbysss/autobackup/monitor_tomcat.sh #5分钟检测一次
01 07 * * * /datadisk2/autobackup/remove_bak.sh
从url中获取purefilename:
方法1:
fbname
=
$
(
basename
"$fullfile"
|
cut
-
d
.
-
f1
)
方法2:
s=/the/path/foo.txt
echo ${s##*/}
foo.txt
s=${s##*/}
echo ${s%.txt}
foo
echo ${s%.*}
foo
其他
ssh-keygen产生key文件,私钥公钥文件分别在~/.ssh/id_rsa,id_rsa.pub中
cat /etc/passwd 可以看某个用户的宿主目录——未必都是home
rpm -rvh 安装 rpm -ql rpmname查看是否安装 rpm -e 卸载
yum安装
ll --full-time查看完整文件时间
hostname 域名,nslookup域名,可以用来查找DNS
md5sum命令可以生成MD5码。 格式: md5sum filepath
md5sum xxx.apk|cut -d ' ' -f1
macbook中:直接使用md5命令
防火墙开放
vi /etc/sysconfig/iptables
添加
-A INPUT -m state --state NEW -m tcp -p -dport 21 -j ACCEPT
然后,sudo service iptables restart
如果要限制某个IP才能访问,可以用-s参数+ip地址
diff命令,是一个很好的东西。我们在服务器上更新文件,有时候需要比较一下变动了哪些。直接使用diff两个文件就可以了。
安装pip:
sudo yum -y install epel-release
sudo yum -y install python-pip
netstat -A inet
通过systemctl来启动的服务,放置在
/etc/systemd/system/tomcat.service
或者
/usr/lib/systemd/system 下
有时候在编辑/etc/profile的时候,不小心可能写成这样export PATH=PATH:/usr/java/bin,实际上应该为export PATH=
$PATH:/usr/java/bin。这时候,运行任何命令可能都出现类似
/usr/bin/env: sh: 没有那个文件或目录 这样的提示。
解决:export PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin,然后再vi /etc/profile修正,然后source /etc/profile就好了。