Linux和Shell基础

447 阅读21分钟

Linux的目录结构

目录 意义
/bin (/usr/bin, /usr/local/bin) Binary的缩写,这个目录存放着最常使用的命令。
/sbin (/usr/sbin, /usr/local/sbin) s是super user的意思,这个目录存放着系统管理员使用的系统管理程序。
/lib, /lib64 (/usr/lib, /usr/lib64) 系统开机所需要的最基本的动态链接库。
/lost+found 一般是空的,当系统非法关机后,这里就存放了一些文件。
/etc 所有系统管理所需要的配置文件和子目录,比如redis.conf。
/usr 用户的很多应用程序和文件存放的目录。
/boot 存放启动linux时使用的一些核心文件,包括一些连接文件和镜像文件。
/proc 这是一个虚拟目录,它是系统内存的映射,访问这个目录可以获取系统信息。
/srv service的缩写,该目录存放一些服务启动之后需要提取的数据。
/sys linux内核2.6版本引入,该目录下安装了一个新的文件系统。
/tmp 用来存放临时文件。
/dev linux下一切皆文件,这部分文件是对硬件的抽象。
/media linux会自动识别一些设备,比如U盘或者光驱等,当识别成功后,Linux会把识别到的设备挂载到此目录下。
/mnt Mount的缩写,挂接光驱、USB设备的目录,加载后,会在mnt里多出相应设备的目录。
/opt 这是给linux主机安装额外软件所准备的目录,比如安装Oracle数据库就可以放在此目录下,默认为空。
/usr/local 这是另一个给linux主机安装额外软件的目录,一般通过源代码编译安装的都放在这个目录下,比如redis/MySQL。
/var 这个目录下存放不断扩充的东西,经常需要修改的东西一般都放在此目录下,比如日志文件。

远程登陆Linux

  首先需要在linux上开启sshd服务,它会监听22端口。ssh是secure shell的简称。

语法:
    ssh 用户名@IP
   # ssh如果登陆出错可以查看是否存在 ~/.ssh/know_ssh,删除该文件看看能否解决问题
  
实例:
    ssh archer@192.168.33.24

  默认情况下,CentOS已经开启了sshd.service,我们可以在终端下输入setup命令(需要root权限),进入Linux的System Service,列表中有前置星号(*)的就是已开启的服务。在这个列表中,按F1可以查看服务介绍,按space可以选中/取消服务,按tab可以退出列表。

  注意,如果使用Xshell连接不上远程Linux,考虑关闭CentOS的firewall:

停止firewall
# systemctl stop firewalld.service 
禁止firewall开机启动
# systemctl disable firewalld.service 
编辑selinux的配置文件
# vi /etc/selinux/config
注释掉下面两行
#SELINUX=enforcing 
#SELINUXTYPE=targeted 
增加一行
SELINUX=disabled 
重启主机
# sync 
# shutdown -r now

用户创建

# 创建一个用户名为xiaoming的用户,他家目录为/home/xiaoming
# 同时创建名为xiaoming的用户组,将用户xiaoming加入到用户组xiaoming中
useradd xiaoming

# 创建一个用户名为denny的用户,指定他的家目录为/home/archer
# 同样也会创建名为denny的用户组并将用户denny加入进去
useradd -d /home/archer denny

# 创建用户mayun,他的家目录是/home/mayun,并指定其属于组alibaba
useradd -g alibaba mayun

# 为用户xiaoming创建一个登陆密码
passwd xiaoming

用户删除

# 删除用户xiaoming但保留其家目录
userdel xiaoming

# 删除用户xiaoming及其家目录
userdel -r xiaoming

查询用户信息

# 查询用户archer的信息
id archer

输出 uid=1000(archer),gid=1000(archer),groups=1000(archer)

切换用户

# 使用su命令切换用户,su是switch user的缩写
su root 
su - root 

su命令与su - 命令的区别:

  1. su命令:su只是切换了root身份,但Shell环境仍然是普通用户的Shell 而su -连用户和Shell环境一起切换成root身份了。只有切换了Shell环境才不会 现PATH环境变量错误,报command not found的错误。
  2. su - 命令:su切换成root用户以后,pwd一下,发现工作目录仍然是普通用户的工作目录;而用su -命令切换以后,工作目录变成root的工作目录了。

用户组

# 新增用户组
groupadd alibaba

# 删除用户组
groupdel alibaba

# 修改用户所属的组,新的组必须先存在
# 新建denver组
groupadd denver
# 将melo移交到denver组
usermod -g denver melo

用户和组的相关文件

/etc/passwd

用户的配置文件,记录着用户信息。

# /etc/passwd中的一行对应如下
archer:x:1000:1000:Denny Archer:/home/archer:/bin/bash

用户名:密码标志:uid:gid:注释性描述:家目录:登陆的Shell
  1. Linux内部是通过uid来区别用户的,用户名只是为了方便系统使用者, 用户名和uid的对应关系就在/etc/passwd文件中定义。
  2. Linux用户的登陆密码存储在/etc/shadow文件中,密码标志只有一个"x"代表 用户是拥有密码的,如果把"x"删掉,系统就会认为此用户没有密码,进而只通过 输入用户名就可以登陆系统。
  3. uid为0表示root用户,如果把某个用户的uid改为0,那么这个用户就会变成root 用户。在Linux中,1~499是系统保留的,用来运行系统服务。
  4. 登陆的shell可以理解为用户登陆后所拥有的权限,即这个用户能干什么。比如 如果是标准shell(/bin/bash),那这个用户能做普通用户能做的所有事情,如果改成 /sbin/nologin,那这个用户就不能登陆了,因为/sbin/nologin是禁止登陆的shell。

/etc/shadow

口令配置文件

# /etc/shadow中的一行对应如下
archer:$6$qDAYQCfVWxUkc10r$obR4MmplCe2kxoHYHUp.gimZAOihAogC0::0:99999:7:::

用户名:加密后的密码:密码最后修改日期:密码修改间隔:密码有效期:密码修改到期前的警告天数:密码过期后的宽限天数:账号失效时间:保留,暂未使用
  1. 如果手工修改加密后的密码,会导致算不出原密码,进而导致该用户无法登录, 基于此,我们可以在密码前添加 ! 或 * 来使密码失效从而限制用户登陆。
  2. 如果加密的密码上是 "!!" 或者 "*", 代表没有密码不能登陆,如果创建 新用户时没有设置密码,那么也是"!!",因而也不能登陆。
  3. 密码修改间隔如果是0表示可以随便修改,如果是10表示10天内不能再次修改, 这个10天是相对于密码最后修改日期而言的。
  4. 密码有效期默认是99999,可以理解为永久有效,如果是90,就是说90天之后必须 再次修改密码,否则不能登陆,这个90天也是相对于密码最后修改日期而言的。
  5. 密码修改到期前的警告天数要和密码有效期相比,就是密码到期前需提前几天修 改。默认值是7,也就是说从密码到期前的7天开始,每次登录系统都会警告该用户 修改密码。
  6. 密码过期后的宽限天数也就是说密码过期后,用户如果还是没有修改密码,那么 在宽限天数内用户还是可以登录系统的;如果过了宽限天数,那么用户就无法再使用 该密码登录了。天数如果是10,则代表密码过期10天后失效;如果是0,则代表密码 过期后立即失效;如果是 -1,则代表密码永远不会失效。
  7. 账号失效时间,这里也要是时间戳(天数,相对于1970.1.1),如果账号过期了, 即使密码没有过期,账号也不能使用。

/etc/group

组配置文件

# /etc/group中的一行对应如下
archer:x:1000:archer

用户名:密码标志:gid:组内成员列表

指令运行级别

Linux默认提供7个运行级别(runlevel):

  • 0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
  • 1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
  • 2:多用户状态(没有NFS)
  • 3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
  • 4:系统未使用,保留
  • 5:X11控制台,登陆后进入图形GUI模式
  • 6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动

运行级别的配置文件是/etc/inittab。CentOS 7已经不使用运行级别了,而是改用 target,默认提供两种target:

  • multi-user.target: 类似于runlevel 3
  • graphical.target: 类似于runlevel 5
# 查询默认的target
 systemctl get-default

# 设置默认的target
 systemctl set-default TARGET.target

mkdir

描述:
 创建文件夹
 
参数:
 -p/--parents参数用来创建多级目录
 
实例: 
 # 在当前目录下创建war3文件夹
 mkdir war3
 
 # 在当前目录下创建games文件夹,再在games下创建war3文件夹
 mkdir -p games/war3

rmdir

描述:
 删除*空*文件夹,如果文件夹非空,则不能删除。
 
参数:
 -p:删除多级目录
 
实例:
 # 删除/home/archer下的dog目录
 rmdir /home/archer/dog
 
 # 删除当前目录下的games文件夹和games下的war3文件夹
 rmdir -p games/war3

rm

描述:
 删除文件或文件夹,默认不删除文件夹,可以通过参数来实现。
 
使用:
 rm [option]... file/dir... # ...表示多个
 
参数:
 -f:强制删除,不管有没有文件。
 -r:递归删除,可以删除文件夹及文件夹里面的内容
 
# 实例:
 # 删除当前文件夹下的log.txt
 rm log.txt
 
 # 如果文件名以-开头,比如-log.txt
 rm ./-log.txt
 
 # 删除文件夹games下的所有内容
 rm -rf games

cp

描述:
 拷贝文件或文件夹。

使用:
 cp src dest # 将src拷贝到dest,dest也是普通文件名而不是文件夹
 cp src... dir # 将多个文件拷贝到指定文件夹
 
参数:
 -r:递归复制整个文件夹
 -a: 复制文件和目录,以及它们的属性,包括所有权和权限。通常,复本具有用户所操作文件的默认属性。
 -u/--update: 当把文件从一个目录复制到另一个目录时,仅复制目标目录中不存在的文件,
 或者是文件内容新于目标目录中已经存在的文件。
 
实例:
 # 将当前文件夹下的log.txt复制到logs下的logback.txt
 cp log.txt logs/logback.txt

 # 将1.txt 2.txt 3.txt复制到logs文件夹
 cp 1.txt 2.txt 3.txt logs
 
 # 将logs文件夹复制到logback文件夹
 cp -r logs logback
 
 # 将logs目录下的所有文件都复制到logback目录下
 cp logs/* logback
 
 # 仅向logback目录中复制其不存在的或已经存在但是更新的文件
 cp -u logs/* logback

mv

描述:
 移动或重命名文件
 
参数:
 -u/--update: 当把文件从一个目录移动另一个目录时,只是移动不存在的文件,
 或者文件内容新于目标目录相对应文件的内容。

使用:
 mv src dest # 重命名src为dest
 mv src... dir # 将多个文件移动到dir

实例:
 # 将当前文件夹下的logbak.txt重命名为log.txt
 mv logback.txt log.txt
 
 # 将1.txt 2.txt移动到logs文件夹
 mv 1.txt 2.txt logs

cat

描述:
 查看文件内容,以只读的方式打开,不能修改
 
参数: 
 -n:输出行号
 -A: 输出不可见字符
 
实例:
 # 查看spring.log的内容并打印在标准输出上
 cat -n spring.log
 
 # 由于cat指令会把文件内容一次性输出到控制台上,如果需要分页显示,
 # 可以接上more或less
 cat -n ~/.bash_history | less

less

  分屏查看文件内容。less指令在显示文件内容时,并不是一次将整个文件都加载之后才显示,而是按需加载,对于大型文件来说效率较高。常用快捷键有:

  • space: 向下翻页
  • PgUp: 向上翻页
  • PgDn:向下翻页
  • /keyword:往下搜索关键字,n下一个,N上一个
  • ?keyword:往上搜索关键字,n上一个,N下一个

>指令和>>指令

 >: 输出重定向
 >>: 追加
 
 # 将ls输出的内容覆盖写入a.txt
 ls -l > a.txt 
 
 # 将ls输出的内容追加到a.txt末尾
 ls -l >> a.txt
 
 # 将/etc/profile的内容覆盖写入/home/archer/Documents
 # 下的profile.txt
 cat /etc/profile > /home/archer/Documents/profile.txt

小技巧

当我们使用“>”重定向符来重定向输出结果时,目标文件总是从开头被重写。因此,如果我们需要删除一个文件内容(或者创建一个新的空文件),可以使用这样的技巧:

# 简单地使用重定向符,没有命令在它之前,这会删除一个已存在文件的内容或是创建一个新的空文件
[archer@localhost ~]$ > output.txt 

重定向标准错误

重定向标准错误缺乏专用的重定向操作符。重定向标准错误,必须参考它的文件描述符。在shell中,标准输入,标准输出和标准错误的文件描述符分别是0,1,2,因此可以这样重定向标准错误:

# 标准错误的文件描述符(2)紧贴在重定向符(>)之前
ls -l /bin/usr 2> ls-output.txt  # /bin/usr并不存在,因此会产生一条出错信息

有时候需要捕捉一个命令的所有输出到同一个文件,因此需要同时重定向标准输出和标准错误,可以这样执行联合重定向:

# 使用单单一个表示法 &> 来重定向标准输出和错误到文件 lsoutput.txt
ls -l /usr/bin &> ls-output.txt

如果不想要一个命令的输出结果,可以将其重定向到一个特殊的文件——"/dev/null"。这个文件可以接收输入,但对输入不做任何处理:

#  丢弃ls的错误信息
ls -l /bin/usr 2> /dev/null

重定向标准输入

# 使用“<”重定向操作符,把标准输入源从键盘改到文件log.txt
cat < log.txt

虽然执行结果和将log.txt作为参数传递给cat是一样的,但是这种方式是将log.txt作为标准输入源。

head

描述: 
 显示文件的开头部分,默认情况下显示前10行。
 
参数:
 -n: 显示前多少行
 
实例:
 # 显示/etc/profile的前5行
 head -n 5 /etc/profile

tail

描述: 
 显示文件的结尾部分,默认情况下显示最后10行。
 
参数:
 -n: 显示最后多少行
 -f: 随着文件的增长输出附加的数据,通过监听文件描述符
 -F: 随着文件的增长输出附加的数据,通过监听文件名
 
实例:
 # 显示/etc/profile的最后5行
 tail -n 5 /etc/profile
 
 # 输出log.txt的最后10行,并跟踪其更新
 tail -f log.txt

find

描述:
 递归的遍历指定文件夹,将满足要求的文件或文件夹显示在终端上。
 
用法:
 find [搜索路径] [参数]
 
参数:
 -name: 按名称搜索
 -user: 按所属用户搜索
 -size: 按大小搜索
        +10M 大于10M
         10M 等于10M
        -10M 小于10M

实例:
 # 搜索整个文件系统中大于20M的文件
 find / -size +20M
 
 # 在当前文件夹下搜索log.txt
 find . -name log.txt
 
 # 在/home/archer文件夹下搜索所有的txt文件
 find /home/archer *.txt
 
 # 搜索所有属于archer的文件
 find / -user archer

zip/unzip

描述:
 zip用于压缩文件或文件夹

用法:
 zip [OPTION...] xxx.zip [FILE/DIR...]

参数:
 -r: 递归压缩,即压缩目录
 
实例:
 # 压缩log.txt
 zip log.zip log.txt
 
 # 压缩a.log和b.log到logs.zip
 zip logs.zip a.log b.log

 # 压缩logs文件夹
 zip -r logs.zip logs
描述:
 unzip用于解压缩

用法:
 unzip [参数] xxx.zip

参数:
 -d: 解压缩到指定文件夹
 
实例:
 # 解压log.zip
 unzip log.zip

 # 解压到logs文件夹
 unzip -d logs log.zip

tar

描述:
 打包指令
 
用法:
 tar [OPTION...] [FILE...]

参数:
 -c: 产生.tar文件
 -v: 显示详细信息
 -f:指定压缩后的文件名
 -z: 打包的同时进行压缩
 -x: 解包.tar文件
 -C: 指定文件夹
 
实例:
 # 将a.log和b.log打包进logs.tar
 tar -cf logs.tar a.log b.log
 
 # 将a.log和b.log打包进logs.tar并使用gzip压缩
 tar -zcf logs.tar.gz a.log b.log
 
 # 对/home/archer目录下的所有文件进行打包并压缩
 tar -zcvf archer.tar.gz /home/archer
 
 # 解包logs.tar.gz到当前文件夹
 tar -zxvf logs.tar.gz
 
 # 解包logs.tar.gz到logs文件夹(必须存在)
 tar -zxvf logs.tar.gz -C logs

chown

描述:
 修改文件所有者
 
用法:
 chown [OPTION...] [OWNER][:GROUP] FILE...
 
参数:
 -R:递归修改,用于文件夹
 -h: 影响符号连接

实例:
 # 将logs文件夹由root所有变为archer所有
 # 仅改变文件夹所有权,文件夹里的东西不受影响
 chown archer logs
 
 # 将logs文件夹及其下的所有东西变为archer所属
 chown -hR archer logs
 
 # 将a.log的所有者和所属组均改为archer
 chown archer:archer a.log

chgrp

描述:
 修改文件所属组
 
用法:
 chgrp [OPTION...] [GROUP] FILE...
 
参数:
 -R:递归修改,用于文件夹
 -h: 影响符号连接

实例:
 # 将a.log的所属组改为archer
 chgrp archer a.log
 
 # 将logs文件夹由root组变为archer组
 # 仅改变文件夹所属组,文件夹里的东西不受影响
 chgrp archer logs
 
 # 将logs文件夹及其下的所有东西变为archer组
 chgrp -hR archer logs

文件和文件夹rwx权限的区别

  • 文件:

    • r: 可以读取和查看文件内容
    • w:可修改,但不代表可删除(可删除的前提是对该文件所在文件夹有w权限)。
    • x: 可执行
  • 文件夹:

    • r: 可查看文件夹内的内容,比如可以使用ls命令
    • w:可在此文件夹内执行创建和删除操作,也可以重命名此文件夹
    • x:能否进入此目录(cd命令能否执行)

tree

描述:
 查看目录树
 
如果没有安装,先执行yum install tree进行安装。

crontab任务调度

描述:
 crontab可以进行定时任务的配置,可以用于MySql备份,日志的整理等。
 
参数:
 -e: 编辑当前定时任务
 -l:打印当前定时任务
 -r:删除当前定时任务
 
实例:
 crontab -e 
 
   * * * * * [user-name] commands
   
   星号从左到右:
    1. 分钟,0~59
    2. 小时,0~23
    3. 一个月的某一天,1~31
    3. 一年的某一月,1~12
    5. 星期几,0~7,其中0和7都表示星期天

   星号(*)代表任何时间,比如上面例子中的第一个*表示一个小时的每分钟都执行。
   
   逗号(,)代表不连续的时间,比如 0 8,12,23 * * * 表示每天的8点0分,12点0分,
   23点0分各执行一次。
   
   中横线(-)代表连续的时间,比如 0 5 * * 1-6 表示每周周一到周六的早上5点0分
   执行一次。
   
   */n代表每隔多久执行一次,比如*/5就表示每隔五分钟执行一次。
   
  # 重启调度任务
  service crond restart
  
  # 每分钟都追加一次日期到mydate
  * * * * * date >> /tmp/mydate 
  
  # crontab调用脚本
  1. 编写一个脚本my.sh,假设放在/home/archer下,注意脚本里只有命令,定时信息
  通过crontab -e 编辑
  2. 确保my.sh有可执行的权限
  3. 命令行输入crontab -e
  4. 在进入的编辑栏里补上定时信息,并跟上脚本的路径,
  比如 */5 * * * * /home/archer/my.sh,表示每5分钟调用一次my.sh脚本

df

描述:
 查询系统磁盘的使用情况
 
参数:
-h: human readable

实例:
 df -h

df-h

du

描述:
 查询指定目录的磁盘占用情况

使用:
 du [OPTION...] DIR...
 
参数:
 -s: 指定目录占用大小汇总
 -h: human readable
 -a: 含文件
 -c: 列出明细的同时,增加汇总值
 -d/--max-depth=n:子目录深度
 
实例:
 # 查询/opt目录磁盘占用情况,深度为1
 du -ach --max-depth=1 /opt

wc

描述:
 统计指令,可以统计一个文件中的newline,character,words,或是文件的byte
 
参数:
 -m:统计character
 -l:统计newline
 -w:统计word
 -c:统计bytes

实例:
 # 统计/home目录下的文件个数
 ls -l | grep "^-" | wc -l # ls -l将分行显示所有的文件和文件夹,再通过grep选出文件,最后统计一下行数就是文件数了

给Linux主机指定固定的ip

修改/etc/sysconfig/network-scripts/文件夹下的网卡映射文件(ifconfig可以查看网卡映射文件的名称)。

几个重要的地方:
ONBOOT=yes # 启动系统时开启
BOOTPROTO=static # dhcp static 由dhcp改为static
IPADDR=192.168.33.24 # 指定ip地址
GATEWAY=192.168.33.2 # route -n 第一行就是网关
DNS1=8.8.8.8 # 固定值

修改完成以后重启网络服务:
 service network restart

ps

描述:
 显示进程信息
 
参数:
 -e: 显示所有进程
 -f: 全格式

实例:
 # 用标准的格式显示进程 
 ps -ef

ps-ef

格式解释:

ps-format

kill 和 killall

描述:
 用来终止进程(给内核发送signal)
 
使用:
 kill [OPTION...] pid # 通过进程id终止进程
 killall pname # 通过进程名终止进程,支持通配符
 
参数:
 -9:立即终止
 
实例:
 # 踢掉远程登陆的非法用户
 # 先使用ps -ef | grep sshd 列举出所有远程登陆的进程
 # 在输出中找到非法登陆的进程id,比如1024
 kill -9 1024
 
 # 终止所有IDEA
 killall idea

pstree

描述:
 查看进程树
 
参数:
 -p: 显示进程pid
 -u:显示进程所属用户

service

描述:
 服务管理
 服务(service)的本质是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求。
 
使用:
 service 服务名 start/stop/restart/reload/status
 systemctl用在CentOS 7以后 systemctl start/stop/restart/reload/status xxx.service

top

描述:
 动态监控进程。top和ps很相似,它们都用来显示正在执行的进程。top和ps的区别在于top可以更新正在运行的进程信息。
 
参数:
 -d:指定top命令每隔几秒更新,默认3秒。
 -i:不显示任何僵死或闲置进程
 -p:通过指定进程id只监控这一个进程的信息
 
交互指令:
 P: 以cpu使用率排序,默认
 M:以内存使用率排序
 N:以pid排序
 u: 只查询属于某个用户的进程
 k: 终止某一进程
 q:退出top

top

top 显示结果由两部分组成: 最上面是系统概要,下面是进程列表,默认的使用率排序。其中系统概要包含许多有用信息。下表是对系统概要的说明:

行号 字段 意义
1 top 程序名
- 14:40:16 当前时间
- up 21:42 这是正常运行时间。它是计算机从上次启动到现在所运行的时间。在这个例子里,系统已经运行了21小时42分
- 1 user 当前只有一个用户登陆系统
- load average 加载平均值是指,等待运行的进程数目,也就是说, 处于运行状态的进程个数,这些进程共享 CPU。展示了三个数值,每个数值对应不同的时间周期。第一个 是最后 60 秒的平均值,下一个是前 5 分钟的平均值, 最后一 个是前 15 分钟的平均值。若平均值低于 1.0, 则指示计算机工作不忙碌。
2 Tasks 总结了进程数目和各种进程状态
3 %Cpu(s) 这一行描述了 CPU 正在执行的进程的特性。
- 0.0 us 0.0%的CPU用于用户进程。 这个表示内核本身之外的进程。
- 0.1 sy 0.1% 的 CPU 时间被用于系统(内核)进程。
- 0.0 ni 0.0% 的 CPU 时间被用于”nice”(低优先级)进程。
- 99.9 id 99.9% 的 CPU 时间是空闲的。
- 0.0 wa 0.0% 的 CPU 时间来等待 I/O。
- 0.0 hi 0.0% 的 CPU 时间来等待硬件中断。
- 0.0 si 0.0% 的 CPU 时间来等待软件中断。
4 Mem 展示物理内存的使用情况。
5 Swap 展示交换分区(虚拟内存)的使用情况。

netstat

描述: 
 netstat 命令是Linux用于显示各种网络相关信息,是一个监控TCP/IP网络的非常有用的工具,
 如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,
 多播成员 (Multicast Memberships) 等等。
 
参数:
 -a或--all:显示所有选项,默认不显示LISTEN相关
 -t或--tcp:仅显示tcp相关选项
 -u或--udp:仅显示udp相关选项
 -n或--numeric:直接使用ip地址,而不通过域名服务器(拒绝显示别名,能显示数字的全部转化成数字)
 -l或--listening:仅列出有在 Listen (监听) 的服務状态
 -p或--programs:显示建立相关链接的程序名
 -r或--route:显示路由信息,路由表
 -e或--extend:显示扩展信息,例如uid等
 -s或--statistice:显示网络工作信息统计表(按各个协议进行统计)
 -c或--continuous:每隔一个固定时间,执行该netstat命令。
提示:LISTEN和LISTENING的状态只有用-a或者-l才能看到

free

描述:
    显示系统中的内存信息(包括已使用的和空闲的)
    
参数:
    -h: human readable
    -t:为每一列增加一个汇总值total
    
 实例:
    free -ht

free

ls

描述:
    列举目录中的内容
    
参数:
    -t: 按最后修改时间排序
    -S:按文件大小排序
    -r/--reverse:按相反的顺序输出
    -R/--recursive:列举出子目录中的内容
    -d:输出目录本身信息而不是目录中的内容,一般配合-l选项
    -h:human readable
    -a:显示隐藏文件
    -l:按长格式输出
    
 实例:
    # 输出当前目录的详细信息
    ls -ld
    # 输出当前目录的所有内容,最近修改的在最前面
    ls -lt
    # 输出当前目录的所有内容,最近修改的在最后面
    ls -ltr

file

描述:
    确定文件的格式。Linux系统并不通过文件后缀名来区分其类型,诸如pet.jpg的文件并不一定真的是jpeg格式的图片。
    
参数:
    -i:输出文件的mine type而不是普通描述信息

file-i

通配符和字符类

接受文件名作为参数的任何命令,都可以使用通配符。

通配符:
    * 匹配任意多个字符(包括0个或1个)
    ? 匹配任意一个字符(不包含0个)
   [characters] 匹配任意一个属于字符集中的字符
   [!characters] 匹配任意一个不属于字符集中的字符
   [[:class:]] 匹配任意一个属于指定字符类中的字符
   
字符类:
    [:alnum:] 匹配任意一个字母或数字
    [:alpha:] 匹配任意一个字母
    [:digit:] 匹配任意一个数字
    [:lower:] 匹配任意一个小写字母
    [:upper:] 匹配任意一个大写字母
    
 实例:
    *             所有文件
    g*           任何以g开头的文件
    b*.txt       任何以b开头的txt文件
    data???    以data开头,后跟任意三个字符的文件
    [abc]*      任何以a,或b,或c开头的文件
    backup.[0-9][0-9][0-9]     以backup.开头,后跟任意三个数字的文件 # [0-9]表示任意一个数字
    [[:upper:]]*    任何以大写字母开头的文件
    [![:digit:]]*    任何不以数字开头的文件
    *[[:lower:]123]     任何结尾是一个小写字母或数字1,2,3的文件,比如AAAAa, BBBB1, CCCC3

花括号展开

我们可以从一个包含花括号的模式中创建多个文本字符串。花括号表达式本身可能包含一个由逗号分开的字符串列表,或者一系列整数,或者单个的字符串。这种模式不能嵌入空白字符。

# 包含由逗号分开的字符串列表
echo prefix-{A,B,C}-suffix # prefix-A-suffix prefix-B-suffix prefix-C-suffix
# 包含一系列整数
echo number-{1..3} # number-1 number-2 number-3
# 包含一系列倒数的字符
echo {Z..P} # Z Y X W V U T S R Q P
# 可以嵌套
echo a{A{1,2},B{3,4}}b # aA1b aA2b aB3b aB4b
# 创建一系列目录
mkdir {2020..2025}-{1..12} # 创建从2020-1到2025-12的一系列文件夹

引号

  如果把文本放在双引号中,shell使用的特殊字符,除了$,(反斜杠),和`(倒引号)之外,则失去它们的特殊含义,被当作普通字符来看待。这意味着单词分割,路径名展开,波浪线展开,和花括号展开都被禁止,然而参数展开,算术展开,和命令替换仍然执行。 **

# 参数展开
echo "$PATH"
# 算数展开
echo "$[5+3]"
# 命令替换
echo "$(ls -l)"
# 双引号用来处理带空格的文件名,避免文件名被shell解释成两个独立单词
echo "hello world.txt"

  如果需要禁止所有的展开,那就使用单引号。

# 原样输出 不做任何展开
echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'

键盘操作

移动光标

  • ctrl+a:移动光标到行首
  • ctrl+e:移动光标到行尾
  • ctrl+f:光标向前移动一个字符,和右箭头作用一样
  • ctrl+b:光标向后移动一个字符,和左箭头作用一样
  • alt+f:光标向前移动一个字,以单词为单位
  • alt+b:光标向后移动一个字,以单词为单位

修改文本 ctrl+d:删除光标处的字符

sort

描述:
    针对文本文件的内容,以行为单位来排序。
    sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
参数:
    -b:忽略每行开始的空格字符,从第一个可见字符开始
    -n:按数值大小排序,默认以字符进行排序,因此可能造成10比2小的情况,因为10的第一个字符1比2小
    -r:反向排序
    -u:去除重复行
    -f:忽略大小写
    -t<分隔字符>:指定排序时所用的栏位分隔字符
    -o:用重定向无法将sort的输出写到原文件中,比如sort log.txt > log.txt不会写入排序后的结果反而会清空log.txt中的内容,
    -o选项解决了这个问题:sort log.txt -o log.txt
 实例:
    1. 假定文件fruits.txt内容为:
        banana:30:5.5
        apple:10:2.5
        pear:30:2.3
        orange:20:3.4
    这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?
    sort -n -t: -k 2 fruits.txt # -n是必要的,因为要按数值进行排序

    2. 可以看到banana和pear的数量是一样的,按数量排序时如何决定banana和pear的先后顺序呢?答案是可以指定排序的优先级,也就是使用多个-k选项:
    # 先按照第二列排序,第二列相同的时候再按照第三列排序
    sort -n -t: -k 2 -k 3 fruits.txt

   3. -k选项还可以加上modifier
   sort -t: -k 2n -k 3nr fruits.txt # 先按照第二列的数值排序,相同的情况下按照第三列的数值反向排序

进程

  当系统启动的时候,内核先把一些它自己的程序初始化为进程,然后运行一个叫做 init 的程序。init,依次地,再运行一系列的称为 init 脚本的 shell 脚本(位于/etc),它们可以启动所有的系统服务。其中许多系统服务以守护(daemon)程序的形式实现,守护程序仅在后台运行,没有任何用户接口。这样,即使我们没有登录系统,至少系统也在忙于执行一些例行事务。

  内核维护每个进程的信息,以此来保持事情有序。例如,系统分配给每个进程一个数字, 这个数字叫做进程 ID 或 PID。PID 号按升序分配,init 进程的 PID 总是 1。内核也对分配给 每个进程的内存进行跟踪。像文件一样,进程也有所有者和用户 ID,有效用户 ID,等等。

软件包管理

  软件包管理系统通常由两种工具类型组成:底层工具用来处理这些任务,比方说安装 删除软件包文件,和上层工具,完成元数据搜索和依赖解析。

发行版 底层工具 上层工具
Debian-Style dpkg apt-get
CentOS rpm yum

yum和apt

上层工具 搜索 安装 卸载 更新系统中的软件包
yum yum search keyword yum install package_name yum erase package_name yum update
apt apt-get update; apt-cache search keyword apt-get update; apt-get install package_name apt-get remove package_name apt-get update; apt-get upgrade

dpkg和rpm

下层工具 安装 升级 显示安装到系统的所有软件包 查询是否安装了指定软件包 查找安装了某个文件的软件包
dpkg dpkg --install package_file dpkg --install package_file dpkg --list dpkg --status package_name dpkg --search file_name
rpm rpm -i package_file rpm -U package_file rpm -qa rpm -q package_name rpm -qf file_name
   # 查询哪个软件包安装了vim
   rpm -qf /usr/bin/vim

find

find 程序能基于各种各样的属性,搜索一个给定目录(以及它的子目录),来查找文件。 find 命令的美丽所在就是它能够被用来识别符合特定标准的文件。它通过(有点奇怪)应用选项,测试条件,和操作来完成搜索。我们先看一下测试条件。

# 找出家目录下的所有目录并统计
find ~ -type d | wc -l
# 找出家目录下的所有文件并统计
find ~ -type f | wc -
# 找出家目录下所有大于1M的jpg文件
find ~ -type f -name "*.jpg" -size +1M

find 命令支持大量不同的测试条件。请注意,在需要数值参数的情况下,可以应用“+”和 “-” 符号表示法:

测试条件 描述
-empty 匹配空文件和目录。
-group name 匹配的文件和目录属于一个组。组可以用组名或组 ID 来表示。
-name pattern 用指定的通配符模式匹配的文件和目录。
-iname pattern 就像 -name 测试条件,但是不区分大小写。
-mmin n 匹配的文件或目录的内容被修改于 n 分钟之前。
-mtime n 匹配的文件或目录的内容被修改于 n * 24小时之前(也就是n天之前)。
-newer file 匹配的文件和目录的内容早于指定的文件。当编写 shell 脚本,做文件备份时,非常有帮助。每次你制作一个备份,更新文件(比如说日志),然后使用 find 命令来决定自从上次更新,哪一个文件已经更改了。
-nouser 匹配的文件和目录不属于一个有效用户。这可以用来查找属于删除帐户的文件或监测攻击行为。
-nogroup 匹配的文件和目录不属于一个有效的组。
-perm mode 匹配的文件和目录的权限已经设置为指定的 mode。mode 可以用八进制或符号表示法。
-size n 匹配的文件大小为 n。
-type c 匹配的文件类型是 c。
-user name 匹配的文件或目录属于某个用户。这个用户可以通过用户名或用户 ID 来表示。

grep

grep程序会在文本文件中查找一个指定的正则表达式,并把匹配行输出到标准输出。

# grep的使用格式
grep [options] regex [file...]

其常用的参数如下:

参数 描述
-i 忽略大小写。也可用 --ignore-case 来 指定。
-v 不匹配。通常,grep 程序会打印包含匹配项的文本行。这个选项导致 grep 程序只会不包含匹配项的文本行。也可用 --invert-match 来指定。
-c 打印匹配的数量(或者是不匹配的数目,若指定了 -v 选 项),而不是文本行本身。也可用 --count 选项来指定。
-l 打印包含匹配项的文件名,而不是文本行本身。也可用 --files-with-matches 选项来指定。
-L 相似于 -l 选项,但是只是打印不包含匹配项的文件名。也可用 --files-without-match 来指定。
-n 在每个匹配行之前打印出其位于文件中的相应行号。也可用 --line-number 选项来指定。
-h 应用于多文件搜索,不输出文件名。也可用 --no-filename 选项来指定。
准备数据:
    ls /bin > dirlist-bin.txt
    ls /sbin > dirlist-sbin.txt
    
# 在dirlist-*.txt中搜索字符串bzip,打印匹配的那一行及其所属文件
grep bzip dirlist-*.txt

# 输出包含匹配项的文件列表而不是文件本身
grep -l bzip dirlist-*.txt

grep

Shell入门

  shell脚本均以 #!/bin/bash (shebang)开头,注意给予其可执行权限。

shell脚本中的注释方式:
    # 单行注释

    :<<!
    多行注释
    多行注释
    多行注释
    !

如何执行shell脚本

有两种方式可以执行shell脚本:

  • 赋予shell脚本可执行权限,通过输入其文件名执行
  • 通过sh命令来执行,格式为 sh 脚本名

shell中的变量

  在bash中,每一个变量的值都是字符串。 无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。Linux Shell中的变量分为系统变量和用户自定义变量,系统变量比如PATH,HOME,USER等。

shell变量的定义

自定义变量:
    语法:
        变量名=值
    实例:
        num=100
    
删除自定义变量:
    语法:
        unset 变量名
    实例:
        unset num

定义静态变量:
    语法:
        readonly 变量名=值
    实例:
        readonly okay=200
  注意:静态变量只能读取,不能unset     
  
将命令的返回值赋予变量:
    语法:
        1. 变量名=`要执行的命令`
        2. 变量名=$(要执行的命令)
    实例:
        A=`ls -l` # 将ls -l的返回值赋给变量A
        A=$(ls -l) # 等价于A=`ls -l`

定义变量的时候有几个点需要注意一下:

  • 不能以数字开头,且一般采用大写
  • 等号两端不能有空格,num=10可以,num = 10不行

设置环境变量

  • export 变量名:将shell变量导出为环境变量
  • source 配置文件名:让修改后的配置信息立即生效

位置参数变量

  当执行一个shell脚本时,如果希望获取命令行参数,就可以使用位置参数变量。比如在命令行执行 ./my.sh 100 200,可以使用位置参数变量来获取100和200这两个命令行参数。

 $n:n为数字,其中$0为命令本身,$1-$9表示第一到第九个参数,十以上的参数需要使用大括号,比如${10}表示第十个参数
 $*:表示命令行中的所有参数,$*把所有的参数看成一个整体
 $@: 也表示命令行中的所有参数,不过$@把每个参数区分对待
 $#: 表示命令行中参数的个数

预定义变量

预定义变量是shell设计者事先定义好的变量,可以直接在脚本中使用.

?: 当前进程id
$!: 后台运行的最后一个进程的id
$?: 最后一次执行的命令的返回值,0表示成功,非0表示失败

运算符

1. $((运算式))或$[运算式]
2. expr m + n, 注意expr运算符间要有空格(+, -, \*, /, %分别对应加减乘除和取模运算)

计算(2 + 3) * 4
    使用$[]:
        $[(2+3)*4]
    
    使用expr:
        SUM=$(expr 2 + 3) # expr是一个表达式,需要使用$()来引用其结果
        echo $(expr $SUM \* 4)

条件判断

基本语法:
    [ condition ] # 注意condition前后要有空格
    非空返回true,可使用 $? 验证,0为true,>1为false
    
实例:
    [ archer ] # 返回true
    [] # 返回false
    
常用判断条件:
    0. = # 字符串比较
    1. 两个整数的比较
        -lt # 小于
        -le # 小于等于
        -gt # 大于
        -ge # 大于等于
        -eq # 等于
        -ne # 不等于
     2. 按照文件权限进行判断
        -r # 有读的权限
        -w # 有写的权限
        -x # 有执行的权限
    
    3. 按照文件类型进行判断
        -f # 文件存在且是普通文件
        -e # 文件存在
        -d # 文件存在且是目录
      
实例:
    # "ok"是否等于"ok"
    [ "ok" = "ok" ]
    
    # 23是否大于22
    [ 23 -gt 22 ]
    
    # /root/install.log是否存在
    [ -e /root/install.log ]

流程控制

if:

语法:
    第一种形式:
        if [ condition ];then
            # code goes here
        fi
    第二种形式:
        if [ condition ]
            then
            # code goes here
            elif [ condition ]
            then
            # code goes here
            fi
 
 实例:
    NUM=101
    
    if [ $NUM -eq 101 ];then 
        echo "NUM = 101"
    fi
    
    if [ $NUM -gt 100 ] 
    then
        echo "NUM > 100"
    else
        echo "NUM <= 100"
    fi
    
    if [ $NUM -gt 200 ] 
    then 
        echo "NUM > 200"
    elif [ $NUM -gt 150 ]
    then
        echo "NUM > 150"
    elif [ $NUM -gt 100 ]
    then 
        echo "NUM > 100"
    else 
        echo "NUM <= 100"
    fi 

case:

语法:
    case $变量名 in
    "值1")
        # code goes here
        ;;
    "值2")
       # code goes here
       ;;
     ...... # 其他分支
    *)
      # default分支
      ;;
    esac # case的反转
    
实例:
    case $1 in
    "1")
        echo "星期一"
     ;;
    "2")
        echo "星期二"
     ;;
    "3")
        echo "星期三"
     ;;
    "4")
        echo "星期四"
     ;;
    "5")
        echo "星期五"
     ;;
     *)
        echo "未知工作日"
     ;;
     esac  # 不要忘了结束case

for:

语法:
    第一种形式:
        for 变量 in 值1, 值2, 值3 ...
        do
          # code goes here
        done
    第二种形式:
        for((初始值;循环控制条件;变量变量))
        do
         # code goes here
        done
    
实例:
    # 遍历命令行参数
    # $*将所有命令行参数视作一个整体,如果使用$*,这里只会有一个输出
    for i in $@  # 这一句的意思是遍历 $@并将值赋值给i
    do
       echo "i = $i"
    done

    # 计算0-49的和
    sum=0
    for((i=0;i<50;i++))
    do 
        sum=$[$sum+$i]
    done
    echo "sum = $sum"

while:

形式:
    while [ condition ]
    do
        # code goes here
    done
    
实例:
    # 从命令行输入一个数n,统计1+2+...+n的值
    i=1
    sum=0
    while [ $i -le $1 ]
    do
     sum=$[$sum+$i]
     i=$[$i+1]
     done

     echo $sum

自定义函数

语法:
    [ function ] funcname[()] {
        # codes goes here
        [return int;]
    }
    # 注意shell的函数不需要写形参,中括号里的内容是可选的
    
实例:
    # 计算两个参数的和
    
    #!/bin/bash
    
    function sum() {
        SUM=$[$n1+$n2] # shell函数没有形参,$n1 $n2是调用时传递的实参
        echo $SUM
    }
    
    # read用来读取命令行输入,它会阻塞当前进程直至输入完成
    read -p "请输入一个整数\n" n1 # 定义n1
    read -p "请再输入一个整数\n" n2 # 定义n2
    
    sum $n1 $n2 # 调用自定义的sum函数,传递$n1 $n2两个参数,这样$n1 $n2就能在函数体使用了  

综合案例

编写shell脚本定时维护数据库,要求:

  1. 每天凌晨2:10备份数据库insoDB到data/backup/db
  2. 备份开始和结束需要给出提示信息
  3. 备份的文件要求以备份时间命名,并打包成tar.gz格式,比如2020-03-12_021545.tar.gz
  4. 在备份的同时,检查是否有十天前的文件,有就将其删除
endgame.sh:

    #!/bin/bash

    # 记录备份时间
    DATETIME=$(date +%Y-%m-%d_%H%M%S)
    # 定义备份文件夹
    BACKUP_DIR=/data/backup/db

    # 创建文件夹,如果不存在  shell的取反也是使用 !
    if [ ! -d $BACKUP_DIR ];then
        mkdir -p $BACKUP_DIR
    fi

    # 创建临时文件夹来存储数据库备份文件
    cd $BACKUP_DIR
    mkdir $DATETIME

    echo "========备份开始=========="
    # MySQL主机地址
    HOST=localhost
    # MySQL用户名
    DB_USER=root
    # MySQL密码
    DB_PWD=123
    # 要备份的数据库
    DATABASE=insoDB

    # 执行MySQL备份指令
    mysqldump -u$DB_USER -p$DB_PWD --host=$HOST $DATABASE | gzip > $BACKUP_DIR/$DATETIME/$DATETIME.sql.gz

    # 对整个临时备份文件夹进行打包
    cd $BACKUP_DIR
    tar -zcvf $DATETIME.tar.gz $DATETIME
    # 删除临时文件夹
    rm -rf $DATETIME

    # 找到10天前的备份文件,进行删除
    find  $BACKUP_DIR -mtime +10 -name "*.tar.gz" -exec rm -rf {} \ # -exec表示执行,{} \是固定写法,表示找到的所有文件

    echo "========备份结束=========="

# 指定凌晨2:10备份
crontab -e
    10 2 * * * endgame.sh

service crond start

给Ubuntu的root用户设置密码

sudo passwd --> 输入普通用户的密码后就可以设置了之后就可以使用su命令切换到root用户