跟运维学 Linux – 02

  • 跟运维学 Linux – 02已关闭评论
  • 104 次浏览
  • A+
所属分类:linux技术
摘要

在Windows中我们可以通过快捷键 ctrl + c 复制,ctrl + v 粘贴,在 linux 中需要使用命令。


文件操作和用户

复制移动和删除

在Windows中我们可以通过快捷键 ctrl + c 复制,ctrl + v 粘贴,在 linux 中需要使用命令。

复制移动

cp 就是 copy 的意思。请看示例:

// 将 a.txt 复制一份,重命名为 b.txt test11@pj-pc:~$ cp a.txt b.txt test11@pj-pc:~$ ls 模板  桌面  a.txt  b.txt  dir1 
// 将 a.txt 复制到 dir1 目录中 test11@pj-pc:~$ cp a.txt dir1 test11@pj-pc:~$ ls dir1 a.txt 
// 将 dir1/a.txt 复制到当前目录 test11@pj-pc:~$ cp dir1/a.txt . 

如果当前目录有同名的文件,需要询问是否覆盖,可以使用参数 -i

// -i 会询问是否覆盖 test11@pj-pc:~$ cp -i dir1/a.txt . cp:是否覆盖'./a.txt'? n test11@pj-pc:~$ rm a.txt // 没有同名文件,则无需询问 test11@pj-pc:~$ cp -i dir1/a.txt . test11@pj-pc:~$ 

文件夹的拷贝需要使用参数 -r,否则会提示错误:

// 报错:缺少 -r test11@pj-pc:~$ cp dir1 dir2 cp: 未指定 -r;略过目录'dir1' // 拷贝目录 test11@pj-pc:~$ cp -r dir1 dir2 test11@pj-pc:~$ ls 模板  桌面  dir1  dir2 

拷贝文件比较清晰,而拷贝文件夹就没那么好理解,我们分几种情况详细介绍:

// 将 dir1 文件夹拷贝到 dir2目录中 test11@pj-pc:~/dir$ cp -r dir1 dir2 test11@pj-pc:~/dir$ ls dir2 c.txt  dir1 test11@pj-pc:~/dir$ 
// tree 可通过包管理器安装 test11@pj-pc:~/dir$ tree . ├── a.txt ├── dir1 │   └── b.txt └── dir2     └── c.txt  2 directories, 3 files // 将dir1文件夹中的内容拷贝到 dir2 中 test11@pj-pc:~/dir$ cp dir1/* dir2 test11@pj-pc:~/dir$ ls dir2 b.txt  c.txt 

dir1/a.txt 拷贝到当前目录,以下两种写法一个有提示,一个没有提示,是什么原因?

test11@pj-pc:~/dir$ tree . ├── a.txt ├── dir1 │   ├── a.txt │   └── b.txt └── dir2     ├── b.txt     └── c.txt  2 directories, 5 files // 没有提示 test11@pj-pc:~/dir$ cp dir1/a.txt . // 有提示 test11@pj-pc:~/dir$ cp dir1/a.txt . cp:是否覆盖'./a.txt'? y 

通过 alias 命令我们得知 cp 其实等同于 cp -i,所以有提示,而 cp 表示不使用别名,表示纯 cp 命令。

test11@pj-pc:~/dir$ alias alias cp='cp -i' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l='ls -CF' alias la='ls -A' alias ll='ls -alF' alias ls='ls --color=auto' 

Tip:alias 显示当前定义的别名。创建一个新的别名 alias ll='ls -l',删除一个别名 unalias ll

删除

删除文件和目录需要使用 rm 命令。

文件直接即可删除:

test11@pj-pc:~/dir$ ls a1.txt  a2.txt  a3.txt  dir1  dir2 // 删除文件 test11@pj-pc:~/dir$ rm a1.txt // -i 删除前确认 test11@pj-pc:~/dir$ rm -i a2.txt rm:是否删除普通空文件 'a2.txt'?n test11@pj-pc:~/dir$ 

删除文件夹需要使用 -r 参数,否则报错:

// 报错:需要使用 -r test11@pj-pc:~/dir$ rm dir1 rm: 无法删除'dir1': 是一个目录 // 删除目录 test11@pj-pc:~/dir$ rm -r dir1 test11@pj-pc:~/dir$ ls a2.txt  a3.txt  dir2 // 删除前确认 test11@pj-pc:~/dir$ rm -ir dir2 rm:是否进入目录'dir2'? y rm:是否删除普通空文件 'dir2/c.txt'?y rm:是否删除普通空文件 'dir2/b.txt'?y rm:是否删除目录 'dir2'?y test11@pj-pc:~/dir$ ls a2.txt  a3.txt 

Tip: 一名合格的运维工程师在修改文件之前需要对源文件(文件夹)进行备份。否则一旦改错,又改不回去,就很麻烦。

查找文件和隐藏文件

比如知道文件或文件夹的名字,但忘记在哪里,可以使用 find 命令。

// 在当前目录中查找名字是 dir2 的文件或名录 test11@pj-pc:~/dir$ find . -name dir2 ./dir1/dir2 ./dir2 

ls 显示的是非隐藏文件(文件夹),如果需要查看隐藏文件(文件夹),可以增加参数 -a

test11@pj-pc:~/dir$ ls a3.txt  dir1 // 显示隐藏文件和隐藏目录 test11@pj-pc:~/dir$ ls -a // . 当前目录 // .. 上一层目录 .  ..  .a2.txt  a3.txt  dir1  .dir2 

隐藏文件(文件夹)以点(.)开头,也是一种保护机制。

隐藏文件查看方式和普通文件相同:

test11@pj-pc:~/dir$ cat .a2.txt apple 

如果需要将隐藏文件或隐藏目录转成非隐藏,重命名(删除.)即可。

test11@pj-pc:~/dir$ mv .a2.txt a2.txt test11@pj-pc:~/dir$ mv .dir2 dir2 // a2.txt 和 dir2 不在隐藏 test11@pj-pc:~/dir$ ls a2.txt  a3.txt  dir1  dir2 

一切皆文件

我们现在一直围绕着文件学习 linux 命令,为什么总是围绕文件?因为 Linux 中一切皆文件。

笔者的 linux 有一块磁盘 /dev/sda 931G。

/dev/sda 是一个文件,用它来表示硬盘。

// fdisk -l 查看本地磁盘信息 pj@pj-pc:/home/test11/dir$ sudo fdisk -l Disk /dev/sda:931.53 GiB,1000204886016 字节,1953525168 个扇区 Disk model: WDC WD10EZEX-75W 单元:扇区 / 1 * 512 = 512 字节 ... 

这个文件和其他文件一样,也有自己的属性:

pj@pj-pc:/home/test11/dir$ ls -l /dev/sda brw-rw---- 1 root disk 8, 0 7月  17 14:52 /dev/sda 

最前面的一位 b,b=block,也就是块设备,说白了就是硬盘。

于是我们知道在 linux 中,用文件表示各种东西。

路径

登陆后默认来到用户的家目录,但对于 linux 来说,家目录不是不是最原始的起点。

Linux 下所有目录最开始的起点叫做“根”,也就是/。所有目录都以它为起点,如树杈一样,一层一层向下扩展。

感觉根有点虚,其实是可以看见的:

pj@pj-pc:~$ ls / backup  bin  boot  cdrom  data  dev  etc  home  lib  lib32  lib64  libx32  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var 

这里显示的就是一级目录,不同发行版,一级目录都差不多(目录名)

pj@pj-pc:~$ tree -L 1 / / ├── backup ├── bin -> usr/bin ├── boot ├── cdrom ├── data ├── dev ├── etc ├── home ├── lib -> usr/lib ├── lib32 -> usr/lib32 ├── lib64 -> usr/lib64 ├── libx32 -> usr/libx32 ├── lost+found ├── media ├── mnt ├── opt ├── proc ├── root ├── run ├── sbin -> usr/sbin ├── srv ├── sys ├── tmp ├── usr └── var  25 directories, 0 files  

如果一个路径从 / 开始,例如 "/home/user1/xx" 就是一个绝对路径。

无敌的 root

接下来我们得真正用 linux 干点活了。

主管:来了2个新人,你(运维工程师)给他们在服务器A中给他们创建账号并邮件通知他们(省去许多其他要求...)

在 windows 中,给用户创建账号,最好是管理员角色。在 linux 中不叫管理员,而是 root,也是一个特殊的用户。

root 在 linux 中拥有最高的权限,无所不能。所以公司通常会加以限制,root账户只对少数人开放(其他人不允许用root登录),例如运维工程师,为了服务器和系统的稳定需要随时拥有最高权限。

通过 whoami 查看当前用户:

pj@pj-pc:~$ whoami user-pj 

Tip: 笔者没有测试服务器的 root 账号。

useradd 创建用户(sudo 让普通用户临时拥有root的权限),并通过 id 查看用户是否真的被创建出来:

// 创建一个叫 test18 的用户 pj@pj-pc:~$ sudo useradd test18 // 用户创建成功 pj@pj-pc:~$ id test18 uid=1005(test18) gid=1005(test18) 组=1005(test18) pj@pj-pc:~$ 

Tip:adduser 和 useradd 功能类似,但有一些区别。adduser 是一个高级的用户管理工具;而 useradd 更基本,比如 useradd 不会创建家目录;

root 不是角色,而是一个实实在在的用户。虽然 root 用户只有一个,但是通过权限和分组,可以让普通用户拥有root一样高的权限。

// 创建一个叫 root 的用户 pj@pj-pc:~$ sudo useradd root 输入密码 useradd:用户“root”已存在 

现在我们创建了 test18 用户,接下来得给他分配密码。通过 passwd 给用户创建密码:

pj@pj-pc:~$ sudo passwd test18 新的密码: // linux 中密码有一定规范 无效的密码:密码少于 8 个字符 新的密码: 无效的密码:密码包含的字符类型少于 2 种 新的密码: 重新输入新的密码: passwd:已成功更新密码 

Tip: 如果你使用root给新用户创建密码,即使使用一个不符合规则的密码,也能创建成功,因为 root 有最高权限。

如果需要切换用户登录,可以使用 su - 用户名

pj@pj-pc:~$ su - test18 输入密码 $ // 再次确定是否切换成功 $ whoami test18 $ id uid=1006(test18) gid=1006(test18) 组=1006(test18) $ 

登录后修改自己的密码,直接输入 passwd 即可:

$ passwd 为test18更改密码 当前密码: 新的密码: 无效的密码:与旧密码相同 新的密码: 

系统账号

前面我们已经对linux 账号有所了解(root、普通用户),这里我们在认识一下系统账号

系统账号不是给人用的,而是给程序用的。系统账号长什么样子?比如 mail:

pj@pj-pc:~$ id mail uid=8(mail) gid=8(mail) 组=8(mail) 

系统账号安装软件时,程序自动创建的。例如现在没有ntp账号,安装 ntp 只有就有该账号了:

// 没有 ntp 账号 pj@pj-pc:~$ id ntp id: “ntp”:无此用户 
// 安装 ntp pj@pj-pc:~$ sudo apt install ntp 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 ... // 有 ntp 账号 pj@pj-pc:~$ id ntp uid=124(ntp) gid=132(ntp) 组=132(ntp) 

系统账号不能拿来直接使用,而是软件运行时,由它们自己来使用。

Tip:约定Uid小于1000的是系统账号。

第一个配置文件

只是学会用命令创建账号、修改密码,这是最基本的入门。

我们要深入探索 Linux 用户账号,先学习用户账号的管理。

要掌握 linux 用户管理,首先得知道全部用户都定义在哪里。如下操作:

pj@pj-pc:~$ head /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 lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin 

/etc 目录放置的都是配置文件,全部用户就定义在 /etc/passwd 配置文件中。

这些都是用户:root、daemo、bin...

pj@pj-pc:~$ id root uid=0(root) gid=0(root) 组=0(root)  pj@pj-pc:~$ id daemon uid=1(daemon) gid=1(daemon) 组=1(daemon)  pj@pj-pc:~$ id bin uid=2(bin) gid=2(bin) 组=2(bin)  

先来认识一下什么是配置文件

我们的 linux 上面运行着各种各样的软件,软件到了底层,就是程序在运行。

如果想改变程序的运行方式,直接跟程序说没用,因为程序不接受你的直接调遣。如果你通过配置文件让其改变,程序就会乖乖就范。

上文我们学习的用户管理,背后也是有对应的程序在运行。

我们直接通过命令 useradd 创建用户,根本没有接触配置文件,其实这是表象。做一个试验就知道了。我们直接修改 /etc/passwd 模仿 test18 增加一条数据:

pj@pj-pc:~$ id test19 id: “test19”:无此用户 
pj@pj-pc:~$ tail -n 2 /etc/passwd test18:x:1006:1006::/home/test18:/bin/sh test19:x:1007:1007::/home/test19:/bin/sh 

用户(test19)创建成功:

// 不一样 pj@pj-pc:~$ id test19 uid=1007(test19) gid=1007 组=1007 pj@pj-pc:~$ id test18 uid=1006(test18) gid=1006(test18) 组=1006(test18) 

这样编辑一下 /etc/passwd 创建创建出来的用户,是不完整的,缺少一些东西,接下来将围绕这个遗留问题,继续操作和讲解。

用户组

用户 test18 使用useradd 命令创建,而 test19 是直接编辑配置文件创建的。通过 id 就会发现有所不同:

pj@pj-pc:~$ id test18 uid=1006(test18) gid=1006(test18) 组=1006(test18) 
// gid=1007(缺少) 组=1007(缺少) pj@pj-pc:~$ id test19 uid=1007(test19) gid=1007 组=1007 

为了讲清楚这部分差异,我们下面分几个步骤。

在linux中,每个用户必须属于一个组织,这个组织就是主组(gid)和附属组(groups,笔者这里就是)。

以 test18 为例,gid=1006(test18) 其主组是 test18,组=1006(test18) 附属组也是 test18。

当执行 useradd,系统会给 test18 创建一个同名的组 test18,并让该用户的主组是它。

主组只有一个,附属组可以没有或者有多个。下面我们给 test18 增加一个附属组(usermod -aG):

// 通过 usermod 给 test18 增加一个附属组 pj@pj-pc:~$ sudo usermod -aG mail test18 输入密码 pj@pj-pc:~$ id test18 uid=1006(test18) gid=1006(test18) 组=1006(test18),8(mail) pj@pj-pc:~$ 

组在哪里定义的,我们可以自己创建吗?

pj@pj-pc:~$ cat /etc/group |grep 'test18' mail:x:8:test18 test18:x:1006: 

/etc/group 配置文件中定义了所有的组,其中用户test18的主组gid=1006(test18)就在其中:

pj@pj-pc:~$ id test18 uid=1006(test18) gid=1006(test18) 组=1006(test18),8(mail) 

而 test19 对应的组 1007 根本不存在

pj@pj-pc:~$ id test19 uid=1007(test19) gid=1007 组=1007 

给配置文件增加一行(test19:x:1007:):

pj@pj-pc:~$ cat /etc/group |egrep "test18|test19" mail:x:8:test18 test18:x:1006: // 增加这一行(shift+g定位到最后一行) test19:x:1007: 

这样就显示正常了:

pj@pj-pc:~$ id test19 uid=1007(test19) gid=1007(test19) 组=1007(test19) pj@pj-pc:~$ 

我们在看下面段代码,1007:1007 是什么?

pj@pj-pc:~$ cat /etc/passwd |egrep "test18|test19" test18:x:1006:1006::/home/test18:/bin/sh test19:x:1007:1007::/home/test19:/bin/sh 

前一个1007表示系统分配给用户 test19 的 ID,不可以随便改变,后一个1007是主组ID

Tip:在Linux用户管理系统中,每个用户和组都有一个唯一的数字标识符(UID和GID)。虽然用户名和组名更加易于人类理解,但实际上,系统在内部使用对应的数字来识别用户和组。

做一个小实验,看主组能否改变。

将 test19 的主组id改成test18的主组id:

pj@pj-pc:~$ tail -n 2 /etc/passwd test18:x:1006:1006::/home/test18:/bin/sh test19:x:1007:1006::/home/test19:/bin/sh 

真的改成功了,现在 test19 的用户组是 test18:。

pj@pj-pc:~$ id test19 uid=1007(test19) gid=1006(test18) 组=1006(test18) 

我们再做一个实验,如果一个用户,一个组都不属于会怎么样?

pj@pj-pc:~$  tail -n 2 /etc/passwd test18:x:1006:1006::/home/test18:/bin/sh test19:x:1007:::/home/test19:/bin/sh 

用户信息报错:

pj@pj-pc:~$ id test19 id: “test19”:无此用户 

用户家目录

我们编辑配置文件创建了 test19,前文已经知道 1007:1007 的含义:

test19:x:1007:1007::/home/test19:/bin/sh 

现在再来看一下 /home/test19,表示test19的家目录。

pj@pj-pc:~$ ls /home/test19 ls: 无法访问'/home/test19': 没有那个文件或目录 

既然没有这个目录,我们自己创建:

// 创建目录 pj@pj-pc:~$ sudo mkdir /home/test19 pj@pj-pc:~$ ls -l /home drwxr-xr-x  2 root    root    4096 7月  18 15:08 test19 // 将 /home/test19 目录及其所有子目录和文件的所有者和所属群组都修改为 test19 pj@pj-pc:~$ sudo chown -R test19:test19 /home/test19 pj@pj-pc:~$ ls -l /home drwxr-xr-x  2 test19  test19  4096 7月  18 15:08 test19 

Tip:chown 用于修改权限,后面会讲到。

现在路径是/home/demo,切换 test19 登录后,自动进入对应的家目录:

pj@pj-pc:~$ pwd /home/demo pj@pj-pc:~$ su - test19 输入密码 $ pwd /home/test19 $ 

Tip: 这里如果使用 su test19,则不会进入该用户的家目录。su -su 是两个命令,su -会同时加载该用户的所有环境变量和配置文件。

用户登录的角度认识bash

所谓登录,到底是登录什么?

有同学说是 linux。对也不对!linux前文我们说是 linux 内核,是深不见底的东西。是有什么东西在协助我们?

是 Shell。表示 linux 内核外的一层壳。而 bash 是最知名的一种 shell。

现在 test19 最后一个字段是 /bin/bash,表示该用户登录后,给他 bash。

test19@pj-pc:~$ tail -3 /etc/passwd test19:x:1007:1007::/home/test19:/bin/bash 
// 当前所使用的 shell 的路径 test19@pj-pc:~$ echo $SHELL /bin/bash  // 输出当前 shell 的名称 test19@pj-pc:~$ echo $0 -bash 

Tip/bin 目录下还有许多常用命令,比如vi,所有用户都可以使用。

如果你将 test19 的 /bin/bash 改成 /bin/vi,登录后就不会给bash,而是vi,感兴趣的同学可以试一下。

我们还看到:

ntp:x:124:132::/nonexistent:/usr/sbin/nologin 

nologin 就是禁止登录,我们将其分配给 test19 看看会怎么样?

// sbin 就是 usr/sbin(sbin -> usr/sbin) test19:x:1007:1007::/home/test19:/sbin/nologin 

用户无法登录

pj@pj-pc:~$ su - test19 输入密码 // 这个帐号当前不可用 This account is currently not available. 

Tip:不建议将 root 设置成这种登录方式,对于初学者比较麻烦。

使用 sudo 切换用户

前面我们用 su 切换用户,相等于注销当前用户,换一个用户来使用。

在日常中,较少使用 su,更多是使用 sudo

普通用户直接查看 /root 不允许:

$ ls /root ls: 无法打开目录'/root': 权限不够 

临时使用 root 的用户运行 ls /root

test19@pj-pc:~$ sudo -u root ls /root 模板  桌面 test19@pj-pc:~$ whoami test19 

Tip:直接使用 sudo 可能提示不在 sudoers 文件中,需要通过 visudo 命令修改 sudo 配置文件

test19@pj-pc:~$ sudo ls /root 输入密码 test19 不在 sudoers 文件中。此事将被报告。 
pj@pj-pc:~$ sudo visudo  root ALL=(ALL:ALL) ALL // 增加一行 // <用户名> <主机名>=(<身份>:<终端>) <命令> test19 ALL=(ALL:ALL) ALL 

指定了 test19 用户在任何主机、以任何用户身份、在任何终端上都可以使用 sudo 命令

密码管理

前面我们通过编辑配置文件 /etc/passwd 创建用户,我们也知道用 passwd 给用户创建密码。

密码没有存在 /etc/passwd,而是在 /etc/shadow 中,加密之后保存的。例如搜索用户 test19 的密码:

pj@pj-pc:~$ sudo cat /etc/shadow |grep 'test19' test19:$6$7ZkiOkEth7bdStHU$GWt/YVaD/KlJ5b21afWhqXPECRDj5tDmNBx.TDKW                                                                                                                                     6M2jd1jvtMlYFcrGVoWsmSkJ5hnIaEQyI8nLs4PDNJOm4.:19556:::::: 

虽然密码并不是使用 md5sum 加密,但我们可以使用其模拟一下:

// 输入不变,输出也不变 pj@pj-pc:~$ echo -n '123456' | md5sum e10adc3949ba59abbe56e057f20f883e  - pj@pj-pc:~$ echo -n '123456' | md5sum e10adc3949ba59abbe56e057f20f883e  - pj@pj-pc:~$ 

本地用户和远程用户

机器就在身边是本地登录,更多的是远程登录。

无论是本地登录还是远程登录,都是 linux 本地账号密码

在一个系统中,如果两个用户都使用 root 身份进行登录,一个是本地登录,另一个是远程登录,那么它们之间可能会互相不知道对方的存在。这种情况下可以被看作是一种多用户管理模式,其中每个用户都以独立的身份登录并运行各自的操作。