shell脚本学习0-预备知识

学习shell脚本前先对linux的基本常用知识点介绍一下。

  1. linux系统介绍
    linux由四个部分组成,分别是linux内核,GUN工具,图形化桌面和应用软件,其中linux系统的核心就是内核,负责计算机的硬件和软件的管理。

1.1 linux内核
linux内核是系统的核心,控制着内存,程序和硬件之间的交互。linux内核主要负责四个功能,分别是内存管理,软件程序管理,硬件设备管理和文件系统管理。

1.1.1 内存管理
内核管理物理内存和虚拟内存,内核通过交换空间实现虚拟内存,交换空间实际上是硬盘上的一段区域,内核会在交换空间和物理内存之间交换虚拟内存中的东西,从而会让进程以为他拥有比物理内存更大的空间。内存是由一个个页面(page)组成的,内核会把页面放进物理内存或者交换空间,内核会维护一个内存页面表,这个内存页面表会指明哪些页面位于物理内存,哪些页面被换到了内存上。
内核会表明哪些页面正在使用中,当某个内存页面一段时间没有被访问的时候,就会把该页面换出到交换空间,换出操作与内存是否还有可用的空间无关,及时还有可用内存,换出也可能会发生。当进程想要访问一段已经被换出的内存的页面的时候,内核会先在物理内存中换出另外一个内存页面来腾出空间,然后从交换空间换入请求的内存页面。linux启动后,内存页面的换出操作就不会停止。

1.1.2 软件程序管理
软件程序就是进程,内核负责所有进程的管理。内核创建的第一个进程为init进程,这个进程会启动系统上所有其他进程。当系统启动时,它会把init进程加载到虚拟内存中,内核在启动其他进程的时候,也会在虚拟内存中分配一块区域来存储该进程的数据段和代码段。

1.1.3 硬件设备管理
Linux把硬件设备当做特殊的文件,称为设备文件。设备文件分为三类,分别是字符型设备文件,块设备文件,网络设备文件。
a) 字符设备文件指的是处理数据时每次只能处理一个字符的设备。比如终端就是个字符设备
b) 块设备文件与字符设备文件类似,不过块设备文件每次能处理大块数据,比如硬盘
c) 网络设备文件指的是用数据包发送和接收数据的设备,比如网卡和特殊回环设备,回环设备允许linux系统使用常用的网络协议同自身通信,比如用tcp协议实现自己与自己通信(回环地址127.0.0.1)
linux系统为了方便管理硬件设备,为每个设备生成了一个称为节点的特殊文件,与设备的所有通信都通过设备节点完成,linux内核为每个节点分配一个唯一的数值对,这个数值对由主设备号和次设备号,功能相近的设备被划分到同样的主设备号下,主设备号用于区分主设备组下某个特定设备。

1.1.4 文件系统管理
linux内核支持通过不同类型的文件系统从硬盘中读写数据,linux内核采用VFS(虚拟文件系统)作为和每个文件系统交互的接口。

1.2 GUN工具
GUN是GUN’s Not Unix的缩写,GUN是一套完整的Unix工具,这些工具开源的,比如shell就是个GUN工具,注意,所有linux发行版默认的shell都是bash shell。

1.3 图形化桌面
有些linux发行版也是可以跟windows一样通过图标操作的。我们把完成的linux系统包称作发行版,大多数发行版是为了某个特性用户群定制的,比如软件开发人员,商业用户等

1.4 应用软件

  1. shell命令
    系统启动什么shell是根据用户ID配置决定的,在文件/etc/passwd文件中,第7个字段就是该用户对应的默认shell程序,只要用户登录到某个虚拟控制台终端或在GUI中启动终端仿真器,默认的shell程序就会运行,比如下面root用户对应的默认shell程序。
root:x:0:0:root:/root:/bin/bash

除此之外,/bin/sh是是另一个默认的shell,这个shell是默认的系统shell,用于那些需要在启动时使用的系统shell脚本,不过一般情况下会把默认的系统shell软连接到另一个,比如我这个系统是ubuntu16.04

aitian@aitian-CW65S:~$ ll /bin/sh
lrwxrwxrwx 1 root root 4 1月  12  2019 /bin/sh -> dash*

2.1 shell基本操作
在linux早期,可以用来工作的只有shell,程序员都是通过终端输入输出,也就是通过文本命令行界面(Command line interface,CLI)。

2.1.1 启动shell
/etc/passwd文件包含了所有系统用户账号列表以及配置信息,取出这个文件中一行看看

root:x:0:0:root:/root:/bin/bash

这个条目用冒号分割,每个条目有七个字段,其中最后一个字段指定了用户使用的shell程序,当roo用户用cli登录系统linux系统的时候,bash shell会自动启动。这个是cli默认进入的shell,如果用的话桌面版,可以指定其他的shell启动。

2.1.2 bash手册
bash手册可以查找一些shell命令,常用的命令是man。man + 想要查找的命令就可以找到相应的手册。比如输入

man chmod

结果为:
1.png
输入q之后就退出了。
如果不记得这个命令完整的名字的话,也可以使用关键字,比如输入:

man -k chm

运行后结果为

chmod (1)            - change file mode bits
chmod (2)            - change permissions of a file
fchmod (2)           - change permissions of a file
fchmodat (2)         - change permissions of a file
intel_upload_blit_large (1) - microbenchmark of Intel GPU performance
intel_upload_blit_large_gtt (1) - microbenchmark of Intel GPU performance
intel_upload_blit_large_map (1) - microbenchmark of Intel GPU performance
intel_upload_blit_small (1) - microbenchmark of Intel GPU performance
perf-bench (1)       - General framework for benchmark suites
XF86VidModeSwitchMode (3) - Extension library for the XFree86-VidMode X extension
XkbLatchModifiers (3) - Latches and unlatches any of the eight real keyboard modifiers

还有一种查看手册的方法是使用help指令,比如输入

chmod --help

运行后结果为:

用法:chmod [选项]... 模式[,模式]... 文件...
 或:chmod [选项]... 八进制模式 文件...
 或:chmod [选项]... --reference=参考文件 文件...
Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.

  -c, --changes          like verbose but report only when a change is made
  -f, --silent, --quiet  suppress most error messages
  -v, --verbose          output a diagnostic for every file processed
      --no-preserve-root  do not treat '/' specially (the default)
      --preserve-root    fail to operate recursively on '/'
      --reference=RFILE  use RFILE's mode instead of MODE values
  -R, --recursive        change files and directories recursively
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.

2.1.3 cd命令
cd 命令用于切换到对应目录下,使用方法为cd + 相应目录。如果在cd命令后面没有加目录,就会自动切换到用户主目录下。比如:

aitian@aitian-CW65S:~/at/shell/0$ pwd
/home/aitian/at/shell/0
aitian@aitian-CW65S:~/at/shell/0$ cd 
aitian@aitian-CW65S:~$ pwd
/home/aitian

看上面的倒数第二行有一个波浪线(~),这个就表示用户主目录,比如输入:

aitian@aitian-CW65S:~$ cd ~/protobuf352/
aitian@aitian-CW65S:~/protobuf352$ pwd
/home/aitian/protobuf352
aitian@aitian-CW65S:~/protobuf352$

单点符(.)表示当前目录;双点符(…)表示上一级目录。

2.1.4 ls命令
ls命令查看目录下文件文件夹的名字,ls输出的列表是按照字母排序的,不过要注意不是按照行排序,而是按照列排序。输入:

aitian@aitian-CW65S:~$ ls
123  examples.desktop  perf.data    pycharm-community-2018.3.4  tags     公共的  视频  文档  音乐
at   GoProject         protobuf352  QtProject                   toLearn  模板    图片  下载  桌面

ls命令本身额不能区分结果中哪个是文件哪个是文件夹,需要加上-F,比如:

aitian@aitian-CW65S:~$ ls -F
123*  examples.desktop  perf.data     pycharm-community-2018.3.4/  tags     公共的/  视频/  文档/  音乐/
at/   GoProject/        protobuf352/  QtProject/                   toLearn  模板/    图片/  下载/  桌面/

文件夹名的最后后面有一个左斜杠(/),同时可以发现123作为一个可执行文件,加上-F后会在他的后面加上一个星号(*),这些变区别不加-F都体现不出来。
如果想显示隐藏文件,输入:

ls -a 

用-R参数可以递归地列出目录的目录一直到最底层的文件,比如:

aitian@aitian-CW65S:~/at$ ls -FR shell/
shell/:
0/             file         tesfile     test1.sh*   test27.sh*  test35.sh*  test43.sh*  test50.sh*  testfile
17/            file1        test10.sh*  test20.sh*  test28.sh*  test36.sh*  test44.sh*  test51.sh*  test.txt
19/            file2        test11.sh*  test21.sh*  test29.sh*  test37.sh*  test45.sh*  test52.sh*  tmp.txt
1.txt          file3        test12.sh*  test22.sh*  test2.sh*   test38.sh*  test46.sh*  test53.sh*  ttt.txt
20/            isPhone.sh*  test13.sh*  test23      test30.sh*  test39.sh*  test47.sh*  test54.sh*
21/            main.c       test14.sh*  test23.sh*  test31.sh*  test3.sh*   test48.sh*  test5.sh*
bg.sh*         mul@         test15.sh*  test24.sh*  test32.sh*  test40.sh*  test49.sh*  test7.sh*
count_exe.sh*  nohup.out    test16.sh*  test25.sh*  test33.sh*  test41.sh*  test4.sh*   test8.sh*
errfile        normalfile   test19.sh*  test26.sh*  test34.sh*  test42.sh*  test5       test9.sh*

shell/0:

shell/17:
1.sh*  echo_function_value.sh*  lib_call.sh*                        post_query_param_to_func.sh*
2.sh*  global_variable.sh*      local_variable.sh*                  return_array.sh*
3.sh*  iter_function.sh*        post_array_to_func_err_emample.sh*
4.sh*  itertion.sh*             post_array_to_func_ok_emample.sh*

shell/19:
aitian  data  destfile  sedfile  test  test2  testfile  value  website

shell/20:
data  data2  data3  data4  data5  data6  data7  data8  gawk_file  gawk_file2  split.sh*

shell/21:
a.c  a.out*  data  data2  data3  data4  data5  data6  data7  data8

ls命令中还可以使用正则表达式:
问号?代表任何一个字符;
星号*代表0个或者多个任意字符
中括号列出所有范围,比如[abc]或者[a-i]
还可以使用感叹号将不需要的内容排除在外,比如:

ls -l abc?def
ll abc*
ll ab[def]
ll a[!b]c

2.1.5 touch命令
touch可以创建文件,比如

touch a.txt

touch命令还可以改变文件的修改时间,注意这里并不会改变文件的内容,比如:

aitian@aitian-CW65S:~/at$ ll vim.txt 
-rw-rw-r-- 1 aitian aitian 11191 1月   5 00:26 vim.txt
aitian@aitian-CW65S:~/at$ touch vim.txt 
aitian@aitian-CW65S:~/at$ ll vim.txt 
-rw-rw-r-- 1 aitian aitian 11191 2月   9 21:25 vim.txt

2.1.6 cp命令
cp命令是复制作用,加上-i参数可以提示是否需要覆盖同名文件,比如:

cp -i one two

复制文件夹的时候,在结尾加上-r,比如:
cp test . -r
cp命令也可以使用通配符。

2.1.7 链接文件
链接文件是linux的一大特色。在windows系统下,如果想维护同一个文件的两份或者多份副本,那就把原来的文件拷贝招贴多份。而通过链接文件,可以保存一份物理文件副本和多个虚拟副本。
链接是目录中,指向文件真实位置的占位符,linux中有两种链接,一种是软连接,又称为符号链接,另一种是硬链接。

2.1.7.1 软链接
软链接本身就是一个文件,这个文件指向另一个文件。软链接文件和源文件完全是两个文件,内容也完全不同。要为一个文件创建软链接,原文件必须预先存在。创建软链接的格式为ln -s file soft_link_file,举例如下:

aitian@aitian-CW65S:~/at/shell/0$ ln -s file file_soft
aitian@aitian-CW65S:~/at/shell/0$ ll
总用量 2008
drwxrwxr-x 2 aitian aitian    4096 2月   9 22:16 ./
drwxrwxr-x 8 aitian aitian    4096 2月   9 17:20 ../
-rw-rw-r-- 1 aitian aitian 2048000 2月   9 22:16 file
lrwxrwxrwx 1 aitian aitian       4 2月   9 22:13 file_soft -> file

后面的参数为软链接文件名,它会指向前面的文件。可以看出两个文件的大小也不一样。通过inode数值也可以看出这两个文件是完全不同的两个文件,inode数值是linux内核为文件分配的,是唯一的。输入

aitian@aitian-CW65S:~/at/shell/0$ ls -i 
539425 file  539423 file_soft

可以看出他们的inode不一样。

2.1.7.2 硬链接
硬链接会创建一个虚拟文件,这个虚拟文件包含了原文件的信息以及位置。从根本上来说,这两个文件是同一个文件。引用硬链接节是引用了原文件。
要创建硬链接,原文件也必须预先存在,举例如下:

aitian@aitian-CW65S:~/at/shell/0$ ln file file_hard
aitian@aitian-CW65S:~/at/shell/0$ ll
总用量 4008
drwxrwxr-x 2 aitian aitian    4096 2月   9 22:22 ./
drwxrwxr-x 8 aitian aitian    4096 2月   9 17:20 ../
-rw-rw-r-- 2 aitian aitian 2048000 2月   9 22:16 file
-rw-rw-r-- 2 aitian aitian 2048000 2月   9 22:16 file_hard
lrwxrwxrwx 1 aitian aitian       4 2月   9 22:13 file_soft -> file
aitian@aitian-CW65S:~/at/shell/0$ ll -i file*
539425 -rw-rw-r-- 2 aitian aitian 2048000 2月   9 22:16 file
539425 -rw-rw-r-- 2 aitian aitian 2048000 2月   9 22:16 file_hard
539423 lrwxrwxrwx 1 aitian aitian       4 2月   9 22:13 file_soft -> file

从文件大小和inode数值可以看出,硬链接文件和原文件是同一个文件。所以说,你只要修改file文件或者file_hard中的任何一个,另外一个会类似量子纠缠一样,产生完成相同的修改。

2.1.8 创建目录
创建目录使用mkdir+目录名的格式,如果创建的目录中还有别的目录,那么就加上-p命令:

aitian@aitian-CW65S:~/at/shell/0$ mkdir -p a/b/c
aitian@aitian-CW65S:~/at/shell/0$ ls -R a/
a/:
b

a/b:
c

a/b/c:

2.1.9 file命令
file命令能够确定文件的类型以及文件的字符编码,比如下面的test.sh是文本内容,输入:

aitian@aitian-CW65S:~/at/shell/0$ file test.sh 
test.sh: ASCII text

假如是一个目录呢?

aitian@aitian-CW65S:~/at/shell/0$ file abc
abc: directory

假如是一个软链接文件的话,还是指出链接到哪个文件:

aitian@aitian-CW65S:~/at/shell/0$ file file_soft
file_soft: symbolic link to file

如果是一个二进制文件,还能看出来这个二进制文件可以在什么平台运行

aitian@aitian-CW65S:~/at/shell/0$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=f0b96f8607c66ae35df14c6381c5af7e2dc8a174, not stripped

2.1.10 cat命令
cat命令可以在终端打印出文本内容,比如:

aitian@aitian-CW65S:~/at/shell/0$ cat main.c
#include<stdio.h>
int main()
{

    
    return 0;
}

加上-n参数可以显示行号,比如:

     1	#include<stdio.h>
     2	int main()
     3	{
     4	
     5	    
     6	    return 0;
     7	}

如果只想给有文本的行加上行号的话,加上-b参数:

     1	#include<stdio.h>
     2	int main()
     3	{

     4	    
     5	    return 0;
     6	}

注意这里的第四行也被显示出来了,因为这一行有很多空格,而不是一个空行。

2.1.11 more命令
cat命令一般用来查看小文本文件比较好用,遇到大文件的时候可以用more。比如输入:

more test.c

555.png

可以发现,左下角显示了当前浏览的位置,按q可以退出,按空格键或者回车键向前运行。

2.1.12 less命令
跟more命令用法差不多

less test.c

2.1.13 head命令
head命令可以用来显示文件开头一些行的内容,如果没有加任何参数的话就是显示前10行。比如文本log.txt的内容为:

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20 

输入:

head log.txt

结果为:

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10

也可以用-n参数显示打印最前面的n行,输入:

head -5 log.txt

结果为:

line 1
line 2
line 3
line 4
line 5

2.1.14 tail命令
tail命令打印文件末尾的内容,如果不加任何参数,就默认打印末尾10行内容,比如文本log.txt的内容为:

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20 

输入:

tail log.txt

结果为:

line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20 

也可以通过-n参数指定打印默认的多行内容,输入:

tail -5 log.txt

tail命令中还有一个常用并且非常好用的参数就是-f,比如在终端使用tail -f log.txt后,当另一个进程向log.txt写入内容的时候,在终端可以实时显示新写入的内容。比如
1.png

可以看出,在下面的终端中写入line 21的时候,上面的终端实时地显示了这一行新增的内容。

2.1.15 ps命令
ps命令能查看系统中进程相关的信息,对于ps命令而言,可以带的参数实在太多了,其实不需要记住所有的参数,只要记住自己常用的就行了。比如ps -ef可以显示系统上运行的所有进程,输入:

ps -ef|more

结果为:
34.png

ps -ef可以显示出系统上运行的所有进程,其中-e表示显示所有运行在系统上的进程,-f表示则扩展打印出一些列,这些列包含很多重要信息,比如上图所示,其中:
UID表示启动进程的用户;
PID和PPID表示进程和该进程父进程的ID;
C表示进程周期中的CPU利用率;
STIME表示进程启动的系统时间;
TTY表示进程启动的终端设备;
TIME表示进程占用的CPU时间,注意这不是运行时间;
CMD表示启动的程序名称;
上面的参数应该非常多了,如果想要更多的参数的话加上-l(小写的L),比如输入:

ps -l

结果为:

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  3676  3665  0  80   0 -  6339 wait   pts/3    00:00:00 bash
4 R  1000  5547  3676  0  80   0 -  7664 -      pts/3    00:00:00 ps

可以发现只用一个-l参数的话只会显示当前控制台下属于当前用户的进程,新增的列有:
F表示内核分配给进程的系统标记;
S表示状态,状态有以下几种:
D 不可中断 Uninterruptible sleep (usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核2.6开始无效)
X 死掉的进程
PRI表示进程的优先级,数字越大表示优先级越低
NI谦让度值用来参与决定优先级
ADDR石金成的内存地址
SZ表示进程被换出,所需交换空间的大致大小
WACHAN表示进程休眠的内核函数的地址

如果输入ps l的话与ps -l的结果基本相同,前者是BSD风格,后者是unix风格,比如输入:

ps l

结果为:

F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1000  3676  3665  20   0  25356  6248 wait   Ss   pts/3      0:00 /bin/bash
4  1000 12893  3676  20   0  30656  1500 -      R+   pts/3      0:00 ps l

其中
VSZ表示进程在内存中的大小,以KB为单位
RSS进程在未换出来时的占用的物理内存
STAT代表进程转台的双字符状态码,这个双字符状态码的第一个字符和unix风格的含义相同,第二个字符为:
< 高优先级
N 低优先级
L 有些页被锁进内存
s 包含子进程
+ 位于后台的进程组;
l 多线程,克隆线程 multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

还有一个用法我个人非常喜欢,输入ps axuf,这个指令可以显示父子进程的关系:

ps axuf

结果为:
5.png

2.1.16 top命令
ps命令有一个缺点,就是只能在某个特定时间点显示进程信息,如果想动态显示内存变化等,可以使用top信息。
输入:

top

结果为:
6.png

该结果中:
第一行有4个参数,分别是当前系统时间(时:分:秒),系统运行时间(时:分),登陆的用户个数,系统的平均负载。其中平均负载有3个值,分别是最近1分钟,最近5分钟和最近15分钟的平均负载,值越大说明负载越高。一般情况下,最近一分钟如果有高负载不足为奇,但如果最近15分钟的负载都非常高,那就有问题了。一般情况下,如果系统负载超过2,就说明系统比较繁忙。

第二行显示了进程的个数信息,有5个参数,分别是进程总个数,当前运行进程个数,睡眠的今晨个数,停止的今晨个数,僵尸进程个数。

第三行显示了CPU相关信息,分别是us:用户态使用的cpu时间比
sy:系统态使用的cpu时间比
ni:用做nice加权的进程分配的用户态cpu时间比
id:空闲的cpu时间比
wa:cpu等待磁盘写入完成时间
hi:硬中断消耗时间
si:软中断消耗时间
st:虚拟机偷取时间

第四行是物理内存相关信息,分别是总共的物理内存,空闲的物理内存,当前使用了多少物理内存,缓存区占用的内存,其中
cache是高速缓存,用于CPU和内存之间的缓冲
buffer是I/O缓存,用于内存和硬盘的缓冲

第五行是交换空的内存。

剩下的都是对一个个进程的描述了,其中
PID是进程的ID
USER是进程所属用户的名字
PR表示进程的优先级
NI表示进程的谦让度值
VIRT表示虚拟内存大小
RES表示物理内存大小
SHR表示进程或其他进程共享的内存总量
S是进程的状态
CPU是进程使用的cpu比例
MEM是进程使用的内存占可用内存的比例
TIME是从进程启动后到当前占用的cpu时间,而不是运行的总时间
COMMAND是进程对应的程序名

默认情况下,是按照cpu使用率排序的,如果想要修改排序标准,按f后移动上下方向键到新的字段上,然后输入s,然后按q退出就行了。

2.1.17 kill命令和killall命令
kill命令使用方法是kill -n pid,表示将n号信号发给pid对应的进程,还有一个命令是killall 进程名。比如输入:

kill -9 2786
killall tcp*

第一条命令是把KILL信号(9号信号)发给2786对应的进程
第二条命令是把所有tcp开头的进程都结束掉。

2.1.18 df命令和du命令
df命令可以查看所有已挂载磁盘的使用情况,比如输入:

aitian@aitian-CW65S:~$ df
文件系统           1K-块     已用     可用 已用% 挂载点
udev             4006220        0  4006220    0% /dev
tmpfs             805608     9576   796032    2% /run
/dev/sdb5      122669092 24513164 91901644   22% /
tmpfs            4028032     7640  4020392    1% /dev/shm
tmpfs               5120        4     5116    1% /run/lock
tmpfs            4028032        0  4028032    0% /sys/fs/cgroup
tmpfs             805608       52   805556    1% /run/user/1000

每一列的解释如下:
第一列为设备的设备位置;
第二列表示能容纳多少个1024字节大小的块;
第三列表示已使用多少个1024字节大小的块;
第四列表示当前还可用多少个1024大小字节的块;
第五列表示以已经使用的比例;
第六列表示设备挂载到了那个挂载点。
df命令可以加-h参数,这个参数能够灵活地调整大小单位,输入:

aitian@aitian-CW65S:~$ df -h
文件系统        容量  已用  可用 已用% 挂载点
udev            3.9G     0  3.9G    0% /dev
tmpfs           787M  9.4M  778M    2% /run
/dev/sdb5       117G   24G   88G   22% /
tmpfs           3.9G  7.5M  3.9G    1% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           3.9G     0  3.9G    0% /sys/fs/cgroup
tmpfs           787M   52K  787M    1% /run/user/1000

df命令能够查看某个磁盘空间使用情况,如果发现某个磁盘空间使用占用很大的时候,可以继续使用du命令看看具体什么目录下有大文件,默认情况下du命令是查看当前目录下所有文件,所有目录,所有子目录的磁盘使用情况,当前也可以指定你想看哪个目录,比如:

aitian@aitian-CW65S:~/at$ du -ch googletest/
1.2M	googletest/googletest/test
8.0K	googletest/googletest/scripts/test
136K	googletest/googletest/scripts
448K	googletest/googletest/src
20K	googletest/googletest/include/gtest/internal/custom
244K	googletest/googletest/include/gtest/internal
508K	googletest/googletest/include/gtest
512K	googletest/googletest/include
120K	googletest/googletest/samples
168K	googletest/googletest/docs
36K	googletest/googletest/cmake
6.6M	googletest/googletest
704K	googletest/googlemock/test
116K	googletest/googlemock/scripts/generator/cpp
148K	googletest/googlemock/scripts/generator
192K	googletest/googlemock/scripts
92K	googletest/googlemock/src
24K	googletest/googlemock/include/gmock/internal/custom
68K	googletest/googlemock/include/gmock/internal
620K	googletest/googlemock/include/gmock
624K	googletest/googlemock/include
240K	googletest/googlemock/docs
12K	googletest/googlemock/cmake
1.9M	googletest/googlemock
44K	googletest/ci
8.6M	googletest/
8.6M	总用量

其中c表示显示已列出文件的总大小,h参数表示灵活使用单位。发现df和du命令使用-h参数非常方便,其实ls命令也可以使用-h参数的。

2.1.19 sort命令
sort命令对文本按照字典顺序排序,数字在字母前面,大小字母在小写字母前面,比如a.txt内容为:

wu lin wai zhuan
Wu lin feng
zhao ben shan
Zeng zeng zeng
liu lao gen
ye shen ren bu jing
123
78
5

输入:

sort a.txt

结果为:

123
5
78
liu lao gen
Wu lin feng
wu lin wai zhuan
ye shen ren bu jing
Zeng zeng zeng
zhao ben shan

可以发现,虽然字符串正常的排序了,但是数字并没有按照先小后大的顺序排序,这是因为默认情况下,数字是被当作字符串处理的,如果想数字按照大小排序的话,加上-n参数。

aitian@aitian-CW65S:~/at/shell/0$ sort -n a.txt 
liu lao gen
Wu lin feng
wu lin wai zhuan
ye shen ren bu jing
Zeng zeng zeng
zhao ben shan
5
78
123

还有一种用法,非常常用。sort刚才sort排序的时候默认用的是第一列,比如

aitian@aitian-CW65S:~/at/shell/0$ du -cs *|sort -n
0	0
0	file_soft
4	abc
4	a.txt
4	log.txt
4	test.c
4	test.sh
4	testshell.sh
12	a.out
12	main
2004	file
2052	总用量

如果不想用第一列,而是想要其他列的数据怎么办呢?可以使用-k参数,-k参数就是告诉sort命令使用第几列的数据进行排序,比如有一个文件b.txt的内容为:

aitian@aitian-CW65S:~/at/shell/0$ sort -k 2 -n b.txt 
liuliuliu -7  90
hululu 0 89
wulinwaizhuan 34 567
chenchenchen 79 1089
aitian@aitian-CW65S:~/at/shell/0$ sort -k 3 -n b.txt 
hululu 0 89
liuliuliu -7  90
wulinwaizhuan 34 567
chenchenchen 79 1089

可以发现上面有一个负数-7也能被正确排序,其实不仅仅符号,浮点数也可以的。那这里有一个问题,sort是怎么知道第一列第二列的呢?实际上默认情况下,sort根据空格制表符,也就是空白区域来分割以列数据。有时候需要用特定的分割符号来进行分割,这个时候使用-t参数,比如哟一个文件c.txt,内容为:

wulinwaizhuan-0.34-567
hululu-0.01-89
chenchenchen-0.79-1089
liuliuliu-0.7-90

输入:

aitian@aitian-CW65S:~/at/shell/0$ sort -t '-' -k 2 -n c.txt 
hululu-0.01-89
wulinwaizhuan-0.34-567
liuliuliu-0.7-90
chenchenchen-0.79-1089

之前所有的命令都是牲畜输出,可以加上-r参数改成降序输出

aitian@aitian-CW65S:~/at/shell/0$ du -c *|sort -nr
2060	总用量
2004	file
12	main
12	a.out
4	testshell.sh
4	test.sh
4	test.c
4	log.txt
4	c.txt
4	b.txt
4	a.txt
4	abc
0	file_soft
0	0

2.1.20 tar命令
tar命令可以归档文件,对文件进行压缩或者解压,比如

aitian@aitian-CW65S:~/at/shell/0$ tar -cvf target.tar abc/ a.txt 
abc/
abc/aaa
a.txt
aitian@aitian-CW65S:~/at/shell/0$ tar -tf target.tar 
abc/
abc/aaa
a.txt
aitian@aitian-CW65S:~/at/shell/0$ tar -xvf target.tar 
abc/
abc/aaa
a.txt

其中tar -cvf 对后面的所有目录和文件压缩到target.tar文件,tar -tf列出target.tar文件中的内容,tar -xvf对target.tar文件进行解压。

2.2 shell父子进程
2.2.1 shell父子进程关系
当在shell的cli输入bash之后,会开启一个新的shell进程,并且是第一个shell的子进程,比如:

aitian@aitian-CW65S:~$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
aitian    5307  5296  0 10:59 pts/2    00:00:00 /bin/bash
aitian    6115  5307  0 11:07 pts/2    00:00:00 ps -f
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
aitian    5307  5296  0 10:59 pts/2    00:00:00 /bin/bash
aitian    6116  5307  0 11:07 pts/2    00:00:00 bash
aitian    6149  6116  0 11:08 pts/2    00:00:00 ps -f
aitian@aitian-CW65S:~$ echo $$
6116
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $$
5307

通过pid和ppid可以看出父子进程关系,通过exit退出的是子进程的shell,通过$$打印当前shell的进程pid。
当前通过输入ps -uf可以看出父子进程的关系:

aitian@aitian-CW65S:~$ ps -uf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
aitian    5307  0.0  0.0  25304  6012 pts/2    Ss   10:59   0:00 /bin/bash
aitian    7187  0.0  0.0  25316  6088 pts/2    S    11:12   0:00  \_ bash
aitian    7471  0.0  0.0  39104  3300 pts/2    R+   11:14   0:00      \_ ps -uf

通过上面可以看出,ps命令实际上是bash拉起的一个新的进程。

2.2.2 进程列表
如果有多个命令想要执行,可以通过分号(;)隔开,这样所有的命令都会依次执行,例如

aitian@aitian-CW65S:~/at$ pwd;cd shell/;pwd
/home/aitian/at
/home/aitian/at/shell
aitian@aitian-CW65S:~/at/shell$ pwd
/home/aitian/at/shell

不过这所有的命令都是父进程执行的命令,如果想构造成进程列表,必须加上小括号。

aitian@aitian-CW65S:~/at$ (pwd;cd shell/;pwd)
/home/aitian/at
/home/aitian/at/shell
aitian@aitian-CW65S:~/at$ pwd
/home/aitian/at

从上面的结果可以看出两个pwd打印出来的内容是完全相同的。但是,加上括号之后是新开了一个子进程来执行括号中的命令,但是不加括号是父进程直接执行的。不过看第四行可以看出差别。不加括号的时候,执行是父进程执行命令,所有命令执行之后,当前路径为/home/aitian/at/shell。可以使用进程列表之后,当前的路径是/home/aitian/at,这是因为所有的命令都是子进程在运行,运行后退回主进程。

还有一个方法可以判断是否生成了子shell,那就是通过打印BASH_SUBSHELL的值,比如输入:

aitian@aitian-CW65S:~/at$ pwd;echo $BASH_SUBSHELL
/home/aitian/at
0
aitian@aitian-CW65S:~/at$ (pwd;echo $BASH_SUBSHELL)
/home/aitian/at
1

注意括号里面可以再加括号,比如输入:

aitian@aitian-CW65S:~/at$ (pwd;(pwd;echo $BASH_SUBSHELL))
/home/aitian/at
/home/aitian/at
2

这说明子shell会再生成新的shell去执行命令。

2.2.3 后台模式运行进程
通过在命令的结尾加上&符号可以让命令在后台运行,同时让出CLI,比如:

aitian@aitian-CW65S:~/at$ sleep 100&
[1] 14305
aitian@aitian-CW65S:~/at$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
aitian    5307  5296  0 10:59 pts/2    00:00:00 /bin/bash
aitian    7187  5307  0 11:12 pts/2    00:00:00 bash
aitian   14305  7187  0 11:55 pts/2    00:00:00 sleep 100
aitian   14306  7187  0 11:55 pts/2    00:00:00 ps -f
aitian@aitian-CW65S:~/at$ jobs
[1]+  运行中               sleep 100 &
aitian@aitian-CW65S:~/at$ jobs -l
[1]+ 14305 运行中               sleep 100 &

上面的结果中,先以后台模式运行sleep命令,会自动打印出一个后台信息,其中方括号中的1表示后台作业号,后面是pid。通过ps -f可看到sleep进程。通过jobs命令可以看到当前在后台模式的所有用户的作业,jobs -l可以看出作业对应的pid。
不仅仅命令后面加&符号可以让其在后台运行,运行bash命令的后面加上&也可以使其后台运行。

2.3 外部命令和内建命令
2.3.1 外部命令
外部命令是文件系统命令,不是shell程序的一部分,通常位于/bin,/usr/bin,/sbin或/usr/sbin中,比如ps命令就是一个外部命令。比如:

aitian@aitian-CW65S:~/at/shell$ which ps
/bin/ps
aitian@aitian-CW65S:~/at/shell$ type -a ps
ps 是 /bin/ps

当外部命令执行时,会创建出一个子进程。
2.3.2 內建命令
內建命令是属于shell的一部分,內建命令在shell中被执行的时候是不会创建子进程的。比如cd命令

aitian@aitian-CW65S:~/at/shell$ type -a cd
cd 是 shell 内建

2.3.2.1 history內建命令
history命令打印出用过的命令,比如

 2048  which ps
 2049  type -a ps
 2050  type -a cd
 2051  history
 2052  history|more
 2053  history|less
 2054  history -n 10
 2055  clear
 2056  history -a
 2057  history 
 2058  pwd
 2059  history

越往后是最新的。

2.3.2.2 alias命令
alias命令也是內建命令,可以给命令指定一个别名,输入:

aitian@aitian-CW65S:~/at/shell$ alias pbc='pwd'
aitian@aitian-CW65S:~/at/shell$ pbc
/home/aitian/at/shell
  1. 环境变量
    环境变量是存储有关shell会话和工作环境的信息,环境变量允许脚本轻松访问他们,环境变量分为全局变量和局部变量。
    3.1 全局环境变量
    全局环境变量对于shell会话和所有生成的子shell都是有效的,局部变量则只对变量创建的shell有效。要查看全局变量可以使用env或者printenv命令。
aitian@aitian-CW65S:~/at/shell$ printenv
LC_PAPER=zh_CN.UTF-8
XDG_VTNR=7
ORBIT_SOCKETDIR=/tmp/orbit-aitian
XDG_SESSION_ID=c2
LC_ADDRESS=zh_CN.UTF-8
CLUTTER_IM_MODULE=xim
IBUS_DISABLE_SNOOPER=1
TERMINATOR_UUID=urn:uuid:08541795-c8ff-4ab7-8692-dcb8925f822f
LC_MONETARY=zh_CN.UTF-8

如果想要查看指定的变量:

aitian@aitian-CW65S:~/at/shell$ printenv HOME
/home/aitian
aitian@aitian-CW65S:~/at/shell$ echo $HOME
/home/aitian

3.2 局部环境变量
局部环境变量只能在定义它们的进程中可见,set命令会显示进程设置的所有环境变量,包括全局环境变量,局部环境变量和用户自定义变量。比如输入:

aitian@aitian-CW65S:~/at/shell$ a=xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$ set|grep xiangcunaiqing
a=xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$ env|grep xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$

set命令会显示出全局变量,局部变量和用户自定义变量,同时set命令会对结果进行排序,不过env和printenv不会对结果进行排序,也不会输出局部变量和用户自定义变量。

3.3 设置变量
可以在shell中设置变量,比如创建当前shell进程内有效的局部变量,比如:

aitian@aitian-CW65S:~$ echo $variable

aitian@aitian-CW65S:~$ variable=str_test
aitian@aitian-CW65S:~$ echo $variable
str_test

这个局部变量只能在当前的shell中有效,在其他的shell中无法访问。比如:

aitian@aitian-CW65S:~$ var=xiangcun
aitian@aitian-CW65S:~$ echo $var
xiangcun
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $var

父进程设置的局部变量在子进程中是无法访问的,同时子进程设置的局部变量在父进程也是无法访问的。如果想要父进程的变量在子进程也可以访问,那么必须使用全局变量,使用export导出全局变量。

aitian@aitian-CW65S:~$ variable1="xiang cun ai qing"
aitian@aitian-CW65S:~$ echo $variable
str_test
aitian@aitian-CW65S:~$ export variable
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $variable
str_test
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $variable
str_test

要注意,在父进程导出的全局变量,子进程可以访问,但是如果在子进程修改这个全局变量的值,不会影响父进程该全局变量的值。比如:

aitian@aitian-CW65S:~$ var2="liu lao gen"
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
aitian@aitian-CW65S:~$ export var2
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
aitian@aitian-CW65S:~$ var2="gen lao liu"
aitian@aitian-CW65S:~$ echo $var2
gen lao liu
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
    可以看出子进程修改了全局环境变量的值,但是父进程该全局变量的值并没有改变。这是因为实际上,全局变量是父进程继承给子进程的,可以理解子进程的内存空间里面也有这个值,并且其初始值就是父进程中设置的值。所以说,这个全局变量是继承的。如果我们重新打开一个新的shell,是无法访问其他shell   export出来的变量的,因为这之间没有继承关系。
    如果在子进程中export一个全局变量,在父进程中无法访问这个全局变量,因为父进程无法继承子进程中的变量。
aitian@aitian-CW65S:~$ echo $var

aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ var=123
aitian@aitian-CW65S:~$ export var
aitian@aitian-CW65S:~$ echo $var
123
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $var

全局变量也可以删除,使用unset命令,比如:

aitian@aitian-CW65S:~$ var=123
aitian@aitian-CW65S:~$ export var
aitian@aitian-CW65S:~$ printenv var
123
aitian@aitian-CW65S:~$ unset var
aitian@aitian-CW65S:~$ printenv var
aitian@aitian-CW65S:~$ 

3.4 设置PATH环境变量
当在shell中输入一个外部命令的时候,shell怎么去找这个程序在哪里呢?PATH环境变量定义了用于进行程序查找的目录,比如:

aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin

这里面的路径用冒号分隔开,这里使用了sed命令换行显示。可以把某个目录加到PATH环境变量中,比如:

aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin
aitian@aitian-CW65S:~$ PATH=$PATH:/home/root
aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin
/home/root

3.5 系统环境变量
如果在PATH里面添加一个路径,当重启系统或者退出这个shell之后,新增的路径就没有了。所以需要设置系统环境变量,也就是任何用户在重启系统之后都可以继续访问最新的变量。
3.5.1 /etc/profile文件
/etc/profile文件是bash shell默认的主启动文件, 只要一登录linux系统,bash就会执行/etc/profile启动文件中的命令,这个文件或导出一些系统环境变量。
3.5.2 用户专属启动文件
除了/etc/profile文件外,还有4个启动文件,这4个启动文件都起着相同的作用,都是用来提供用户专属的环境变量。这四个文件都位于用户的HOME目录下,分别是:

$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_login
$HOME/.profile

当然,大多数linux发行版只用这4个启动文件中的一个或者两个。用户可以编辑这些文件为自己添加自己专属的环境变量,这些环境变量会在每次启动bash shell的时候生效。

注意一般情况下,都把变量放进.bashrc文件或者放进/etc/profile文件中。

3.6 数组变量
数组变量可以存储多个值,比如

aitian@aitian-CW65S:~$ array=(apple banana cindy dog egg)
aitian@aitian-CW65S:~$ echo $array
apple
aitian@aitian-CW65S:~$ echo ${array[2]}
cindy
aitian@aitian-CW65S:~$ echo ${array[*]}
apple banana cindy dog egg
aitian@aitian-CW65S:~$ array[2]=fruit
aitian@aitian-CW65S:~$ echo ${array[*]}
apple banana fruit dog egg
  1. linux安全
    linux安全是通过用户和组根据每个文件和目录的安全性设置来访问文件,linux安全的核心是用户账户,每个能进入linux系统的用户都会被分配唯一的用户账户,用户对系统中各种对象的访问权限取决于用户。用户权限是通过创建用户时分配的用户ID(UID)来跟踪的,UID是一个数字。
    4.1 /etc/passwd文件
    linux系统用/etc/passwd文件将用户的登录名匹配到对应的UID,比如:
aitian@aitian-CW65S:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

root用户账户是linux系统的管理员,对应的UID永远为0.其余还有一些UID是1或者2或者3这样的,那是针对特殊服务设定的UID。LINUX为系统账户预留了500已下的UID。上面一行数据通过冒号分隔开,一共有7个字段,分别是:
用户名,用户密码,UID,组ID(GID),用户账户的文本描述,用户HOME目录的位置,用户默认的shell。
4.2 /etc/shadow文件
上面的密码段被写成了x,真正的密码存储在/etc/shadow中,只有特定的程序比如登录程序才能访问这个文件。比如:

aitian@aitian-CW65S:~$ sudo cat /etc/shadow
[sudo] aitian 的密码: 
root:!:17908:0:99999:7:::
daemon:*:16911:0:99999:7:::
bin:*:16911:0:99999:7:::
sys:*:16911:0:99999:7:::

4.3 用户设置
用户设置包括添加新用户,删除用户,修改用户。
4.3.1 添加新用户
添加新用户的时候有一些缺省值,如下:

aitian@aitian-CW65S:~$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

上面的默认值的含义是:
新用户被添加到GID为100的公共组
新用户的HOME目录为/home/登录名
新用户账户密码过期后不会被禁用
新用户账户未被设置过期日期
默认的shell是bash shell
系统会把/etc/skel目录下的内容复制到用户的HOME目录下
系统为该用户账户在mail目录下创一个用于接收邮件的文件
其中/etc/skel中的内容为:

aitian@aitian-CW65S:~$ ls -al /etc/skel/
总用量 44
drwxr-xr-x   2 root root  4096 7月  28  2019 .
drwxr-xr-x 152 root root 12288 2月  14 21:21 ..
-rw-r--r--   1 root root   220 9月   1  2015 .bash_logout
-rw-r--r--   1 root root  3771 9月   1  2015 .bashrc
-rw-r--r--   1 root root  8980 4月  20  2016 examples.desktop
-rw-r--r--   1 root root  2181 11月  2  2015 .kshrc
-rw-r--r--   1 root root   655 5月  16  2017 .profile

这些都是标准启动文件。

现在来新增一个用户并查看:

aitian@aitian-CW65S:~$ sudo useradd -m new_user
[sudo] aitian 的密码: 
aitian@aitian-CW65S:~$ ls -al /home/new_user/
总用量 36
drwxr-xr-x 2 new_user new_user 4096 2月  23 18:04 .
drwxr-xr-x 6 root     root     4096 2月  23 18:04 ..
-rw-r--r-- 1 new_user new_user  220 9月   1  2015 .bash_logout
-rw-r--r-- 1 new_user new_user 3771 9月   1  2015 .bashrc
-rw-r--r-- 1 new_user new_user 8980 4月  20  2016 examples.desktop
-rw-r--r-- 1 new_user new_user 2181 11月  2  2015 .kshrc
-rw-r--r-- 1 new_user new_user  655 5月  16  2017 .profile

这里的-m参数是让他创建HOME目录,如果不加-m参数,对应的牡蛎将不会被创建。这里的创建用的都是默认值。除了-m之外,还有一些其他的参数可以指定别的参数而不使用默认值。

4.3.2 删除用户
userdel命令可以删除用户,默认情况下,如果不加任何参数,只会删除/etc/passwd文件中的用户信息,而不会删除系统中属于该账户的任何文件。如果-r参数,会删除用户的HOME目录以及邮件目录,但是系统上仍可能存在用户的其他文件。

aitian@aitian-CW65S:/home$ sudo userdel -r new_user
[sudo] aitian 的密码: 
userdel: new_user 邮件池 (/var/mail/new_user) 未找到

4.3.4 修改用户
修改用户要用特定命令。
4.3.4.1 usermod 根据指定的参数修改对应的值
4.3.4.2 passwd和chpasswd修改用户密码

aitian@aitian-CW65S:/home$ sudo passwd new_user
输入新的 UNIX 密码: 
重新输入新的 UNIX 密码: 
passwd:已成功更新密码
aitian@aitian-CW65S:/home$ su new_user
密码: 
new_user@aitian-CW65S:/home$ id
uid=1001(new_user) gid=1002(new_user) 组=1002(new_user)

4.4 用户组
/etc/group文件包含系统上用到的组的信息,比如:

aitian@aitian-CW65S:/home$ cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
.
.
.
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:

这里的四个字段分别是:组名,组密码,GID,属于该组的用户列表
4.4.1 创建新组
groupadd命令用于新增一个group,比如

aitian@aitian-CW65S:/home$ sudo groupadd new_group
[sudo] aitian 的密码: 
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
new_group:x:1003:

从最后两行可以发现,new_user用户对应的GID是1002.对应的组名也叫new_user,new_group对应的UID为1003.
通过usermod修改一个用户对应的group,比如:

aitian@aitian-CW65S:/home$ sudo usermod -G new_group new_user
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
new_group:x:1003:new_user

4.4.2 修改组
groupmod命令用于修改已有组的信息,通过-g修改GID,通过-n修改组名。所有的权限都是基于GID的,所以可以随意改变组名不会影响安全性。比如

aitian@aitian-CW65S:/home$ sudo groupmod -n  rename_group new_group
[sudo] aitian 的密码: 
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
rename_group:x:1003:new_use
  1. 文件权限
    首先看下面的结果:
aitian@aitian-CW65S:~/at/shell$ ll test9.sh 
-rwxrwxrwx 1 aitian aitian 54 12月  7 23:00 test9.sh*

这里的3组rwx分别是,文件的属主s,文件的属组,系统其他用户的权限。

发布了12 篇原创文章 · 获赞 0 · 访问量 132

猜你喜欢

转载自blog.csdn.net/weixin_36888250/article/details/104468245
-0-