[每天一个 Linux 命令:系列目录](https://mp.weixin.qq.com/s/h2ySo9WqYT-dXHAyHoB3NA?) ## curl 请求 ```shell # Get 请求 curl http://www.baidu.com # Post 请求 curl -H "Content-Type: application/json" -X POST -d '{"taskId": 123 }' "http://localhost:8080/task/detail" # 参数内容:-H 请求头,-X 请求协议,-d 请求体 ``` ## 日志排查 ```shell # 实时更新日志输出 tail -f /app/tomcat/logs/catalina.out tail -200f /app/tomcat/logs/catalina.out # 查询最近n行的日志 tail -n 30 /app/tomcat/logs/catalina.out # 搜索关键词 # -C 表示同时输出关键词前后各n行的日志 # -A 表示同时输出关键词后面n行的日志 # -B 表示同时输出关键词前面n行的日志 grep -C 10 'OutOfMemoryError' /app/tomcat/logs/catalina.out # 同时grep命令中的文件路径可以使用正则表达式 # 比如搜索最近3天的日志 grep -C 10 'OutOfMemoryError' /app/tomcat/logs/catalina_202109[11,10,09].log # 搜索特定时间段的日志 sed -n '/2021-09-11 12:00:/, /2021-09-11 12:01:/p' /app/tomcat/logs/catalina.out # 从文件末尾开始搜索 tac /app/tomcat/logs/catalina.out | grep -C 1 'OutOfMemoryError' ``` ## 用户 - 超级用户 root 只有一个,home目录在 /root 下,拥有最高权限。 - 普通用户 user 可以多个,home目录在 /home/user 下,拥有部分权限。   **添加用户**  `useradd  user1` **切换用户**  `su - user1`  (加中间"-"的好处在于切换后就能进入用户home目录,也可以不加)  **修改密码**  `passwd [uname]`(不加uname,默认是当前用户) ## 文件权限 ### 权限介绍 Linux中的文件有权限的概念,文件并不是想改就改,想看就看的,需要一定的权限。Linux中将文件面对的人分为三种:分别是**拥有者**,**所属组**,**other**,这三种人有不同的权限,其中other是除了拥有者和所属组之外的人,**拥有者一般用u表示,所属组一般用g表示,other就是用o表示**。对于一个文件,一般的权限就是**读(r),写(w),执行(x)** ### 权限详解 ```shell -rw-rw-r-- 1 liuchuanwei liuchuanwei 0 Aug 12 15:20 tmp.txt ``` tmp.txt 这个文件前面有一行`-rw-rw-r–-` ,一共10位,第一位表示文件类型,"-"是文件,"d"是目录,其余位表示三种用户权限,前三位**拥有者owner**的权限,中三位属于**所属组group**的权限,后三位**其他用户other**的权限。 把这一行拆开,第一个 `-` 表示这个文件是一个普通文件,不是一个目录 第一个 `-` 后面的首个 `rw-` 是文件的**拥有者**具有的权限 第一个 `-` 后面的第二个 `rw-` 是文件的**所属组**具有的权限 第二个 `rw-` 后面的 `r--` 是**other**具有的权限 **拥有者**具有 `rw-` 的权限,这表示拥有者具有读写文件的权限,但是没有执行文件的权限 **所属组**具有 `rw-` 的权限,这表示所属组具有读写文件的权限,但是没有执行文件的权限 **other**具有 `r--` 的权限,这表示other只具有读文件的权限,没有写文件和执行文件的权限 怎么证明拥有者具有rw-的权限? 我们去掉拥有者的rw权限,然后看一下拥有者是否具有读写权限。 ```shell [liuchuanwei@VM-24-15-centos ~]$ chmod u-rw tmp.txt [liuchuanwei@VM-24-15-centos ~]$ cat tmp.txt cat: tmp.txt: Permission denied ``` **Linux中,修改文件权限的命令是chmod** 可以看到,显示Permission denied,这也说明了文件确实有权限这个概念。 修改文件权限不仅可以使用u/g/o +(-) r/w/x 还可以使用8进制的方法。 r权限要么是有,要么是没有,对应2种状态 w权限要么是有,要么是没有,对应2种状态 x权限要么是有,要么是没有,对应2种状态 所以可以用8进制数字转化为2进制来表示权限 例如7的2进制是111,表示3中权限都有。0的二进制是000,表示三种权限都没有 第一个0表示拥有者的权限,第二个0表示所属组的权限,第三个0表示other的权限 **目录的权限也有rwx,目录的权限大部分都与文件的权限一样,但是有一点,进入目录需要有x权限** ### 拥有者和所属组 在文件权限的后面跟的还有liuchuanwei,而且有2个,第一个表示文件的拥有者,第二个表示文件的所属组,除此之外,全部都是文件的other 更改文件的拥有者和所属组的指令是chown和chgrp ```shell [liuchuanwei@VM-24-15-centos ~]$ sudo chown root tmp.txt [sudo] password for liuchuanwei: [liuchuanwei@VM-24-15-centos ~]$ ll total 0 -rw-rw-r-- 1 root liuchuanwei 0 Aug 12 15:20 tmp.txt [liuchuanwei@VM-24-15-centos ~]$ sudo chgrp root tmp.txt [liuchuanwei@VM-24-15-centos ~]$ ll total 0 -rw-rw-r-- 1 root root 0 Aug 12 15:20 tmp.txt ``` 这里有一点需要注意,就是当文件的拥有者和所属组都是root时,普通用户可能不能rwx文件,但是普通用户可以删除文件 ### 将用户添加到sudoer列表 参考:[将用户添加到sudoer列表 - 简书 (jianshu.com)](https://www.jianshu.com/p/71e5184a8241) 普通用户用sudo执行命令时报"xxx is not in the sudoers file.This incident will be reported"错误,解决方法就是在/etc/sudoers文件里给该用户添加权限 1. 切换到root用户下,修改/etc/sudoers权限 2. 编辑sudoers文件 visudo 找到这行 root ALL=(ALL) ALL,在他下面添加xxx ALL=(ALL) ALL (这里的xxx是你的用户名) ps:这里说下你可以sudoers添加下面四行中任意一条 xxx ALL=(ALL) ALL %xxx ALL=(ALL) ALL xxx ALL=(ALL) NOPASSWD: ALL %xxx ALL=(ALL) NOPASSWD: ALL 第一行:允许用户youuser执行sudo命令(需要输入密码). 第二行:允许用户组youuser里面的用户执行sudo命令(需要输入密码). 第三行:允许用户youuser执行sudo命令,并且在执行的时候不输入密码. 第四行:允许用户组youuser里面的用户执行sudo命令,并且在执行的时候不输入密码. 3. 撤销sudoers文件写权限: chmod u-w /etc/sudoers ### sudo sudo 全称 super user do,意思是**干超级用户才能干的事!** 注意:只有加入到 sudoer 列表中的用户才有权使用 sudo 使用 sudo 命令后会提示输入当前用户的密码,还可以使用管道将密码以参数的形式加到命令语句上。如 ```shell echo normal123 | sudo -S sh /app/tomcat/bin/startup.sh ``` -S表示将echo输出的标准流读取,作为输入密码 ## 文件操作 * touch * cat * less * tail * vim ```shell #创建 touch file #查看 cat file cat > file #创建文件 cat f1 f2 > file #合并文件 #分页显示,pageup、pagedown 翻页,q退出 # / 向下查找字符串,? 向上查找字符串 less file #显示文件末尾几行的内容, -n 10 指定行数 tail file tail -f file #循环显示文件末尾内容, f 表示 foreach ``` ## grep 命令 参考:https://www.cnblogs.com/flyor/p/6411140.html ```shell #查找字符串上下10行的内容 Context grep -C 10 "Index: 0, Size: 0" error.log | more #查找字符串后10行的内容 After grep -A 10 #查找字符串前10行的内容 Before grep -B 10 #统计匹配的个数 grep -c #显示行数 grep -n #查看除name之外的 grep -v name ``` ## wl 命令 ```shell #查看行数 wc -l ``` ## tar 命令 ==**必选其中之一参数(而且 一次只能使用其中一个,不能同时使用多个):**== **(这五个参数是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用,但一次只能用其中一个) ** ```diff -c:建立一个压缩文件的参数指令(create 的意思); -x:解开一个压缩文件的参数指令! / -t:查看 tarfile 里面的文件! -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 ``` **特别注意,在参数的下达中, c/x/t/r/u 仅能存在一个!不可同时存在!因为不可能同时压缩与解压缩。** ==**下面的参数是根据需要在压缩或解压档案时可选的。**== ```diff -z:有gzip属性,即需要用 gzip 压缩 -j:有bz2属性,即需要用 bzip2 压缩 -Z:有compress属性的 -v :压缩的过程中显示文件(显示所有过程)!这个常用,但不建议用在背景执行过程! -O:将文件解开到标准输出 -f :使用档名,请留意,在 f 之后要立即接档名!不要再加参数!例如使用『 tar -zcvfP tfile sfile』就是错误的写法,要写成『 tar -zcvPf tfile sfile』才对喔! -p :使用原文件的原来属性(属性不会依据使用者而变) -P :可以使用绝对路径来压缩! -N :比后面接的日期(yyyy/mm/dd)还要新的才会被打包进新建的文件中! --exclude FILE:在压缩的过程中,不要将 FILE 打包! -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。 ``` **例子** ```shell # 这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示创建新的包,-f指定包的文件名。 tar -cf all.tar *.jpg # 这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。 tar -rf all.tar *.gif # 这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。 tar -uf all.tar logo.gif # 这条命令是列出all.tar包中所有文件,-t是列出文件的意思 tar -tf all.tar #这条命令是解出all.tar包中所有文件,-x是解开的意思 tar -xf all.tar #压缩(其中 c 表示create创建,f表示file文件,j表示某种压缩算法 tar -zcvf 压缩文件名.tar.gz 被压缩文件名 #解压,将压缩文件解压到目录中,参数-C必须大写 tar -zxvf 压缩文件名.tar.gz -C 目标目录 #查看打包压缩文件内容 tar tvf 压缩文件名.tar.gz ``` ## 定时任务crontab [每天一个 Linux 命令(50):crontab命令](https://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666540390&idx=2&sn=7902fffb30a421daa77c98908ae03e41&chksm=80dce9cdb7ab60db9a8ac0a6276c0d3e71fe4e782514ef016eb885d5d0ff70085f4f4fda83fb&scene=21#wechat_redirect) **查看crontab服务** * service crond status // 查看服务状态 * service crond start //启动服务 * service crond stop //关闭服务 * service crond restart //重启服务 * service crond reload //重新载入配置 **编辑定时任务文件** crontab -e ```shell # 每天凌晨0点执行 0 0 * * * /opt/tomcat/cleanLogCron.sh ``` ## 时间命令 date ```shell #非常有用的帮助命令 date --help #2022-07-04 date +%F date +%Y-%m-%d #18:15:34 date +%T date +%H:%M:%S ``` ## 格式化文件列表时间格式 ``` ls -lh --time-style=+"%Y-%m-%d %H:%M:%S" ``` ## 查看端口被谁占用了 ```shell netstat -tunlp | grep 8081 ``` ## 查询进程 ```shell ps -ef | grep java ``` ## 硬盘使用情况 ```shell # 查看目录空间占用 directory used # -s 总计,-h human-readable du -sh /usr/local/tomcat # 查看目录下各文件的占用空间大小 du -sh /usr/local/* # 查看硬盘使用情况 disk free # -l local 只显示本地系统 # -h human-readable df -lh ``` ## 查看系统CPU 总核数 = 物理CPU个数 X 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 ```shell #  查看物理CPU个数 cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l # 查看每个物理CPU中core的个数(即核数) cat /proc/cpuinfo| grep "cpu cores"| uniq # 查看逻辑CPU的个数 cat /proc/cpuinfo| grep "processor"| wc -l # 查看CPU型号 cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c # 查看Linux 内核 uname -a # 也可以使用下面的命令来查看Linux的内核 cat /proc/version ``` ## 内存使用情况 ```shell cat /proc/meminfo #查看内存情况 free -h total: 内存总数 used: 已经使用内存数 free: 完全空闲内存 shared: 多个进程共享的内存 buffers: 用于块设备数据缓冲,记录文件系统metadata(目录,权限,属性等) cached: 用于文件内容的缓冲 available:真正剩余的可被程序应用的内存数 ``` ## 查看系统信息 `uname` 意:unix name ```sh [root@Centos ~]# uname -a Linux Centos 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux ``` 信息依次为: 系统名称 sysname 主机名称 nodename 操作系统发行编号 release 系统版本和时间 version 计算机类型 machine 也可以分别通过命令单独获取这些信息: uname -s uname -n uname -r uname -v uname -m * 查看 redhat 系列的版本 `cat /etc/redhat-release` * 查看系统版本 `lsb_release -a` ```sh [root@Centos ~]# lsb_release -a LSB Version: :core-4.1-amd64:core-4.1-noarch Distributor ID: CentOS Description: CentOS Linux release 7.4.1708 (Core) Release: 7.4.1708 Codename: Core ``` * cat /proc/version * cat /etc/issue ## 环境变量 linux下的环境变量可以理解为windows下的环境变量,作用相同。执行某命令时,会从**PATH包含的目录和当前的目录**寻找该命令,如果没找到,则会提示 **command not found** ```shell # 查看环境变量 echo $PATH ``` * **临时有效** ```shell # 这种方式只对本次登陆有效 export PATH=$PATH:/usr/local/mysql/bin ``` * **只对当前用户有效** 在 `~/.bashrc` 文件末尾添加 `export PATH=$PATH:/usr/local/mysql/bin` 另起一个终端 或者 执行 `source ~/.bahsrc` 使环境变量生效 * **永久有效** 在 `/etc/profile` 文件末尾添加 `export PATH=$PATH:/usr/local/mysql/bin` 执行 `source /etc/profile` 只对本次登录生效。 要想永久生效,需要重启系统 `reboot`(==实际上重启也不会生效,这个问题待解决==) ## sshpass 命令 参考 http://linux.51yip.com/search/sshpass https://blog.csdn.net/xiaofang2015/article/details/106895913 sshpass 是一个简单、轻量级的命令行工具,通过它我们能够向命令提示符本身提供密码(非交互式密码验证),这样就可以通过 cron 调度器执行自动化的 shell 脚本进行备份。 参数: -f filename:从文件中获取密码 -d number:使用数字作为获取密码的文件描述符 -p password:指定明文本密码输入(安全性较差) -e 从环境变量SSHPASS获取密码 --- 1、直接远程连接某主机 **sshpass -p {密码} ssh {用户名}@{主机IP}** 2、远程连接指定ssh的端口 **sshpass -p {密码} ssh -p ${端口} {用户名}@{主机IP}**  3、从密码文件读取文件内容作为密码去远程连接主机 **sshpass -f ${密码文本文件} ssh {用户名}@{主机IP}**  4、从远程主机上拉取文件到本地 **sshpass -p {密码} scp {用户名}@{主机IP}:${远程主机目录} ${本地主机目录}** 5、将主机目录文件拷贝至远程主机目录 **sshpass -p {密码} scp ${本地主机目录} {用户名}@{主机IP}:${远程主机目录}**  6、远程连接主机并执行命令 **sshpass -p {密码} ssh -o StrictHostKeyChecking=no {用户名}@{主机IP} 'rm -rf /tmp/test'** -o StrictHostKeyChecking=no 忽略密码提示 7、脚本 sendFileToRemote.sh ```shell #!/bin/bash ##发送文件到其他服务器 source /etc/profile #源文件 srcFile=$1 #目标文件 targetFile=$2 set timeout 3000 #其他服务器 proIpArr=('168.23.12.1' '168.23.12.2' '168.23.12.3') dte=$(date +%Y%m%d) #遍历服务器 for ip in ${proIpArr[*]} do #备份原文件 sshpass -e ssh -o "StrictHostKeyChecking no" root@$ip "mv ${targetFile} ${targetFile}_${dte}.back" #传送文件到远程服务器 sshpass -e scp -o "StrictHostKeyChecking no" $srcFile root@$ip:$targetFile RETVAL=$? if [ $RETVAL -ne 0 ]; then echo $ip"文件传输失败" exit else echo $ip"文件传输成功" fi done ``` ## 防火墙 **service方式** 1. 查看防火墙状态 `service iptables status` 2. 开启防火墙 `service iptables start` 3. 关闭防火墙 `service iptables stop` 4. 重启防火墙 `service iptables restart` 5. 永久关闭防火墙 `chkconfig iptables off` 6. 永久关闭后重启防火墙 `chkconfig iptables on` **iptables方式** 1. 查看防火墙状态 `/etc/init.d/iptables status` 2. 暂时关闭防火墙 `/etc/init.d/iptables stop` 3. 重启防火墙 `/etc/init.d/iptables restart`