Linux学习笔记--鸟哥的Linux私房菜(全)

发生问题怎么处理

  • Linux自己的文件数据:/usr/share/doc
  • The Linux Documentation Project:http://www.tldp.org/
  • linux.vbird.org/Searching.php
  • /var/log 日志文件
  • 酷学园讨论区phorum.study-area.org
  • 鸟哥的私房菜讨论区phorum.vbird.org

Linux发行版分为两大家族

一类是RPM方式安装软件的系统,包括Red Hat、Fedora等,还有一类是dpkg方式安装软件的系统。


各硬件设备在Linux中的文件名

在Linux系统中,每个设备都被当成一个文件来对待。
几乎所有的硬件设备文件都被放在 /dev这个目录

设备 设备在Linux中的文件名
SCSI、SATA、USB磁盘驱动器 /dev/sd[a-p]
U盘 /dev/sd[a-p]
Virtio接口 /dev/vd[a-p](用于虚拟机)
打印机 /dev/lp[0-2] (25针打印机)
/dev/usb/lp[0-15] (USB接口)
鼠标 /dev/input/mouse[0-15](通用)
/dev/psaux(PS/2接口)
/dev/mouse(当前鼠标)
CD-ROM、DVD-ROM /dev/scd[0-1] (通用)
/dev/sr[0-1] (通用,CentOS较常见)
/dev/cdrom(当前CD-ROM)
磁带机 /dev/ht0(IDE接口)
/dev/st0(SATA/SCSI接口)
/dev/tape(当前磁带)
IDE磁盘驱动器 /dev/hd[a-d] (旧时系统才有)
/dev/sd[a-p] (现在)

更多Linux内核支持的硬件设备与文件名,可见kernel.org/doc/Documentation/devices.txt


磁盘分区

SATA、USB、SAS等磁盘接口都是使用SCSI模块来驱动的,且根据Linux内核检测到磁盘的顺序来命名。
MBR与GPT磁盘分区表(partition table)
SATA接口的硬盘文件名为:/dev/sd[a-d]

MBR

启动引导程序记录区与分区表放置在磁盘的第一个扇区,这个扇区通常是512字节的大小,里面有

  • 主引导记录(MBR):可以安装启动引导程序的地方,有446字节。
  • 分区表(partition table):记录整个硬盘的分区的状态,有64字节
    由于分区表只有64字节,因此最多仅能有4组记录区,每组记录区记录了该区段的启动与结束的柱面号码。并不是只能划分4个分区,利用扩展分区可以达到4个以上分区。分区分为主分区和扩展分区,扩展分区继续被切出去的分区,称为逻辑分区。sda[1-4]用于主分区,大于4为逻辑分区号。

GPT磁盘分区表

34个LBA逻辑区块地址,LBA0与MBR兼容模块,LBA1为GPT表头记录,LBA2-33为实际记录分区信息处,GPT分区表表示对于单一分区来说,它的最大容量限制在8ZB,Linux通过udev方式以不限制分区数量,GPT分区已经没有所谓的主分区、扩展分区、逻辑分区的概念,每组记录都可以独立存在,都可视为主分区,每一个分区都可以拿来格式化。
要使用GPT,得要运行类似gdisk或parted命令才行,启动引导程序grub第一版并不支持GPT,得要grub2才支持,


BIOS搭配MBR/GPT的启动流程

  1. BIOS:启动主动执行的固件,会认识第一个可启动的设备;
  2. MBR:第一个可启动的第一个扇区内的主引导记录块,内含启动引导代码;
  3. 启动引导程序boot loader:一个可读取内核文件来执行的软件;
  4. 内核文件:开始启动操作系统。

如果你的分区表为GPT格式的话,那么BIOS也能从LBA0的MBR兼容区块读取第一阶段的启动引导程序代码,如果你的启动引导程序能够支持GPT的话,那么使用BIOS同样可以读取到正确的操作系统内核。
由于LBA0仅提供第一阶段的启动引导程序代码,因此如果你使用类似grub的启动引导程序的话,那么就得要额外划分出一个BIOS boot的分区,这个分区才能够防止其他开机过程所需的软件,在CentOS中,这个分区通常占用2MB。

Boot Loader的主要任务:

  • 提供选项:用户可以选择不同的启动选项,这也是多重引导的重要功能;
  • 加载内核文件:直接指向可使用的程序区段来启动操作系统;
  • 转交其他启动引导程序:将启动管理功能转交给其他启动引导程序负责。

如果要安装多重引导,最好先安装Windows再安装Linux,Windows在安装的过程中,它的安装程序会主动地覆盖掉MBR以及自己所在分区的启动扇区。

UEFI BIOS搭配GPT启动流程

UEFI统一可扩展固件接口,想要取代BIOS这个固件接口,UEFI加入了安全启动secure boot功能,这个功能代表着即将启动的操作系统必须要被UEFI所验证,否则就无法顺利启动。某些时刻,可能要将UEFI的secure boot功能关闭才能顺利进入Linux。另外,与BIOS模式相比,虽然UEFI可以直接获取GPT的分区表,不过最好依旧拥有BIOS boot的分区支持,同时,为了与Windows兼容,并且提供其他第三方厂商所使用的UEFI应用程序存储的空间,你必须要格式化一个FAT格式的文件系统分区,大约提供512MB到1GB左右的大小,以让其他UEFI执行较为方便。


Linux安装模式下,磁盘分区的选择

目录树结构:根目录/

如何结合目录树的架构与磁盘内的数据,需要牵涉挂载mount问题。
文件系统与目录树的关系(挂载)
所谓挂载就是利用一个目录当成进入点,将磁盘分区的数据放置在该目录下;也就是说进入该目录就可以读取该分区的意思。分区1挂载根目录/,分区2挂载home目录。
Linux是将光驱的数据放置到/media/cdrom里,如果光驱并非挂载到/media/cdrom,可以挂载到/mnt
/usr是Linux的可执行程序及相关的文件存放的目录
初次接触Linux:只要划分“/”,和“swap”即可
建议分区的方法:预留一个备用的剩余磁盘容量

SAMBA(加入Winodows网络邻居)
SAMBA的性能不错,也没有客户端数量的限制,相当适合于一般学校环境的文件服务器(file server)的角色。这种服务器由于分享的数据量较大,系统的网卡与硬盘的大小及速度就比较重要,如果你还针对不同的用户提供文件服务器功能,那么/home这个目录可以考虑独立出来,并且加大容量。
CentOs使用的是Apache这个软件来完成WWW网站的功能。在WWW服务器上面,如果你还有提供数据库系统的话,那么CPU的等级就不能太低,最重要的是内存。

在默认CentOS环境中,下面的目录是比较符合容量大且(或)读写频繁的特征的目录:

  • /boot
  • /
  • /home
  • /var 邮件主机
  • swap
    提供了鸟哥的服务器案例

安装CnetOS 7

dd if=centos7.iso of=/dev/sdc 将image刻录进U盘
vmlinuz initrd=initrd.img inst.stage2=hd:LABEL=CentOS\x207\x20x86_64 rd.live.check quiet inst.gpt 使用GPT分区表
因为我们需要输入中文,所以常常打字会在中/英文之间切换。过去我们经常使用的键盘布局是[Ctrl+空格]或[Ctrl+Shift],不过这一版的窗口界面,默认没有提供切换的按钮,需要手动设置。

biosboot由于是bios使用,因此没有挂载点,同时文件系统的部分也是会变成Bios Boot的关键字。
LVM:这是一种可以弹性增加或缩小文件系统容量的分区,我们会在后面的章节持续介绍LVM。
LVM精简配置(Thin Provisioning):LVM的高级版。与传统LVM直接分配固定的容量不同,这可以让你在使用多少容量才分配磁盘多少容量给你,所以如果LVM设备内的数据量较少,那么你的磁盘其实还可以作更多的数据存储,而不会被平白无故的占用。

  • ext2/ext3/ext4:这是Linux早期使用的文件系统类型。由于ext3/ext4文件系统多了日志功能,对于系统的恢复比较快速,不过由于磁盘容量越来越大,ext系列似乎有点挡不住了,所以除非你有特殊的设置需求,否则尽来比较少用ext4.
  • swap:就是磁盘模拟为内存的交换分区,由于交换分区并不会使用到目录树的挂载,所以用交换分区就不需要指定挂载点。
  • BIOS BOOT:就是GPT分区表可能用到的东西,若你使用MBR,那就不需要这个东西。
  • xfs:这个是目前CentOS7默认的文件系统,最早是为大型服务器所开发。它对于大容量的磁盘管理非常好,而且格式化快。
  • vfat:同时被Linux和Windows所支持的文件系统类型。如果你的主机硬盘内同时存在Windows和Linux系统,为了数据的交换,确实可以创建一个vfat的文件系统。

交换分区需要内存的2倍容量较佳。

内核管理与网络设置

KDUMP这个选项主要是处理当Linux系统因为内核问题导致的宕机事件时会将该宕机事件的内存中的数据保存的一项功能。不过这个功能适用于内核开发者除错用,也可以关闭。

/root/anaconda-ks.cfg这个文件包含了安装配置
笔记本安装时Tab nofb apm=oof acpi=off pci=noacpi
APM=advanced power management 是早期的电源管理模块,
ACPI=advanced configuration and power interface则是最近的电源管理模块
这两者都是硬件本身就支持的,但是笔记本电脑可能不使用这些机制,因此,当安装时启动这些机制将会造成一些错误,导致无法顺利安装,
nofb则是取消显卡上面的缓存检测。因为笔记本电脑的显卡常常是集成型的,Linux安装程序本身可能就无法检测到该显卡。


首次登陆与在线求助

Linux使用异步的磁盘/内存数据传输模式,同时又是个多人多任务的环境,所以你不能随便地不正常关机,关机有一定的顺序,错误的关机方法可能会造成磁盘数据的损坏。

上方工具栏:位置(就是文件资源管理器)
如果你想要知道系统上面还有哪些文件,以及你目前这个账号的基本子目录,那就得要打开文件资源管理器(file manager)。
文件名前面开头是小数点. 代表隐藏文件,隐藏文件并不是什么特殊权限,单纯是因为文件名命名的处理方式来搞定。

gsettings set org.gnome.desktop.interface enable-animations false
这个操作会将GNOME默认的界面切换的动画功能关闭,在虚拟机的环境下,有助于提升界面的切换速度

yum install ibus-libpinyin
中文输入法。选择语言为Chinese

X Winodw与命令行模式的切换

  • ctrl+alt+F2~F6:命令行模式登录tty2-tty6
  • ctrl+alt+F1:图形用户界面模式

若在tty3中startx,需要保证

  • 并没有其他的X Window被启用
  • 你必须要已经安装了 X Window,并且X Server能够顺利启动;
  • 你最好要有窗口管理器,例如GNOME、KDE或是普通的TWM等。

如果默认要使用图形界面,只要在后续管理服务的程序中,将graphical.target这个目标服务设置为默认,就能够默认使用图形界面。
新的管理方法使用的是systemd的模式,这个模式将很多的服务进行依赖性管理。

命令行模式下命令的执行

command [-options] parameter1 parameter2 ... 
 命令     选项        参数1     参数2

-h选项缩略 --help选项全名

\ 符号可以转义换行若代码较长

locale 查看支持语系
LANG=en_US.utf8
export LC_ALL=en_US.utf8
LANG只与输出信息有关,若需要更改其他不同的信息,要同步更新LC_ALL

只限于此次登录。

  • 显示日期与时间的命令:date

  • 显示日历的命令:cal

  • 简单好用的计算器:bc

      date +%Y/%m/%d 2020/1/1
      date +%H:%M		15:30
      cal [month] [year]
    

上例表示除了减号外,还可以用加号。

	bc包含了加减乘除指数求余,如果要输出小数点下位数,那么就必须要执行scale=number命令

–help用于协助查找曾经使用过的命令所具备的选项和参数
如果你要使用的是从来没有使用过的命令,或是你要查询的根本就不是命令,而是文件的格式时,那就要通过man page命令了。例如 man date

代号 代表内容
1 用户在shell环境中可以操作的命令或可执行文件
2 系统内核可调用的函数与工具等
3 一些常用的函数(function)与函数库(library),大部分为C的函数库(libc)
4 设备文件的说明,通常在/dev下的文件
5 配置文件或是某些文件的格式
6 游戏
7 惯例或协议等,例如Linux文件系统、网络协议、ASCII代码等的说明
8 系统管理员可用的管理命令
9 跟内核有关的文件

在man page 界面输入/word 例如/date表示向下搜索,?word向上搜索,在搜索结果里按n代表向下查询,按N代表向上查询。
系统中查出跟man这个命令有关的说明文件man -f man,执行man 1 man

关键词查询
man -k man
whatis [命令或文件] 相当于 man -f [命令或是文件]
apropos [命令或文件] 相对于 man -k [命令或是文件]
whatis需要在root下更新数据库 mandb
info page

info page则是将文件数据拆成一个一个的段落,每个段落用自己的页面来编写,并且在各个页面中还有类似网页的超链接来跳到各不同的页面中,每个独立的页面也被称为一个节点(node)。所以,你可以将info page想成是命令行模式的网页显示数据。
不过你要查询的目标数据的说明文件必须要以info的格式来写成才能够使用info的特殊功能(例如超链接),而这个支持info命令的文件默认是放置在/usr/share/info/这个目录当中。

file:代表这个info page的数据是来自info.info文件所提供;
Node:代表目前的这个页面是属于Top节点,意思是info.info内含有很多信息,而Top仅是info.info文件内的一个节点内容而已;
Next:下一个节点名称,按N下一个
Up:回到上一层的节点总揽画面,你也可以按下U回到上一层;
Prev:前一个节点,但由于Top是info.info的第一个节点,所以上面没有前一个节点的信息;
按下h可以查询命令提醒
可以使用上下左右按键来将光标移动到该文件或[*]上面,按下Enter,就可以前往该小节。另外,也可以按下TAb键,就可以快速的将光标在上面画面中的节点间移动。

如果以info page格式写成的说明文件,虽然也能够使用info来显示,不过其结果就会跟man相同。

其他有用的文件(documents)

毕竟不是每个东西都需要做成联机帮助文件的,还有相当多的说明需要额外的文件,此时,这个所谓的HowTo就很重要。/usr/share/doc目录内,说明文件。
如果你想要架设一些其他的服务,或想要利用一整组软件来完成某项功能时,请赶快到/usr/share/doc下面查一查有没有该服务的说明文件。

超简单的文本编辑器:nano

nano的使用其实很简单,你可以直接加上文件名就能够打开一个旧文件或新文件。
^代表的是键盘的Ctrl按键。
Alt+Y:语法校验功能开启或关闭;
Alt+M:可以支持鼠标来移动光标的功能。
有时候,M代表Alt键。

正确的关机方法

在你看不到的屏幕背后其实可能有相当多人同时在你的主机上面工作。若不正常关机,则可能造成文件系统的毁坏。正常情况下,要关机时需要注意以下几件事:

  • 观察系统状态,who指令看谁在线, netstat -a 查看网络联机状态,查看后台执行的程序执行ps -aux

  • 通知在线用户关机的时候,使用shutdown给在线用户一些时间来结束它们的工作。

  • 将数据同步写入硬盘中的命令:sync(将内存数据写入硬盘)

  • 常用的关机命令:shutdown

  • 重启,关机:reboot,halt,poweroff

    shutdown [-krhc] [时间] [警告信息]
    shutdown -h now
    shutdown -h 20:25
    shutdown -h +10
    shutdown -r now 重启
    shutdown -r +30 ‘The system will reboot’
    shutdown -k now ‘This system will reboot’

halt #系统停止,屏幕可能会保留系统已经停止的信息
poweroff #系统关机,所以没有提供额外的电力,屏幕空白
systenctl [命令],reboot、halt、poweroff都是调用的这个命令,suspend是睡眠模式。init 0关机,init 6 重启。


Linux的文件权限与目录配置

用户、用户组概念、其他人

用户组最有用的功能之一,就是当你在团队进行协同工作的时候,如果自己还有私人隐秘的文件,仍然可设置成让自己的团队成员也看不到自己的文件。每个账号都可以由多个用户组的支持。
其他人就是不属于用户组的人。

默认情况下,所有系统上的账号、一般身份用户以及root的相关信息,存储在/etc/passwd这个文件内。至于个人密码则是记录在/etc/shadow这个文件内。所有的组名都记录在/etc/group中。

Linux文件权限的概念

ls -al
drwxr-xr-x.  2    eeqyang eeqyang    6      4月  12 02:54 桌面
[权限]     [链接] [拥有者] [用户组] [文件容量]  [修改日期]   [文件名]

第一个字符代表这个文件是目录、文件或链接文件等:

  • [d]是目录
  • [-]是文件
  • [l]是链接文件
  • [b]是表示设备文件里面的可供存储的周边设备(可按块随机读写的设备);
  • [c]是表示为设备文件里面的串行端口设备,例如键盘和鼠标(一次性读取设备)

接下来的字符中以三个为一组,且均为[rwx]的三个参数的组合。[x]代表可执行。要注意这三个权限的位置不会变化,如果没有权限,则出现[-]号。

  • 第一组为文件拥有者可具备的权限。
  • 第二组为加入此用户组的账号的权限
  • 第三组为非本人且没有加入本用户组的其他账号的权限。

另外,目录与文件的权限意义并不相同,这是因为目录与文件所记录的数据内容不相同所致。

第二栏表示有多少文件名链接到此节点(inode)

每个文件都会将它的权限与属性记录到文件系统的inode中,不过,我们使用的目录树是用文件名来记录的,因此每个文件名就会链接到一个inode,这个属性记录的就是有多少不同的文件名链接到相同的一个inode号码。

第六栏中如果修改日期距离现在较远,只显示年份而已。否则月/日。
如果想要完整的时间格式,ls -l --full-time即可。

如何修改文件属性与权限

  • chgrp:修改文件所属的用户组;(要被修改的组名要在/etc/group中有)

  • chown:修改文件拥有者;(用户必须是已经存在系统中的账号,也就是/etc/passwd这个文件中有记录的用户名称才能修改)

  • chmod:修改文件的权限,SUID、SGID、SBIT等的特性。

      chgrp [-R] group dirname/filename 
      -R:进行递归修改,目录及目录下所有文件修改。
      chown [-R] 账号名称 文件或目录
      chown [-R] 账号名称:用户组名称 文件或目录
      chmode [-R] xyz 文件或目录
    

cp 源文件 目标文件
例如,cp .bashrc .bashrc_test,复制出一个test文件。之后需要修改这个cp文件的权限,它的拥有者和用户组也被cp了。

chmod权限的设置方法有两种,分别可以使用数字或是符号来进行权限的修改。4可读,2可写,1可执行,可组合。

符号类型,先把身份分为u、g、o、a,user,group,others,all。
chmod u=rwx,go=rx .bashrc
chmod u=rwx,g=rx,o=r .bashrc
chmod a+w .bashrc 所有人增加w功能
chmod a-w .bashrc 所有人减去w功能

目录与文件的权限意义

对一般的文件来说,rwx主要是针对文件的内容来设计权限,
对目录来说,rwx则是针对目录内的文件名列表来设计权限。
x才代表能够进入目录!

Linux文件种类与扩展名

  • 常规文件[-]:纯文本文件,二进制文件,数据文件。
  • 目录[d]
  • 链接文件link[l]:类似于windows快捷方式
  • 设备与设备文件(device):与系统周边及存储等相关的文件,通常集中在/dev这个目录下,有可分为:
  • 区块block设备文件:就是一些存储数据,以提供系统随机存取的接口设备,举例来说硬盘和软盘就是。你可以随机地在硬盘的不同区块读写,这种设备就是块设备。你可以自行查一下/dev/sda,会发现第一个属性为[b]。
  • 字符character设备文件:串行端口的接口设备,如键盘鼠标等。这些设备的特色是一次性读取,不能够截断输出。举例来说,你不可能让鼠标跳到另一个画面,而是连续性滑动到另一个地方,第一个属性为[c]。
  • 数据接口文件sockets:被用在网络上的数据交换上,启动一个程序来监听客户端的要求,而客户端就可以通过这个socket来进行数据的沟通了,第一个属性为[s]。最常在/run和/tmp中。
  • 数据传输文件(FIFO,pipe):FIFO是一种特殊的文件类型,它主要的目的是解决多个程序同时读写一个文件所造成的错误问题,FIFO是先进先出的缩写,即管道,第一个属性为[p]。

扩展名:

  • .sh:脚本或批量处理文件scripts,因为批量处理文件使用shell写成,所以扩展名就编成.sh;
  • *Z、.tar,.tar.gz,.zip,.tgz:经过打包的压缩文件
  • .html,.php:网页文件,html的文件可使用网页浏览器来直接开启,php文件,则可以通过客户端的浏览器来服务器浏览,以得到运算后的网页结果。

文件名长度限制:
在Linux下,使用传统的ext2、ext3、ext4文件系统以及近来被CentOS7当作默认文件系统的xfs而言,针对文件的文件名长度限制为:单一文件或目录的最大容许文件名为255字节,以一个ASCII英文占用一个字节来说,则大约可达255个字符长度,若是以每个汉字占用2字节,最多128个汉字。

Linux文件名的限制:最好避免* ? > < ; & ! [ ] | \ ' " 以及左小点 () {} . - +

Linux 目录配置

Linux目录配置的依据——FHS

可分享shareable 不可分享unshareable
不变static /usr(软件存放处) /etc(配置文件)
/opt(第三方辅助软件) /boot(启动与内核文件)
可变动variable /var/mail(用户邮箱) /var/run(程序相关)
/var/spool/news(新闻组) /var/lock(程序相关)
  • 可分享:可以分享给其他系统挂载使用的目录,所以包括执行文件与用户的邮件等数据,是能够分享给网络上其他主机挂载用的目录。
  • 不可分享:自己机器上面运行的设备文件或是程序相关的socket文件等,由于仅与自身机器有关,所以当然就不适合分享给其他主机;
  • 不变:有些数据是不会经常变动的,跟随着发行版而不变动。例如函数库,文件说明,系统管理员所管理的主机服务配置文件等;
  • 可变动:经常修改的数据,例如日志文件,一般用户可自行接受的新闻组等。

事实上,FHS针对目录树架构仅定义了三层目录下面应该放置什么数据而已,分别是下面三个目录的定义:

  • /root:与启动系统有关;
  • /usr:与软件安装/执行有关;
  • /var:与系统的运行过程有关;

目录的各种介绍在鸟哥的书P166-169。

目录树

特性:

  • 目录树的起始点为根目录
  • 每一个目录不止能使用本地分区的文件系统,也可以使用网络上的文件系统。举例来说,可以利用Network File System(NFS)服务器挂载某特定目录等;
  • 每一个文件在此目录树中的文件名(包含完整路径)都是独一无二的。

绝对路径与相对路径

因为根据文件名写法的不同,也可将所谓的路径path定义为绝对路径absolute与相对路径relative。

  • 绝对路径:由根目录开始写起的文件名或目录名,例如/home/eeqyang/.bashrc
  • 相对路径:相对于目前路径的写法。例如./home

CentOS的观察

除了FHS之外,还有个Linux Standard Base(LSB)的标准是可以依循的。

uname -r #查看内核版本
uname -m #查看操作系统的架构版本
yum install redhat-lsb #安装
lsb_release -a #查看是否符合lsb

目录与路径

路径(PATH),如果是在写程序(shell脚本)来管理系统的条件下,务必使用绝对路径。

. 		 代表此层目录
..		 代表上一层目录
-	     代表前一个工作目录
~		 代表目前使用者身份所在的家目录
~account 代表account这个使用者的家目录

cd:切换目录
pwd:显示当前目录  -P显示真正路径,而非使用链接link路径。
mkdir:建立一个新目录 [-mp]其中-m:设置文件的权限。直接设置,不使用默认权限(umask)。-p:帮助你直接将所需的目录(包含上层目录)递归创建。没有-m直接使用默认属性。-p的时候如果里面有目录已存在,系统也不会显示错误信息。
rmdir:删除一个空目录。[-p]:连同上层“空的”目录也一起删除。
rm -r :若目录里有文件,递归删除

关于执行文件路径的变量:$PATH

系统会依照PATH的设置去每个PATH定义的目录下查找文件名为ls的可执行文件,如果在PATH定义的目录中含有多个文件名为ls的可执行文件,那么先查找到的同名命令会先被执行。

echo $PATH 查看PATH目录,不同目录中间用:隔开
PATH="${PATH}:/ROOT"

文件与目录管理

ls [-adl] [文件名或目录名称]
ls [--color={never,auto,always}] [文件名或目录名称]
ls [--full-time] [文件名或目录名称]
-a:全部的文件,连同隐藏文件(开头为.的文件)一起列出来;
-d:仅列出目录本身,而不是列出目录内的文件数据;
-l:详细信息显示,半酣文件的属性与权限等数据;
--full-time:以完成时间模式输出;
--time={atime,ctime}:输出access时间或改变权限属性时间(ctime),而非内容修改时间;
ls -l等价于ll
复制、删除与移动:cp、rm、mv
  • cp

      cp [-aipr] 源文件 目标文件
      cp [options] source1 source2 ... directory
      -a:相当于-dr --preserve=all的意思,至于dr请参考下列说明
      -l:硬链接
      -u:目标文件与源文件有差异才复制
      -d:若源文件为链接文件的属性,则复制链接文件属性而非文件本身
      -i:若目标文件已经存在,在覆盖时会先询问操作的进行;
      -p:连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性(备份常用);
      -r:递归复制,用于目录的复制操作(常用);
      -s:复制成为符号链接文件,即快捷方式文件;
      --preserve=all:除了-p的权限相关参数外,还加入了SELinux的属性,links、xattr等也复制;
      最后需要注意的是,如果源文件有两个以上,则最后一个目标文件一定要是目录才行。
      直接复制不加上-a则有可能权限和时间不同!
    

在默认的条件下,cp的源文件与目标文件的权限是不同的,目标文件的拥有者通常会是命令操作者本身。
对于特殊的一些文件,需要加上-a或-p才能实现复制。

  • 是否需要完整的保留源文件的信息?
  • 源文件是否为符号链接文件(symbolic link file)?
  • 源文件是否为特殊的文件,例如FIFO、socket等?
  • 源文件是否为目录?

  • rm

    rm [-fir] 文件或目录
    -f:就是force的意思,忽略不存在的文件,不会出现警告信息。
    -i:交互模式,在删除前会询问使用者是否操作;
    -r:递归删除,最常用在目录的删除,这是非常危险的选项。
    \rm 可以忽略alias选项
    删除带有-的文件需要输入相对地址


  • mv

    mv [-fiu] source destination
    mv [options] source1 source2 source3… directory
    -f:force强制的意思,如果目标文件已经存在,不会询问而直接覆盖。
    -i:若目标文件已经存在时,就会询问是否覆盖。
    -u:若目标文件已经存在,且source比较新,才会更新update。
    mv test test1即将目录更名为test1


获取路径的文件名与目录名称
basename 绝对路径=获取文件名
dirname 绝对路径=获得路径目录名

文件内容查看

cat:由第一行开始显示文件内容。
tac:从最后一行开始显示,可以看出tac是cat的倒着写
nl:显示的时候,同时输出行号。
more:一页一页地显示文件内容。
less与more类似,但是比more更好的是,它可以往前翻页。
head只看前几行
tail只看后面几行。
od以二进制的方式读取文件内容。

直接查看文件内容

cat [-AbEnTv]
-n:打印出行号,连同空白行也会有行号,与-b选项不同

nl [-bnw] 文件
-b:指定行号指定的方式,主要有两种:
    -b a:表示不论是否为空行,也同样列出行号。
	-b t:有空行,空的那一行不要列出行号。
-n:列出行号表示的方法,主要有三种:
    -n ln:行号在屏幕的最左方显示;
	-n rn:行号在自己栏位的最右方显示,且不加0;
	-n rz:行号在自己栏位的最右方显示,且加0;
-w:行号栏位的占用的字符数。在-n rz中一起使用。

可翻页查看

more一页一页翻动
less:比more多一个向上翻页

数据截取

head [-n +-number] 文件:取出文件前面n行,默认不填表示10行,-号代表去除多少行
tail [-n number] 文件
-f:表示持续刷新显示后面所接文件中的内容,要等到按下ctrl+c结束
head -n 20 test | tail -n 10这就得到了第11行到第20行之间的内容了。
|代表管道,前面的命令所输出的结果,通过管道交给后续的命令继续使用。

非纯文本文件:od

由于执行文件是二进制文件,需要od命令读取。
od [-t TYPE] 文件
-t:后面可以接各种TYPE的输出,例如:
a:利用默认的字符输出;
c:使用ASCII字符输出
d[size]:利用十进制输出,每个整数占用size Bytes;
f[size]:利用浮点数值输出。
o[size]:利用八进制输出。
x[size]:利用十六进制输出。
echo password | od -t oCc

修改文件时间或创建新文件:touch

时间参数:

  • 修改时间modification time ,mtime:当该文件的内容数据变更时,就会更新这个时间,内容数据指的是文件的内容,而不是文件的属性或权限。

  • 状态时间status time,ctime:当该文件的状态改变时,就会更新这个时间,举例来说,像是权限与属性被更改了,都会更新这个时间。

  • 读取时间access time,atime:当该文件的内容被读取时,就会更新这个读取时间access,举例来说,我们使用cat去读取某文件,就会更新该文件的atime。

    touch [-acdmt] 文件
    -a:仅自定义access time;
    -c:仅修改文件的时间,若该文件不存在则不建立新文件;
    -d:后面可以接欲自定义的日期而不用目前的日期,也可以使用–date=“日期或时间”
    -m:仅修改mtime;
    -t:后面可以接欲自定义的时间而不用目前的时间,格式为[YYYYMMDDhhmm];
    touch 修改的是atime与mtime
    touch最常用为:创建一个空文件;将某个文件日期自定义为目前(mtime与atime)。

文件与目录的默认权限与隐藏权限

文件默认权限:umask

umask就是指定目前用户在建立文件或目录时候的权限默认值。
umask:0022,第一组是特殊权限用的,后三组才是,代表该默认值需要减掉的权限
文件默认为666,目录为777,再减去umask的值。
umask xxx 设置默认权限值
注意不是数值相减而是对应位相减,不补

文件的隐藏属性

强调chattr命令只能再ext234的Linxu传统文件系统上面完整生效。xfs仅支持部分参数。

  • chattr配置文件隐藏属性
    chattr [±=][ASacdistu] 文件或目录名称
    +:增加一个特殊参数,其他原本存在参数则不动。
    -:删除一个特殊参数,其他原本存在参数则不动。
    =:直接设置特殊参数
    a:当设置a之后,这个文件将只能增加数据,而不能删除也不能修改数据,只有root才能设置这个属性。
    i:不能被删除、改名、设置链接也无法写入或新增数据。对于系统安全性有相当大的助益,只有root才能设置此属性。
    其他见鸟哥书P197页

  • lsattr
    lsattr [-adR] 文件或目录
    -a:将隐藏文件的属性也显示出来;
    -d:如果接的是目录,仅列出目录本身的属性而非目录内的文件名;
    -R:连同子目录的数据也一并列出来;

文件特殊权限:SUID、SGID、SBIT

SUID是s位于拥有者的x位

  • SUID权限只对二进制程序有效;
  • 需要x权限,显示为s
  • 本权限仅再执行该程序的过程中有效run-time;
  • 执行者将具有该程序拥有者owner的权限。

SGID是s位于用户组的x位

  • SGID对二进制程序有用;
  • 程序执行者对于该程序来说,具有x的权限
  • 执行者再执行的过程中将会获得该程序用户组的支持。

除了二进制程序外,SGID也能用于目录:

  • 用户若对此目录具有rx权限,该用户能够进入此目录;
  • 用户在此目录下的有效用户组将会变成该目录的用户组;
  • 用途:若用户在此目录下具有w的权限,则用户所建立的新文件,该新文件的用户组与此目录的用户组相同。

Sticky Bit(SBIT)
只针对目录有效显示位t

  • 当用户对于此目录具有wx权限;
  • 当用户在该目录下建立文件或目录时,仅有自己与root才有权力删除该文件。

SUID/SGID/SBIT权限设置

只需要在三个数字前面加上一个数字即可。

  • 4为SUID
  • 2为SGID
  • 1为SBIT

大写的S和T代表空,即x为置位。

观察文件类型:file

想要知道某个文件的基本信息,例如是属于ASCII或是数据文件或是二进制文件,且其中有没有使用到动态链接库(share library)等信息,就可以利用file这个命令来查看。

命令与文件的查找

脚本文件的查找
  • which(查找执行文件)

      which [-a] command
      -a:将所有由PATH目录中可以找到的命令均列出,而不止第一个被找到的命令名称。
      不能找出bash内置的命令只能找PATH路径下的,例如history找不出。
    
文件的查找

wheris只找系统中某些特定目录下面的文件而已,locate则是利用数据库来查找文件名。

whereis [-bmsu] 文件或目录名
locate [-ir] keyword (部分名称),需要先更新数据库updatedb,这是在数据库/var/lib/mlocate/里查找
find [PATH] [option] [action] 
find / -mtime 0 (24小时内更新过的文件)
find / -mtime 3 (3天前的24中更新过的文件)
find /etc -newer /etc/passwd (-newer用在辨别两个文件之间的新旧关系是很有用的)
+4 4天之前 -4 4天内 4 第4天
P203-P205 find用法。find用来查找特殊属性的。

文件与文件系统的压缩

*.Z		compress程序压缩的文件
*.zip	zip程序压缩的文件
*.gz	gzip程序压缩的文件
*.bz2	bzip2程序压缩的文件
*.xz	xz程序压缩的文件
*.tar	tar打包的文件
*.tar.gz tar打包,gz压缩的文件

gzip [-cdtv#] 文件名  -d是解压缩
	可以建立压缩文件*.gz
zcat/zmore/zless 文件名.gz
先解压再查看文件数据
zgrep 找数据 egrep不需要解压

bzip2 [-cdkzv#] 文件名
bzcat 文件名.bz2

xz [-dtlkc#] 文件名
xcat 文件名.xz

压缩:tar [-z|-j|-J] [cv] -f filename.tar.[gz|bz2|xz] 要被压缩的文件或目录名;
查询:tar [-z|-j|-J] [tv] -f filename.tar.[gz|bz2|xz]
解压缩:tar [-z|-j|-J] [xv] -f filename.tar.[gz|bz2|xz] (-C 目标目录)
解压缩压缩包中的单个文件:
1.查找:tar [-z|-j|-J] [xv] -f filename.tar.[gz|bz2|xz] | grep '名称'
2.压缩:tar [-z|-j|-J] [xv] -f filename.tar.[gz|bz2|xz] etc/shadow
--exclude=file 这个exclude就是不包含的意思
--newer-mtime="2015/06/17" 需打包的文件或目录   打包新的文件

tar打包的文件没有进行压缩被称为tarfile,tar打包且压缩的文件称为tarball。

tar -cvf - /etc | tar -xvf - 一边打包一边解压到当前目录

解压缩后的SELinux问题
备份恢复的情况,SELinux的权限问题可能会让你的系统无法读写某些配置内容,导致影响系统的正常使用。P271


8.4 XFS文件系统的备份与还原

xfsdump与xfsrestore对整个文件系统来进行备份和还原。

xfsdump

xfsdump具有完整备份和增量备份,至于各个level的记录相关信息则放置于/var/lib/xfsdump/inventory中。

  • xfsdump不支持没有挂载的文件系统备份,所以只能备份已挂载的文件系统;

  • xfsdump必须使用root权限;

  • xfsdump只能备份xfs文件系统;

  • xfsdump备份下来的数据只能让xfsrestore解析;

  • xfsdump是通过文件系统UUID来辨别各备份文件,因此不能备份两个具有相同UUID的文件系统。

      xfsdump [-L S_label] [-M M_label] [-l #] [-f 备份文件] 待备份数据
      xfsdump -I 查看有没有任何文件系统备份过
      xfsdump默认仅支持文件系统的备份,并不支持特定目录的备份,所以你不能用xfsdump去备份/etc,因为/etc从来就不是一个独立的文件系统。
    

例子:1.先确定/boot是独立的文件系统
df -h /root #挂载/boot的是/dev/vda设备
2.将完整备份的文件名记录成为/srv/boot.dump
xfsdump -l 0 -L boot_all -M boot_all -f /srv/boot.dump /boot

xfs文件系统还原xfsrestore

xfsrestore -I    # 用来查看备份文件
xfsrestore [-f 备份文件] [-L S_label] [-s] 待恢复目录 #单一文件全系统恢复。
xfsrestore [-f 备份文件] -r 待恢复目录    	#通过增量备份文件来恢复系统
xfsrestore [-f 备份文件] -i 待恢复目录 		#进入交互模式。(不知道文件名的时候用)

例子:1.直接将数据覆盖回去即可。
xfsrestore -f /srv/boot.dump -L boot_all /boot
2.将备份数据再/tmp/boot下面解开。

8.6 其他常见的压缩与备份工具

dd if="input_file" of="ouput_file" bs="block_size" count="number"
bs:设置的一个block的大小,若未指定则默认是512Bytes(一个扇区的大小);
count:多少个bs的意思;

例子:将/dev/vda2完整地复制到另一个硬盘分区上
fdisk /dev/sda 1.进行分区的操作
partprobe
2.不需要格式化,直接进行sector表面地复制。
dd if=/dev/vda2 of=/dev/sda1
xfs_repair -L /dev/sda1 #一定要先清楚一堆log才行
uuidgen #下面两行在给予一个新的UUID
xfs_admin -U 某个UUid /dev/sda1 #因为xfs文件系统主要使用UUID来识别系统,但我们使用dd复制,连UUID也都复制成了相同的了。
mount /dev/sda1 /mnt
df -h /boot /mnt
xfs_growfs /mnt
umount /mnt

cpio可以备份任何东西,包括设备文件,不过cpio不会主动找文件来备份。需要配合find等查找命令。
find /boot | cpio -ovcB > [file|device] #备份
cpio -ivcdu < [file|device] #还原
cpio -ivct < [file|device] #查看
都需要进入到需要覆盖恢复备份的目录,不要使用绝对地址即/不能出现在最开始。

第9章 vim程序编辑器

vi

vi共有3种模式,一般命令模式、编辑模式与命令行模式。

  • 一般命令模式:可以使用上下左右按键移动光标,也可删除字符或删除整行,也可以复制、粘贴。
  • 编辑模式:一般命令模式不能编辑内容,需要按下i进入编辑模式,如果要回到一般命令模式按esc。
  • 命令行模式:在一般模式下输入[?]三个中的任何一个按键,提供查找数据,读取保存批量替换字符、退出vi、显示行号等操作。
简易执行范例

vi可以直接创建一个文件,vi filename。

替换  :n1,n2s/word1/word2/g
	 :1,$s/word1/word2/g(c)(确认)
删除: x向后删除一个字符,X向前删除一个字符,nx向后连续删n个字符
(n)dd 删除(剪切)光标所在的那一行
nyy复制光标所在的那n行
nG:移动到第n行
u 恢复前一个操作
ctrl+r 重做上一个动作
. 小数点代表重复前一个操作
r与R:r只会替换光标所在的那一个字符一次;R会一直替换光标所在的文件,直到按下esc为止。
p与P:将复制的在下一行或上一行粘贴出来。
J:将光标所在行与下一行的数据结合成同一行。
vim环境的修改:
:set nu   显示行号,设置之后,会在每一行的前缀显示该行的行号
:set nonu 与set nu相反,为取消行号

vim的缓存、恢复与打开时的警告信息

打开编辑后建立一个名为 .filename.swp的文件
宕机后可以先R再保存再打开一次按D再退出,swp文件需要手动删除。
问题一:多人使用只能按O
问题二:宕机,按R保存后再自行删除swp,或E不调用swp

vim的额外功能

可视区块visual block
以列为操作对象
v:字符选择,会将光标经过的地方反白
V:行选择,会将光标经过的行反白
ctrl+v:可视区块,可以用矩形的方式选择数据
y:复制选择区域
d:删除选择区域
p:将复制的粘贴再光标处。

多文件编辑

:r filename 读入某个文件的内容
:n 编辑上一个文件
:N 编辑下一个文件
:files 列出目前这个vim开启的所有文件

多窗口功能

:sp{filename}划分窗口,文件名可以为空,可以重复添加窗口
ctrl+w+↑,ctrl+w+↓,则在窗口间切换

vim的关键词补全功能

ctrl+x再ctrl+n	通过目前正在编辑的这个文件的内容文件作为关键词,予以补齐
ctrl+x再ctrl+f	以当前目录内的文件名作为关键词,予以补齐
ctrl+x再ctrl+o 	以扩展名作为语法补充,以vim内置的关键词,予以补齐

vim环境设置与记录: ~/.vimrc ~/.viminfo

记录操作的文件:~/.viminfo
可以在一般命令模式输入[:set all]查看
p304
整体vim的设置值一般放置在/etc/vimrc这个文件中,不过不建议修改,可以修改~/.vimrc这个文件(默认不存在需要手动创建)

vim常用命令示意图

p305页

其他vim使用注意事项

中文编码的问题
LANG=zh_CN.gb18030
export LC_ALL=zh_CN.gb18030
然后在终端工具栏的终端->设置字符编码->中文简体即可。
DOS与Linux的换行符
DOS下换行符是^M$,Linux下回车是LF符号,shell脚本的程序文件将可能造成程序无法执行的状态。
安装dos2unix-*
rpm -ivh dos2unix-*
dos2unix [-kn] file [newfile]
unix2dos [-kn] file [newfile]
-n:保留原本的旧文件,将内容转换后的内容输出到新文件。
不同系统间复制纯文本格式,需要使用上述指令。
语系编码转换
iconv --list
iconv -f 原本编码 -t 新编码 filename [-o newfile]
将繁体中文的UTF-8转换成简体中文的UTF-8编码
iconv -f utf8 -t big5 vi.utf8 | \
> iconv -f big5 -t gb2312 |iconv -f gb2312 -t utf8 -0 vi.gb.utf8

第10章 认识与学习BASH

登录取得的shell记录在/etc/passwd中。可以设置用户能够取得的shell。/etc/shells存放所有shells。

命令别名设置功能:例如alias lm='ls -al'
任务管理、前台、后台控制:job control、foreground、background
程序化脚本:shell scripts
通配符:wildcard。例如*号

查询命令是否为Bash Shell的内置命令:type

type [-tpa] name

快速删除

ctrl+u / ctrl+k	删除前面所有,删除后面所有
ctrl+a / ctrl+e 移动到最前面/最后面

10.2 Shell的变量功能

某些特定变量会影响到bash的环境,例如PATH、HOME、MAIL、SHELL等,为了区别与自定义变量的不同,环境变量通常以大写字符来表示。个人设置方面的应用,快速修改脚本。

变量就是以一组文字或符号等,来替换一些设置或一串保留的数据。

变量前要加$符号。echo $variable
设置变量直接使用等于号(=)即可。
变量不能以数字开头,且只能用数字和字母。变量内容若有空格可使用“”或''将内容结合起来,双引号内的特殊内容$可以保有原本特性,单引号''内的内容仅为一般字符。
可用转义字符[\]将特殊符号变成一般字符,如:myname=VBird\ Tsai
在一串命令的执行中,还需要借由其他额外的命令所提供的信息时,可以使用反单引号[`命令`]或[$(命令)]。例如version=$(uname -r)再echo $version
若该变量为扩增变量内容,使用"$变量名称"或${变量}累加内容。例如PATH="PATH":/home/bin
若该变量需要再其他子程序执行,则需要以export来使变量变成环境变量:例如export PATH
取消变量的方法为使用:[unset 变量名称]

环境变量的功能

env列出目前的shell环境下的所有环境变量与其内容
declare -i number=$RANDOM*10/32768;echo $number;
RANDOM为一个随机数
set观察环境变量以及自定义变量
PS1可以设置命令提示字符
$是关于本shell的PID
?是关于上个执行命令的返回值
export:自定义变量转成环境变量

影响显示结果的语系变量(locale)

locale -a 显示支持的语系
en_US.utf8 zh_CN.UTF-8

变量键盘读取、数组与声明:read、array、declare

read [-pt] variable
-p:后面可以接提示字符
-t:后面可以接等待的秒数。
declare [-aixr] variable 声明变量类型array integer 默认为字符串
+-x等价于export -r将变量设置为readonly,也不能unset
数组var[index]=content

与文件系统及程序的限制关系:ulimit

bash是可以限制用户的某些系统资源,包括可以开启的文件数量,可以使用的CPU时间,可以使用的内存总量等。
ulimit [-SHacdfltu] [配额]
ulimit -a 先显示所有再配 不用记忆上面的字母

变量内容的删除、取代与替换

书本P330-334

10.3 命令别名与历史命令

alias设置别名,注意转义字符加单引号
unalias 取消设置别名
history [n] :列出最近n条命令
history [-c]:将目前shell中的所有history清楚
history [-raw] histfiles
-a:将目前新的命令加入histfiles,若没有文件则默认加入~/.bash_history
-r:将histfiles的内容读到目前这个shell的history中。
-w:将目前的history记录内容写入histfiles中。
重新登陆记录的history数量与变量HISTFILESIZE有关。

!number 执行历史第n条指令
!command 可以缩写 直接最近的以command开头的命令
!!执行上一条指令

同一账号同时多次登录的history会被最后一个关机的覆盖。需要单一bash登录,再用任务管理来切换不同任务,这样才能够将所有曾经执行过的命令记录下来,也才方便未来系统管理员进行命令的debug
如果需要加上时间,可以通过~/.bash_logout来进行history记录。

Bash shell的操作环境

type -a ls可以查询到命令运行的顺序

bash的登录与欢迎信息:/etc/issue、/etc/motd

issue里的内容使用反斜杠作为变量使用
\d本地端时间和日期;
\l显示第几个终端界面;
\m显示硬件的等级(i386,i486等);
\n显示主机的网络名称;
\O显示domain name;
\r操作系统的版本
\t显示本地断的时间
\S操作系统的名称;
\v操作系统的版本

/etc/issue.net 是给telnet远程登录的欢迎界面

至于如果你想要让用户登陆后取得一些信息,例如您想要让大家都知道的信息,那么可以将信息加入/etc/motd里面。例如告诉登录者,系统将会在某个时段维护。
vim /etc/motd

10.4.3 bash的环境配置文件

login shell与non-login shell,重点在于有没有登录login
login shell:取得bash时需要完整的登录流程。
non-login shell:终端接口不需要再次输入的shell。例如子shell

login shell的配置文件:
1./etc/profile:这是系统整体的设置,你最好不要修改这个文件;
2.~/.bash_profile或~/.bash_login或~/.profile:属于个人设置,需要自己添加数据,写入这。

login shell会读整体配置文件/etc/profile并且其会调用/etc/profile.d/*.sh、/etc/locale.conf、/usr/share/bash-completion/completions/*
~/.bash_profile也只有login shell会读。只会读三面三个或中的一个,顺序依次。

source 配置文件文件名
等价于 . ~/.bashrc
不需要注销即可生效配置

~/.bashrc(non-login shell会读)
会调用/etc/bashrc,其中内容有:根据不同的UID设置umask的值,根据不同的UID设置提示字符(就是PS1变量);调用/etc/profile.d/*.sh的设置;
如果出现-bash-4.2$,可以复制/etc/skel/.bashrc到你的根目录,再自定义一下你所想要的内容。

其他的一些配置文件

  • /etc/man_db.conf:规范使用man的时候,man page去哪里找
  • ~/.bash_history
  • ~/.bash_logout:当我注销bash后,系统再帮我做完什么操作后才离开

终端的环境设置:stty、set

登录终端时,自动获取的一些终端的输入环境的设置。
stty [-a]
特别注意带^的符号。
set [-uvCHhmBx]
echo $- 可以显示目前所有的set设置值

通配符与特殊符号

符号 意义
* 代表0到无穷多任意字符
代表一定有一个任意字符
[] 同样代表一定有一个再括号内的字符(非任意字符)。例如[abcd]代表一定有一个字符,可能是a、b、c、d中的一个
[-] 若有减号在中括号内时,代表在编码顺序内的所有字符。例如[0-9]代表0到9之间的所有数字,因为数字的语系编码是连续的
[^] 表示[反向选择],例如[^abc]代表一定有一个字符不是a、b、c的其他字符就接受的意思

特殊符号

符号 内容
# 注释符号
|将[特殊字符或通配符]还原成一般字符
竖号 管道(pipe):分隔两个管道命令的符号
; 连续命令执行分隔符:连续性命令的界定
$ 使用变量前导符:亦即是变量之前需要加的变量替换符
& 任务管理job control:将命令变成后台任务
逻辑运算意义上的的[非]not的意思
>、>> 数据流重定向:输出定向,分别是[替换]与[累加]
<、<< 数据流重定向:输入定向
‘’ 单引号,不具有变量替换的功能($ 变为)
“” 具有变量替换的功能,($ 可保留相关功能)
`` 两个[`]中间为可以先执行的命令,亦可使用$()
() 在中间为子shell的起始与结束
{} 在中间为命令区块的组合

10.5 数据流重定向

数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据,给它传输到其他的地方,例如文件或是设备。

  • 标准输入stdin:代码为0,使用< 或 <<;
  • 标准输出stdout:代码为1,使用 > 或 >>;
  • 标准错误输出stderr:代码为2,使用 2> 或 2>> ;

重定向操作会新建或覆盖原有文件。

如果想将数据累加而不想要将旧的数据删除,利用两个大于的符号(>>)就好。
将stdout与stderr分别存到不同的文档中
find /home -name .bashrc >list_right 2>list_error

/dev/null垃圾桶黑洞设备与特殊写法
/dev/null可以吃掉任何导向这个设备的信息
将错误的数据丢弃,屏幕上显示正确的数据。
find /home -name .bashrc 2> /dev/null

将命令的数据全部写入名为list的文件中
find /home -name .bashrc > list 2>&1
find /home -name .bashrc &> list
1>&2转换成标准错误信息输出

standard input:<与<<

代表将原本需要由键盘输入的数据,改由文件内容来替换
利用cat命令来建立一个文件的简单流程。
cat > catfile
输入内容
按ctrl+d解除。


利用某个文件的内容来替换键盘的敲击
cat > catfile < ~/.bashrc

<< 代表的是[结束的输入字符]即结束。
输入eof就结束输入
cat > catfile << "eof"

命令执行的判断根据: ;与&&与||

$?(命令返回值)与&&或||
若前一个命令执行的结果为正确,在Linux下面会返回一个$?=0的值
cmd1&&cmd2  1.若cmd1执行完毕且正确执行$?=0,则开始执行cmd2
			2.若cmd1执行完毕且错误$?≠0,则cmd2不执行
cmd1||cmd2 1.若cmd1执行完毕且正确执行$?=0,则cmd2不执行
			2.若cmd1执行完毕且错误$?≠0,则开始执行cmd2

创建:ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe
判断:cmd1 && cmd2 || cmd3

10.6 管道命令(pipe)

管道命令使用的是[|]这个界定符号。管道命令与[连续执行命令]是不一样的。这个管道命令仅能处理经由前面一个命令传来的正确信息,也就是标准输出的信息,对于标准错误并没有直接处理的能力。

  • 管道命令仅会处理标准输出,对于标准错误会予以忽略;
  • 管道命令必须要能够接受来自前一个命令的数据成为标准标准输入继续处理才行。
  • 如果硬要让标准错误可以被管道命令所使用,通过数据流重定向,让2>&1加入命令。

选取命令:cut、grep

经过分析的数据,取出想要的一段,cut是一行一行处理的。
cut -d’分隔字符’ -f fields 用于有特定分隔字符
cut -d字符区间 用于排列整齐的信息


例子:将path变量取出,找出第3、5个路径
echo ${PATH} | cut -d':' -f 3,5
例如:将export输出的信息,取得第12字符以后的所有字符,即每行消除前12个字符。
export | cut -c 12-

grep则是分析一行信息,不是处理,若当中有我们所需要的信息,就将该行拿出来。
grep [-acinv] [–color=auto] ‘查找字符’ filename


例子:将last中,有出现root的行显示出来
last | grep 'root'
例如:将last中,没有出现root的行显示出来
last | grep -v 'root'
例子:在last的输出信息中,只要有root取出,并且仅取第一栏
last | grep 'root' | cut -d ' ' -f 1

排序命令:sort、wc、uniq

sort可以根据不同的数据形式在排序,排序的字符与语系的编码有关,因此,如果需要排序时,建议使用LANG=C来让语系统一。

sort [-fbMnrtuk] [file or stdin]
例子:个人账号记录在/etc/passwd下,请将账号进行排序。
cat /etc/passwd | sort
#sort是默认以第一个条信息来排序。而且默认是以文件形式来排序的,所以由a开始排到最后。
例子:/etc/passwd内容以:来分隔的,我想以第三栏来排序,该如何?
cat /etc/passwd | sort -t ':' -k 3
#上面的用文字形式排序仅先比较这个字段的第一个字符,若要以数字排序
cat /etc/passwd | sort -t ':' -k 3 -n
例子:利用last将输出的数据仅显示账号,并加以排序
last | cut -d ' ' -f 1 | sort 

uniq可以将列出的数据中重复的数据仅列出一个显示。

uniq [-ic]
例子:使用last将账号列出,仅取出账号栏,进行排序后仅取出一位。
last | cut -d ' ' -f 1 | sort | uniq
例子:承接上题,如果我还想要知道每个人的登录总次数?
last | cut -d ' ' -f 1 | sort | uniq -c

wc可以知道文件里面有多少字,多少行,多少字符。

wc [-lwm]
例子:/etc/man_db.conf里面到底有多少相关字、行、字符数
cat /etc/man_db.conf | wc
例子:以一行命令串取得登录系统的总人次
last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' |\
>grep -v 'unknown' | wc -l

双向重定向:tee

tee会同时将数据流分送到文件与屏幕,而输出屏幕的,其实就是stdout。

tee [-a] file
-a:以累加append的形式,将数据加入file
例子:last | tee last.list | cut -d ' ' -f 1

字符转换命令:tr,col,join,paste,expand

tr可以用来删除一段信息当中的文件,或是进行文字信息的替换。
tr [-ds] SET1 ...
-d:删除信息当中的SET1字符
-s:替换掉重复的字符
例子:将小写变成大写
last | tr '[a-z]' '[A-Z]'
例子:将/etc/passwd转存成dos换行到/root/passwd中,再将^M删除
cp /etc/passwd ~/passwd && unix2dos ~/passwd
cat ~/passwd | tr -d '-r' > ~/passwd.Linux

col [-xb]
-x:将tab键转换成对等的空格键

join是再两个文件当中,有相同数据的那一行,才将它加在一起。

join [-ti12] file1 file2
-t:join默认以空格字符分隔数据,并且比对第一个栏位的数据,如果两个文件相同,则将两条数据连成一行,且第一个栏位放在第一个。
-i:忽略大小写差异。
-1:数字,代表第一个文件要用哪个栏位来分析
-2:代表第二个文件用哪个栏位来分析
例子:将/etc/passwd与/etc/shadow相关数据整合成一栏
join -t ':' /etc/passwd /etc/shadow | head -n 3
例子:/etc/passwd的第四个栏位是GID,/etc/group的第三个栏位是GID,如何将两个文件整合。
join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
# 相同的栏会移动到输出最前面
在使用join之前,你所需要处理的文件应该要事先经过排序sort处理,否则有些比对的项目会被忽略

paste直接将两行贴在一起,且中间以[Tab]键隔开
paste [-d] file1 file2
-d:后面可以接分隔字符,默认使用Tab
-:如果file部分写成-,表示来自标准输入的数据的意思。

expand将Tab按键转成空格键
expand [-t] file
-t:后面可接数字,一般来说一个Tab按键可以用8个空格键替换,也可自定义数量
行首的代表标志位^
此外,unexpand将空格转成Tab命令。

划分命令:split

split可以将一个大文件,依据文件大小或行数来划分,就可以将大文件划分成为小文件了。

split [-bl] file PREFIX
-b:后面可接欲划分成的文件大小,可加单位,例如b、K、M等
-l:以行数来进行划分
PREFIX:代表前缀字符的意思,可作为划分文件的前缀文字。
例子:将/etc/services以300k一划分
split -b 300k /etc/services services
例子:将上面的三个小文件合成一个文件,文件名位servicesback
cat services* >> servicesback
例子:ls -al /输出的信息中,每十行记录成一个文件。
ls -al / | split -l 10 - lsroot

参数代换:xargs

xargs就是在产生某个命令的参数的意思。xargs可以读入stdin的数据,并且以空格符或换行符作为识别符,将stdin的数据分隔成参数。如果有一些文件名或是其他意义的名词内含有空格符,xargs可能就会误判。

xargs [-0epn] command
例子:将/etc/passwd内的第一栏取出,仅取出三行,使用id这个命令将每个账号内容显示出来
id root
uid=0 gid=0 groups=0 #这个id命令可以查询使用者的UID/GID信息。
cut -d ':' -f 1 /etc/passwd | head -n 3 | id  #id 不是管道命令,前面的命令都不会传递给id
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id 
#id一次只能接收一个参数,xargs是管道命令
例子:将所有的/etc/passwd内的账号都以id查看,但查到sync就结束命令串
cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
使用xargs的原因是很多命令其实并不支持管道命令,因此可以通过xargs来提供该命令使用的 标准输入。

关于减号[-]的用途

stdin与stdout可以利用减号来代替
例子:tar -cvf - /home | tar -xvf - -C /tmp/homeback
将/home里面的文件给它打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf - /home 传送给后面的tar -xvf - 。

软件安装rpm、srpm、yum

如果在安装的时候加上一些这些程序的相关信息,将它建立成为数据库,那不就可以进行安装、反安装、升级与验证等的相关功能。客户端获取某个文件后,只需通过特定的命令来安装,那么该文件就会依照内部的脚本来检测依赖的辅助软件是否存在,若安装的环境符合需求,那就会开始安装。

发行版代表 软件管理机制 使用命令 在线升级功能(命令)
Red Hat/Fedora rpm rpm、rpmbuild YUM(yum)
Debian/Ubuntu dpkg dpkg APT(apt-get)

什么是rpm与srpm

RPM是以一种数据库记录的方式来将你所需要的软件安装到你的Linux系统的一套软件管理机制。其最大特点是已经编译过,记录这个软件要安装时候所必须具备的依赖性文件。为了使不同的Linux发行版能够安装,SRPM是source RPM是含有源代码且可以修改参数配置的,需要先将该软件以RPM管理的方式编译,再完成安装。

文件格式 文件名格式 直接安装与否 内含程序类型 可否修改参数并编译
RPM xxx.rpm 可以 已编译 不可以
SRPM xxx.src.rpm 不可以 未编译的源代码 可以

rp-pppoe   -3.11-         5          .e17.x86_64    .rpm
软件名称  软件的版本信息  发布的次数    适合的硬件平台  扩展名

RPM软件管理程序:rpm

RPM默认安装的路径

先会读取文件内记录的设置参数内容,然后比对Linux系统的环境,以找出是否有属于依赖的软件尚未安装的问题。
安装完毕后,该软件的信息就会被写入到/var/lib/rpm/的目录下的数据库文件中。目前的RPM也提供数字签名信息。软件内的文件放置是与文件系统有关的。

RPM安装install

rpm-ivh package_name
-i:安装
-v:观看到安装信息
-h:显示安装进度
可以直接加网址或者硬盘下的rpm文件
--nodeps:不考虑依赖性强制安装
--replacefiles如果在安装过程中显示某个文件已经安装在你的系统上,可以覆盖用这个
--replacepkgs重新安装某个rpm
--force是--replacefiles和--replacepkgs的综合体
--justdb由于RPM数据库损坏,可使用这个选项更新软件在数据库内的信息
--nosignature想要跳过数字签名
--prefix 路径 ,想将软件安装到非正规的地方
--noscripts不想让软件在安装过程中自行执行某些系统命令
--test 测试此软件是由具有依赖性

RPM升级与更新(Upgrade/Freshen)

-Uvh与-Fvh可以用的选项与参数,跟install是一样的。
-Uvh 后面接的软件即使没有安装过,则系统将予以直接安装;若后面接的软件有安装过旧版,则更新
-Fvh 没装不装,装过则更新

RPM查询(Query)

其实查询的是/var/lib/rpm/这个目录下的数据库文件
例子:找出系统中是否安装某个软件
rpm-q 软件名
例子:列出该软件所提供的所有目录与文件
rpm-ql 软件名
例子:列出软件的相关说明信息
rpm-qi 软件名
例子:找出软件的配置文件与说明文件
rpm-qc 文件名
rpm-qd 文件名
例子:若要成功安装软件,还需要什么文件
rpm-qR 文件名
例子:根据上例列出的某个文件,找出某个程序是哪个软件提供的
rpm-qf 文件名
例子:想知道软件安装还需要什么依赖文件
rpm-qpR 软件名

RPM验证与数字签名(Verify/signature)

验证也就是说某个文件被你删除或修改了,原本的安装可能不能用了,就验证一下可用性。
例子:列出某软件是否被修改过
rpm-V 软件名
没有任何信息就是没有修改,有信息就是有修改
例子:判断某个文件是否被修改过
rpm-Vf 文件名
例子:列出软件内可能被修改的文件
rpm-Vp 文件名
至于显示出来的信息有具体的含义可以参见P717代表什么被修改过了


除了用md5验证软件,软件还可使用数字签名,并先将公钥发布,在安装一个RPM文件时,先安装公钥文件,安装过程会读取RPM文件的签名信息并与本机系统内的签名信息比对,若签名相同,则准许安装。CentOS使用的是GPG利用哈希算法,算出独一无二的专属密钥或是数字签名。

RPM卸载与重建数据库(erase/rebuildddb)

卸载安装的过程一定是要由最上层往下接触。
rpm-e 软件名 可以用–nodeps来不管依赖文件
rpm–rebuilddb 重建数据库

YUM在线升级功能

YUM可以自动处理软件依赖性问题。

YUM查询

范例一:查找出某关键字的相关软件有哪些
yum search 软件或描述的重要关键字;
范例二:找出某软件的功能
yum info 软件
范例三:列出YUM服务器上面提供的所有软件名称
yum list
范例四:列出目前服务器可供本机升级的软件有哪些
yum list updates
范例五:列出提供passwd这个命令的软件有哪些
yum provides passwd

YUM安装升级软件

范例一:安装(先可以查询未安装的软件名)
yum install 软件名
yum update 不加软件名则会升级整个系统,加软件名则升级一个软件。

YUM删除软件

yum remove 软件名

YUM的配置文件

镜像网站内[repodata]的目录,就是分析RPM软件后所产生的软件属性依赖数据存放处。
baseurl:这个最重要,因为后面接的就是软件源的实际地址,mirrorlist是由YUM程序自行去识别镜像站,但可以会识别有误,baseurl则是指定固定的一个软件源网址。

vim /etc/yum.repos.d/CentOS-Base.repo

修改系统默认的配置文件,事实上我们应该要在/etc/yum.repos.d/下面新建一个.repo才行,但因为是特定的镜像站,才直接配置系统文件。但是可能由于使用的软件源版本由新旧之分,你得要知道YUM会先下载软件源的列表到本机的/var/cache/yum里面去。那我们修改了网址却没有修改软件源名称[base]例如中括号内的名字,可能就会造成本机的列表与YUM服务器的列表不同步,此时就出现无法更新的问题了。
yum clean all/packages/headers
删除已下载过的所有软件源的相关数据。

YUM的软件群组功能

安装大型软件。利用软件群组功能。
yum [群组功能] [软件群组]
grouplist:列出所有可使用的软件群组
groupinfo:后面接group name,则可了解该group内含的所有软件名
groupinstall:群组安装
groupremove:群组卸载
在群组的软件可以是[可选择的]而不是[主要的mandatory],则系统不会帮你安装,若要一个一个安装可以用yum install xxx一个一个安装,也可以修改
vim /etc/yum.conf
找到distroverpkg=centos-release 这一行,下面加入
group_package_types=default,mandatory,optional


EPEL/ELRepo外挂软件以及自定义配置文件

vim /etc/yum.repos.d/epel.repo
[epel]
name=epel_packages
baseurl=https://dl.fedoraproject.org/pub/epel/7/x86_64/
gpgcheck=0
enablede=0
暂时不使能这个软件源。
光盘则设置baseurl为file:///mnt

全系统自动升级

yum -y update

基础服务管理:以Apache为例

1. 安装:yum install 软件;
2. 启动:systemctl start 软件;
3. 开机启动:systemctl enable 软件;
4. 防火墙:firewall-cmd --add-service="你的服务";firewall-cmd --permanent --add-service="你的服务";firewall-cmd --list-all
5. 测试:用软件去查看你的服务正常与否localhost

认识系统服务(daemon)

什么是daemon与服务(service)

常驻内存中的进程且可以提供一些系统或网络功能,那就是服务。但是service的提供总是需要程序的运行吧,所以完成这个service的程序我们就称呼它为daemon。
systemd的好处:

  • 并行处理所有服务,加速开机流程
  • 一经要求就响应的on-demand启动方式:systemd由于常驻内存,因此任何要求on-demand都可以立即处理后续的daemon启动任务
  • 服务依赖性的自我检查
  • 依daemon功能分类:首先systemd先定义所有的服务为一个服务单位unit,并将该unit归类到不同的服务类型type,区分为service,socket,target,path,snapshot,timer等多种不同的类型type,方便管理员的分类和记录。
  • 将多个daemons集合成为一个群组:systemd亦将许多的功能集合成为一个所谓的target项目,这个项目主要在设计操作环境的创建,所以是集合了许多的daemons,亦即是执行某个target就是执行好多个daemon的意思。
  • 向下兼容旧有的init服务脚本

虽然如此,不过systemd还有些地方无法完全替换init的,包括:

  • 全部的systemd都用systemctl这个管理程序进行管理,而systemctl支持的语法有限制,不能自定义参数。
  • 某服务手动执行,不使用systemctl去启动,那么systemd将无法检测到服务,而无法进一步管理。
  • systemd启动过程中,无法与管理员通过标准输入传入信息。因此,自行编写systemd的启动设置时,务必要取消交互机制。(连通过启动时传进的标准输入信息也要避免)。

systemd的配置文件放置目录

  • /usr/lib/systemd/system:实际启动脚本设置
  • /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先级要比/usr/lib/systemd/system/高
  • /etc/systemd/system/:管理员根据主机系统的需求所建立的执行脚本。执行优先级比/run/systemd/system/高。

操作系统启动会不会执行某些服务其实是看/etc/systemd/system/,修改某个服务的启动参数设置,到/usr/lib/systemd/system。

systemd的unit类型分类说明

/usr/lib/systemd/system利用扩展名可以区分不同的服务。

扩展名 主要服务功能
.service 一般服务类型:主要是系统服务,包括服务器本身所需要的本地服务以及网络服务等
.socket 内部程序数据交换的socket服务:主要是IPC的传输信息socket文件功能。
.target 执行环境类型:其实就是一群unit的集合
.mount .automount 文件系统挂载相关的服务:例如来自网络的自动挂载,NFS文件系统挂载等与文件系统相关性较高的进程管理
.path 检测特定文件或目录类型:某些服务需要检测某些特定的目录来提供队列服务
.timer 循环执行的服务:这个服务有点类似anacrontab,不过是由systemd主动提供,比anacrontab更加有弹性

通过systemctl管理服务

基本上,systemd这个启动服务的机制,主要是通过一个名为systemctl的命令来完成的。全部操作都要使用systemctl。

通过systemctl 管理单一服务的启动/开机启动与查看状态

一般来说服务的启动有两个阶段,一个是[开机的时候设置要不要启动这个服务],以及[你现在要不要启动这个服务]。

systemctl [command] [unit]
start:立刻启动
stop:立刻关闭
restart:立刻重启
reload:不关闭,重新加载配置文件,让设置生效
enable:设置下次开机时,后面接的unit会被启动
disable:设置下次开机时,不启动unit
status:查看目前unit的状态
is-active:目前有没有正在运行
is-enable:开机有没有默认要启用这个unit

范例一:查看atd这个服务的状态
systemctl status atd.service
范例二:正常关闭这个atd服务
systemctl stop atd.service
常见的几种状态:
active(excited):仅执行一次就正常结束的服务,目前并没有任何进程在系统中执行。
active(waiting):正在运行,不过还需要等待其他的事件发生才能继续运行。
static:这个daemon不可以自己启动,不过可能会被其他的enabled的服务来唤醒(依赖属性的服务)。
mask:这个daemon无论如何都无法被启动,因为已经被强制注销(非删除)。可以通过systemctl unmask方式改回默认状态。
很多服务彼此之间具有依赖性,需要全部关闭才可以。

强迫服务注销mask的练习

systemctl stop cups.service
systemctl mask cups.service
其实这个mask注销的操作,只是让启动的脚本变成空的设备而已。
恢复则 systemctl unmask cups.service

通过systemctl查看系统上所有的服务

systemctl [command] [--type=TYPE] [--all]
command:
list-units:依据unit显示目前启动的unit,若加上--all才会列出没启动的。
list-unit-files:依据/usr/lib/systemd/system/内的文件,将所有文件列表说明。
--type=TYPE:就是主要有service,socket,target等。

范例一:列出系统上面有启动的unit
systemctl list-units
范例二:列出所有已经安装的unit有哪些。
systemctl list-unit-files
范例三:仅列出service的daemon
systemctl list-units --type=service --all

通过systemctl管理不同的操作系统(target unit)

如何知道当前模式以及如何修改target
systemctl [command] [unit.target]
command:
get-default:取得目前的target。
set-default:设置后面的target成为默认的操作模式。
isolate:切换到后面接的模式。

范例一:查看当前的模式
systemctl get-default
范例二:在不重启的情况下,将目前的操作系统改为纯命令行模式,关闭图形界面。
systemctl isolate multi-user.target
范例三:若要重新加载图形界面
systemctl isolate graphical.target

通过systemctl分析各种服务之间的依赖性

systemctl list-dependencies [unit] [--reverse]
--reverse:反向追踪谁使用这个unit的意思。
范例一:列出目前的target环境下,用到了哪些unit。
systemctl list-dependencies
范例二:如果要查出谁会使用到unit
systemctl list-denpendencies --reverse

与systemctl的daemon运行过程相关的目录介绍

哪些目录跟系统的daemon有关?

  • /usr/lib/systemd/system

  • /run/systemd/system/

  • /etc/systemd/system/

  • /etc/sysconfig/* :几乎所有的服务都会将初始化的一些选项设置写入到这个牡蛎。

  • /var/lib/ :一些会产生数据的服务,将数据写入到此文件夹。

  • /run/ :放置了好多daemon的缓存,包括lock文件以及PID文件等。

    查询socket服务放置的位置
    systemctl list-sockets


网络服务与端口对应简介

设置服务与端口对应:/etc/services

关闭网络服务

systemd将许多原本不被列为daemon的进程都纳入到systemd自己的管辖监测范围内,因此就多了很多daemo的存在。网络服务虽然默认由SELinux管理,建议非必要的网络服务就关闭它,那什么是网络?基本上,会产生一个网络监听端口port的进程,你就可以称它是网络服务。

查看网络端口
netstat -tlunp

systemctl针对service类型的配置文件

systemctl配置文件相关目录简介

修改的位置在/etc/systemd/system/
  • /usr/lib/systemd/system:官方发布的默认配置文件。
  • /run/systemd/system/
  • /etc/systemd/system/ :建立与配置文件相同文件名的目录,但是要加上 .d的扩展名,然后在该目录下建立custom.conf的配置文件即可。
  • /etc/systemd/system/vsftpd.service.wants/* :此目录内的文件为链接文件,设置依赖服务的链接,意思是启动vsftpd.service之前,需要事先启动哪些服务的意思。
  • /etc/systemd/system/vsftpd.service.requires/* :此目录内的文件为链接文件,设置依赖服务的链接。意思是在启动vsftpd.service之前,需要事先启动哪些服务的意思。

基本上,在配置文件里你都可以自由设置依赖服务的检查,并且设置加入到哪些target里面。

systemctl配置文件的设置项目简介

cat /usr/lib/systemd/system/sshd.service
[Unit]:unit本身的说明,以及与其他依赖daemon的设置,包括在什么服务之后启动才启动此unit之类的设置。
[Service]、[Socket]、[Timer]、[Mount]、[Path]:不同的unit类型就得要使用相对应的设置项目。我们使用sshd.service来当模板,所以这就使用[Service]来设置。这个项目主要用来规范服务启动的脚本、环境配置文件名、重新启动的方式等。
[Install]:这个项目就是将此unit安装到那个target里面去的意思。

配置文件内的设置规则:

  • 设置项目是可以重复的,例如我可以重复设置两个After在配置文件中,不过,后面的设置会替换前面的。因此,如果你想要将设置值归零,可以使用类似[After=]的设置,亦即项目的等号后面什么都没有,就将该设置归零了(reset)。
  • 如果设置参数需要有[是/否]的项目(布尔值,boolean),你可以使用1、yes、true、on代表启动,用0、no、false、off代表关闭,就将该设置归零了(reset)。
  • 空白行、开头为#或;的,都是注释
  • P579-581

两个vsftpd运行的实例

直接在配置目录以及设置脚本目录里,复制原文件。

多重的重复设置方式:以getty为例

systemd:
先看/usr/lib/systemd/system/、/etc/systemd/system/有没有[email protected]的设置,若有就执行,若没有就执行下一步。
找[email protected]的设置,若有则将@后面的数据带入成%l的变量,进入[email protected]执行。

[email protected]的目的就是为了要简化多个执行的启动设置,它的命名方式是这样的:

原始文件:执行服务名称@.service
执行文件:执行服务名称@范例名称.service
启动脚本中:ExecStart=-/sbin/agetty --noclear %I $TERM

将tty的数量由6个降低到4个

#修改默认的logind.conf内容,将原本6个终端改成4个。
vim /etc/systemd/logind.conf
#关闭tty5和tty6并重新启动getty.target
systemctl stop [email protected]
systemctl stop [email protected]
systemctl restart systemd-logind.service
#暂时需要启动tty8时,
systemctl start [email protected]

暂时新增vsftpd到2121端口

#/usr/lib/systemd/system下面还有个特别的[email protected]
cat /usr/lib/systemd/system/[email protected]
#先复制一个conf再修改监听port
listen_port=xxxx
默认启动小于1024以下的端口时,需要使用到root的权限,因此小于1024以下端口的启动较可怕。而这次范例中,我们使用2121端口,它对于系统的影响可能小一些,所以就忽略了SELinux的限制。

自己的服务自己做

P585
1.先做一个脚本。
2.再添加给执行权限。
3.添加启动服务脚本指向执行脚本。

systemctl针对timer的配置文件

任务需求,基本上想要使用systemd的timer功能,你必须要有几个要件:

  • 操作系统的timer.target一定要启动。
  • 要有个sname.service的服务存在(sname是你自己指定的名称)。
  • 要有个sname.timer的时间启动服务存在。

sname.timer的设置值

可以到/etc/systemd/system下面去建立这个*.timer文件,基本的设置参数(man systemd.timer&man systemd.time)。
设置参数 参数意义说明
OnActiveSec 当timer.target启动多久之后才执行这个unit
OnBootSec 当启动完成后多久之后执行
OnStartupSec 当systemd第一次启动后之后过多久才执行
OnUnitActiveSec 这个timer配置文件所管理的那个unit服务在最后一次启动后,隔多久再执行一次的意思
OnUnitInactiveSec 这个timer配置文件所管理的那个unit服务在停止一次启动后,隔多久再执行一次的意思
OnCalendar 使用实际时间(非循环时间)的方式来启动服务的意思,至于时间的格式后续再谈
Unit 一般来说不太需要设置,因此如同上面刚刚提到的,基本上我们设置都是sname.server+sname.timer,如果你的sname并不相同时,那在.timer的文件中,就得要指定是哪一个service unit
Persistent 当使用OnCalendar的设置时,指定该功能要不要持续进行的意思,通常是设置yes,比较能够满足类似anacron的功能

使用于OnCalendar的时间

如果你想要从crontab转成这个timer功能的话,那么要了解时间设置的格式,基本上的格式如下:
语法:英文周名 YYYY-MM-DD HH:MM:SS
范例:Thu 2015-08-13 13:40:00
也可使用us,ms,s,m,h,d,w,month,y。
也可以使用英文常用的口语化日期代表。


一个循环时间运行的案例

启动后2小时开始执行一次这个backup.service
自从第一次执行后,未来我每两天要执行一次backup.service
vim /etc/lib/systemd/system/backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2hrs
OnUnitActiveSec=2days
[Install]
WantedBy=multi-user.target
要注意,最终backup.timer所记录的下次运行时间,其实是与timers.target所记录的时间差。

一个固定日期运行的案例

星期天凌晨2点运行这个备份
vim /etc/lib/systemd/system/backup2.timer
[Unit]
Description=backup my server timer2
[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service
[Install]
WantedBy=multi-user.target
注意,是与日历时间对比1970-01-01 00:00:00

17.5 CentOS 7.x默认启动的服务概要

P589-591

基础系统设置与备份策略

网络设置(手动设置与DHCP自动获取)

nmcli是通过一个名为【连接代号】的名称来设置是否要上网,而每个【连接代号】会有个【网卡名称】,这两个东西通常设置成相同名称。

nmcli connection show [网卡名称]
设置网络参数
nmcli connection modify eth0 \
> connection.autoconnect yes \
> ipv4.method manual \
> ipv4.addressers x.x.x.x/xx \
> ipv4.gateway x.x.x.x \
> ipv4.dns x.x.x.x
上面只是修改了网络配置还需要(up)生效
nmcli connection up eth0
nmcli connection show eth0

自动获取IP参数
nmcli connection modify eth0 \
>connection.autoconnect yes \
>ipv4.method auto
nmcli connection up eth0

修改主机名
hostnamectl [set-hostname 你的主机名]

日期与时间设置

timedatectl [command]
list-timezones:列出系统上所支持的时区名称
set-timezone:设置时区位置
set-time:设置时间
set-ntp:设置网络校时系统。
例子:显示目前的时区与时间等信息
timedatectl
例子:显示出是否有New_York时区?若有,则请将目前的时区更新一下
timedatectl list-timezones | grep -i new
timedatectl set-timezones "America/New_York"

时间的调整
timedatectl set-time "2015-09-01 12:02"
ntpdate自动网络校时
ntpdate s2m.time.edu.cn 这里的网址指的是北京大学提供的时间服务器
hwclock -w 则是将正确的时间写入你的BIOS时间记录内。

语系设置
locale 
/etc/locale.conf
LANG
localectl 也能查看系统语系配置
locale  是当前这个软件的语系信息
export LC_ALL=en_US.utf8切换英文语系。
例子:图形界面改成英文语系的登录界面
localectl set-locale LANG=en_US.utf8
systemctl isolate multi-user.target
systemctl isolate graphocal.target

防火墙的简易设置
不要只是在Runtime记录区增加规则设置,而是必须要在永久记录区增加规则才性。
区域zone:根据不同的环境所设计的网络区域zone
服务\端口\富规则:如果你有整个域名需要开放或者拒绝的时候,则需要用这个项目处理。\接口:针对网卡做出的规范。
firewall-cmd --permanet --add-rich-rule='rule family="ipv4" \
> source address="192.168.1.0/24" accept'
firewall-cmd --reload
重新加载生效防火墙。

第13章 Linux账号管理与ACL权限设置

用户标识符:UID与GID

系统根据/etc/passwd和/etc/group的内容,找到UID与GID对应的账号与组名再显示出来。
文件只会记录UID的数字。管理密码的文件/etc/shadow

/etc/passwd
root:x:0:0:root:/root:/bin/bash
以:分隔。
1.账号名称。2.密码,但已经不用,用x表示,密码放置到/etc/shadow
3.UID,0表示系统管理员,1-999表示系统账号,1000-60000表示可登录用户。
4.GID,与/etc/group有关。5.用户信息说明栏:只是用来解释这个账号的意义。
6.家目录:可以修改。
7.shell:当用户登录系统后就会获取一个shell来与系统的内核沟通以进行用户的操作任务。有一个shell可以使账号再登录时无法获得shell环境,那就是/sbin/nologin,可以用来制作纯pop邮件账号的数据。

/etc/shadow文件结构
root:$6$qa4xJ0t5$xMHtOEI.IxFuZ.cNALHF6eLVJP4eReaooBKyxmaZ.qogDwsiKljeB1GUuBb6DYlpoT.YBmbJmmh1LsacANmSZ1:18365:0:99999:7:::
bin:*:17834:0:99999:7:::
daemon:*:17834:0:99999:7:::
adm:*:17834:0:99999:7:::
以分号:为分隔
  1. 账号名称,必须与/etc/passwd中的相同
  2. 密码
  3. 最近修改密码的日期,以1970年1月1日累加
  4. 密码不可修改的天数(与第三个字段相比):0为任意时间可修改,20的话就是20天后不能修改
  5. 密码需要重新修改的天数(与第三个字段相比):你必须要再这个天数内重新设置密码,否则这个账号的密码将会【变为过期特性】。
  6. 密码需要修改期前的警告天数(与第5个字段相比)
  7. 密码过期后的账号宽限时间(密码失效日):密码有效期为3字段和5字段相加。
  8. 账号失效日期:收费服务中使用
  9. 保留

若忘记了root密码,可以以live CD启动后挂载根目录去修改/etc/shadow,将里面的root的密码字段清空,再重新启动后root不用密码即可登录,登录后在赶快以passwd命令去设置root即可。或重启进入单人维护模式,系统赋予root权限,再以passwd修改密码。


关于用户组:有效与初始用户组,groups,newgr

/etc/group
/etc/gshadow

head -n 4 /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
  • 以冒号【:】为分隔符
  • 1.组名
  • 2.用户组密码
  • 3.GID
  • 4.此用户支持的账号名称:要让dmtsai与alex加入root组,可以再第一行后加入【dmtsai,alex】,注意不要有空格

有效用户组与初始用户组
groups:查询当前用户所属的用户组
第一个输出的用户组即为有效用户组。通常有效用户组的作用是新建文件。
newgrp:有效用户组的切换
而且是另外以一个shell来提供这个功能。如果想要退回则exit即可。
加入用户组:root下usermod;用户组管理员以gpasswd设置。

/etc/gshadow
root:::
bin:::
daemon:::
sys:::
如果第二栏为空或【!】则该组不具有组管理员。这个gshadow最大的功能是建立用户组管理员。

13.2 账号管理

13.2.1 新增与删除用户:useradd、相关配置文件、passwd、usermod、userdel

useradd [-u UID] [-g 初始用户组] [-G 次要用户组] [-mM] \
> [-c 说明栏] [-d 家目录绝对路径] [-s shell] 使用者名称
范例一:完全参考默认值建立一个使用者,名称为vbird1
useradd vbird1
范例二:令初始用户组为users,且UID设为1500,建立一个账号
useradd -u 1500 -g users vbird2
范例三:建立一个系统账号
useradd -r vbird3
不会自行建立家目录

useradd参考文件
useradd -D
/etc/default/useradd
针对用户组的角度有两种不同的机制:私有用户组机制(不参考GROUP=100这个设置值),家目录仅自己进入;公共用户组机制(每个账号属于user用户组可以互访家目录)。
除了这些基本的账号设置之外,UID/GID的密码参数又是在哪里参考的呢?
/etc/login.defs

passwd
passwd [--stdin] [账号名称] #所有人均可使用来改自己的密码
passwd [-l] [-u] [--stdin] [-S] \
> [-n 日数] [-x 日数] [-w 日数] [-i 日期] 账号  #root功能
范例一:请root设置vbird2的密码
passwd vbird2 #root下
PAM模块管理密码,/etc/pam.d/passwd,该文件与密码有关的测试模块就是使用pam_cracklib.so,这个模块会检验密码相关的信息,并且替换/etc/login.defs内的PSS_MIN_LEN的设置。
范例三:使用standard input建立用户的密码
echo "abc543CC" | passwd --stdin vbird2
范例四:管理vbird2的密码使具有60天有效期,密码过期10天后账号失效的设置。
passwd -S vbird2
passwd -x 60 -i 10 vbird2
passwd -S vbird2
范例五:让vbird2的账号失效。
passwd -l vbird2 #锁定
passwd -u vbird2 #恢复

chage [-ldEImMW] 账号名
范例一:列出vbird2的详细密码参数
chage -l vbird2
范例二:建立一个账号,该账号第一次登陆后必须使用默认密码,但必须要修改密码后,使用新密码才能够登录系统使用bash。
useradd agetest
echo "agetest"|passwd --stdin agetest
chage -d 0 agetest
chae -l agetest | head -n 3

usermod提供相关命令对账号相关数据进行微调。
usermod [-cdegGlsuLU] username
范例一:修改使用者vbird2的说明栏
usermod -c "Tset" vbird2
范例二:使用者vbird2在2015/12/31失效
usermod -e "2015-12-31" vbird2
chage -l vbird2|grep 'Account expires'
范例三:建立家目录
cp -a /etc/skel /home/vbird3
chown -R vbird3:vbird3 /home/vbird3
chmod 700 /home/vbird3
ll -a ~vbird3

userdel [-r] username
-r:连同使用者的家目录也删除。

用户功能

id [username] 查询某人或自己的UID/GID
finger [-s] username
-s:仅列出使用者的账号、全名、终端代号与登录时间等。
范例一:查看vbird1的使用者相关账号属性
finger vbird1
范例二:利用vbird1建立自己的计划文件
echo "I will study" > ~/.plan
finger vbird1
范例三:找出目前在系统上面登录的使用者与登录时间。
finger

chfn 有点像change finger的意思
范例一:vbird1修改一下自己的相关信息。
chfn

chsh [-ls] #change shell的意思
-l:列出系统上可用的shell,其实就是/etc/shells的内容
-s:修改自己的shell
范例一:用vbird1的身份列出系统上所有合法的shell,并且指定csh为自己的shell
chsh -l
chsh -s /bin/csh

新增与输出用户组

groupadd [-g GID] [-r] 用户组名称
范例一:新建一个用户组
groupadd group1
新建与用户私有用户组无关的其他用户组时,使用小于1000的GID为宜。
groupmod [-g GID] [-n group_name] 用户组名
范例一:将group1名称改为mygroup,且GID=201
groupmod -g 201 -n mygroup group1
groupdel [groupname]
如果硬要删除一个groupname需要确定/etc/passwd里的账号没有任何人使用该用户组作为初始用户组。
可以先修改这个用户的GID再输出这个用户。
gpasswd groupname
gpasswd [-A user1,...] [-M user3,..] groupname
gpasswd [-rR] groupnmae
范例一:将用户组交给某用户管理
gpasswd -A vbird1 group1
范例二:以vbird1登录,将vbird1、vbird3成为group1的成员
gpasswd -a vbird1 group1
gpasswd -a vbird3 group1

账号管理实例

SGID?

使用外部身份认证系统
authconfig-tui,Tab键切换
*代表启用,不要随意更改

主机的详细权限规划:ACL的使用

访问控制列表,单针对一个用户或某个用户组来设置特定的权限

什么是ACL与如何支持启动ACL

ACL几乎已经默认加入了所有常见的Linux文件系统的挂载参数中(ext2,ext3,ext4,xfs等)

dmesg|grep -i acl 查询是否支持ACL的功能

ACL的设置技巧:getfacl、setfacl

getfacl:获取某个文件/目录的ACL设置选项;
setfacl:设置某个目录/文件的ACL规范。

setfacl [-bkRd] [{-m|-x} acl 参数] 目标文件名
1.针对特定使用者的方式。
#设置规范【u:[使用者账号列表]:[rwx]】,例如针对vbird1的权限规范rx。
touch acl_test1
ll acl_test1
setfacl -m u:vbird1:rx acl_test1
ll acl_test1
#权限部分多了个+,且与原本的权限644看起来差异很大,但要如何查看?
setfacl -m u::acl acl_test1
ll acl_test1
#设置值中的u后面无使用者列表,代表设置该文件拥有者,所以上面root的权限成了rwx。
一个文件设置了ACL参数后,它的权限部分就会多出一个+号,但是此时你看到的权限与实际权限可能有点误差。利用getfacl查看。

getfacl filename
选项基本与setfacl差不多

范例二:针对特定用户组的方式。
#设置规范:【g:[用户组列表]:[rwx]】
setfacl -m g:mygroup1:rx acl_test1
getfacl acl_test1

范例三:针对有效权限mask的设置方式
#设置规范:【m:[rwx]】,例如针对刚刚的文件规范仅有r。
setfacl -m m:r acl_test1
getfacl acl_test1
#vbird1与mask的集合发现仅有r存在,因此vbird1仅具有r的权限而已,并不存在x权限,这就是mask的功能。

ACL的权限设置被子目录继承。
#针对默认权限的设置
#设置规范【d:[ug]:使用者列表:[rwx]】
【针对目录来设置的默认ACL权限设置值】的选项,我们可以让这些属性继承到子目录下。
setfacl -b 文件名 取消ACL的属性。
范例:取消某个账号的ACL时,不需要加上权限设置
setfacl -x u:myuser1 /srv/projecta
setfacl -x d:u:myuser1 /srv/projecta
#开始让pro3这个用户无法使用该目录。
setfacl -m u:pro3:- /srv/projecta
#在设置一个用户或用户组没有任何权限的ACL语法中,权限的字段不可留白,而是应该加上一个减号。

13.4 用户身份切换

【su -】 直接转变成root
【sudo 命令】执行root的命令串。

13.4.1 su

su [-lm] [-c 命令] [username]
-m:-m与-p是一样的,表示【使用目前的环境设置,而不读取新使用者的配置文件】。
-c:仅进行一次命令
# 单纯使用【su】切换成为root的身份,读取的变量设置方式为非登录shell的方式,这种方式很多原本的变量不会被修改。要加上【-】可以转换环境。
范例三:dmtsai想要执行【head -n 3 /etc/shadow】一次,且已经root密码
su - -c "head -n 3 /etc/shadow"
范例四:原本是dmtsai这个用户,切换成为vbird11
su -l vbird1
若想完整地切换到新用户的环境,必须使用【su - username】或【su -l username】

13.4.2 sudo

并非所有人都能够执行sudo,而是仅有规范到/etc/sudoers内的用户才能够执行sudo这个命令
sudo [-b] [-u 新使用者账号]
-b:将后续命令放到后台执行
-u:后面可以接欲切换的使用者
范例二:想要以vbird1的身份建立~vbird1/www并于其中建立index.html命令
sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
> echo 'This is index.html file' > index.html
sh -c "一串命令"执行。

visudo与/etc/sudoers

visudo修改/etc/sudoers可以检测语法错误
vbird1 ALL=(ALL)   ALL #自己添加
使用者账号  登录者的来源主机名称=(可切换的身份) 可执行的命令

利用wheel用户组以及免密码的功能处理visudo

visudo
%wheel   ALL=(ALL)   ALL
# 【%】代表用户组
usermod -a -G wheel pro1
上面的设置【任何加入wheel这个用户组的用户,就能使用sudo】
例子:设置【不需要密码即可使用sudo】
visudo
%wheel   ALL=(ALL)  NOPASSWD:ALL

有限制的命令操作

范例:设置myuser1仅能够帮root修改其他用户的密码时
visudo
myuser1   ALL=(root)    /usr/bin/passwd
必须要填写绝对路径
限制用户的命令参数
myuser1 ALL=(root)   !/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root

通过别名创建visudo

visudo的别名可以是【命令别名,账户别名,主机别名】
visudo
User_Alias ADMPW = pro1,pro2,pro3
Cmnd_Alias ADMPWCOM=!/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root
ADMPW ALL=(root)  ADMPWCOM
利用User_Alias创建一个账号,且必须大写,包括Cmnd_Alias,Host_Alias(来源主机别名),都需要大写。

sudo的时间间隔问题

两次sudo操作的时间间隔超过5分钟,那就得要重新输入一次你的密码了。

sudo搭配su的使用方式

visudo
User_Alias ADMINS=pro1,pro2,pro3
ADMINS ALL=(root) /bin/su -
上述三个人只要输入【sudo su -】输入自己的密码即可转换为root,不用担心root密码泄露。

13.5 用户的特殊shell与PAM模块

【仅能使用邮件服务器相关邮件服务的账号,而该账号并不能登录Linux主机】

13.5.1 特殊的shell、/sbin/nologin

/sbin/nogoin的【无法登录】:【这个用户无法使用bash或其他shell来登录系统】,并不是说这个账号无法使用其他的系统资源。可以创建【/etc/nologin.txt】告知不能登录的原因。

PAM模块简介

【PAM:插入式验证模块】
PAM可以说是一套API,它提供了一连串的验证机制,只要用户将验证阶段的需求告知PAM后,PAM就能够返回用户验证的结果。PAM用来进行验证的数据称为模块(modules)

PAM模块设置语法

例如passwd的执行,PAM模块会到/etc/pam.d/找寻与程序(passwd)同名的配置文件,根据/etc/pam.d/passwd的配置,引用相关的PAM模块逐步进行验证分析。

cat /etc/pam.d/passwd
#%PAM-1.0
auth       include	system-auth
account    include	system-auth
password   substack	system-auth
-password   optional	pam_gnome_keyring.so use_authtok
password   substack	postlogin
验证类别	   控制标准   PAM模块与该模块的参数
字段在P453-454页解释。验证的类型通常是有顺序的。

Linux主机上的用户信息传递

13.6.1 查询用户:w、who、last、lastlog

w或who 查询目前登录在系统上的主机
lastlog 查询每个账号最近登录的时间,即读取/var/log/lastlog

13.6.2 用户对谈:write、mesg、wall

write 使用者账号 [使用者所在的终端界面]
这些信息会立刻中断他人原本的任务。
mesg n  #不接受他人的消息
mesg y  #接受他人的消息
wall “话”  #广播消息

13.6.3 用户邮箱:mail

mail -s "nice to meet you" vbird1
结束以【.】结束。
标题为“nice to meet you”
可以用mail -s "nice to meet you" vbird1 < filename
先将邮件编辑好。

mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/eeqyang": 1 message 1 new
>N  1 yang                  Thu Apr 16 15:29  45/2215  "mylife"
& 

接受邮件:输入【mail】查看输入【?】
> 代表目前处理的邮件,N代表尚未读过。R阅读。
h列出邮件标头【h 40】
d删除后续接的邮件号码【d10】删除单封,或【d20-40】删除20-40封。
s将邮件存储为文件【s 5 ~/mail.file】
x【不做任何操作退出mail程序】不保存任何刚刚的操作
q【退出】

13.7 CentOS 7环境下大量创建账号的方法

使用shell脚本。

13.7.1 一些账号相关的检查工具

pwck 检查/etc/passwd这个账号配置文件内的信息,检查实际的家目录是否存在,还可以比对/etc/passwd与/etc/shadow的信息是否一致。如果有误,会提醒更改。
pwconv:若没有/etc/shadow所对应的密码,读取/etc/login.defs相关数据,建立该账号的/etc/shadow
/etc/passwd若存在密码,则将其转移到/etc/shadow,并将原本的密码栏变为x。
pwunconv:将/etc/shadow的密码返回到/etc/passwd,最好不要使用这个命令
chpasswd:读入未加密的密码,并将加密后密码写入/etc/shadow
现在passwd已经内置--stdin,可以不使用chpasswd
echo "vbird3:abcdefg"|chpasswd

13.7.2大量创建账号模板(适用passwd --stdin选项)

P461-462


第21章 软件安装:源代码与Tarball

除了每个主程序与子程序均需要写上一条编译过程的命令外,还需要写上最终的链接程序。通过make命令简化编译过程。当执行make时,make会在当前的目录下查询Makefile这个文本文件,而makefile里则记录了源代码如何编译的详细信息。make会自动地判别源代码是否经过变动了,而自动更新执行文件。

Makefile怎么写?通常软件开发商都会写一个检测程序来检测用户的操作环境,以及该操作环境是否有软件开发商所需要的其他功能,该检测程序检测完毕后,就会主动地建立这个Makefile地规则文件,通常这个检测程序的文件名为configure或config。

为什么要检测操作环境呢?不同版本的内核所使用的系统调用可能不相同,而且每个软件所需要依赖的函数库也不相同,同时,软件开发商不会针对Linux开发,而是会针对整个Unix-Like做开发,所以也必须要检测该操作系统平台有没有提供合适的编译器才行。

检测程序会检测的内容:

  • 是否有适合的编译器可以编译本软件的程序代码;
  • 是否已存在本软件所需要的函数库,或其他需要的依赖软件;
  • 操作系统平台是否适合本软件,包括Linux的内核版本;
  • 内核的头文件header include是否存在(驱动程序必须要的检测)。

什么是Tarball的软件

纯文本文件在网络上其实是很浪费带宽的一种文本格式,通常要打包,用到Tarball。

Tarball将软件的所有源代码先以tar打包,然后再以压缩技术来压缩。一般有tar.gz,tar.bz2.tar.xz。所以说Tarball是一个软件包,将它解压缩后有:

  • 源代码文件;
  • 检测程序文件(可能是configure或config等文件)
  • 本软件的简易说明与安装说明(INSTALL或README)

需要gcc和make软件。

21.2 使用传统程序语言进行编译的简单范例

vim hello.c
gcc hello.c
若gcc不加上任何参数,则执行文件的文件名会被自动设置为a.out
gcc -c hello.c #输出hello.o目标文件。
gcc -o hello hello.o 	#产生hello的可执行文件

21.2.2 主、子程序链接:子程序的编译

以thanks.c这个主程序去调用thanks_2.c这个子程序。

vim thanks.c
vim thanks_2.c
gcc -c thanks.c thanks_2.c
gcc -o thanks thanks.o thanks_2.o
链接成功。thanks_2.c中没有main函数。
制作出目标文件的意义:有时候源代码文件并非仅有一个文件,所以我们无法直接编译。这个时候需要先产生目标文件,然后再以链接制作成为二进制可执行文件。另外,如果有一天,更新了thanks_2.c这个文件的内容,则你只要重新编译thanks_2.c来产生新的thanks_2.o即可,然后再以链接制作出新的二进制可执行文件即可,而不必重新编译其他没有修改过的源代码。

若想再编译的过程加入适当参数,使得程序再执行的时候具有比较好的性能
gcc -O -c thanks.c thanks_2.c
gcc -Wall -c thanks.c thanks_2.c
#使用-Wall参数会产生更详细的编译过程信息,上面的信息为警告信息所以不用理会也没关系。

21.2.3 调用外部函数库:加入链接的函数库

新版的gcc会主动帮你将所需要的函数库放进来编译,所以不会出现怪异信息。
若要自己加入,例如数学函数库使用的是libm.so这个函数库,你最好再编译的时候将这个函数库包含进去
另外,这个函数库放置的地方是系统默认的/lib与/lib64,所以你无需使用下面的-L去加入查找的目录。
而libm.so在编译的写法上,使用的是-lm(lib的简写)。因此就变成:
gcc sin.c -lm -L/lib -L/lib64
  • -l:是【加入某个数据库library】的意思
  • m:则是libm.so这个函数库,其中,lib与扩展名(.a或.so)不需要写。
  • -L:我要的函数库请到某个路径寻找
  • -I:-I/path后面接的路径就是设置要去查找相关的include文件的目录。

用make进行宏编译

将编译过程模块化。

1. 先编辑makefile这个规则文件,内容只要有main这个执行文件
vim makefile
main: main.o haha.o sin_value.o cos_value.o
		gcc -o main.o haha.o sin_value.o cos_value.o -lm
#注意:第二行的gcc之前用产生空格。
2. 尝试使用makefile制定的规则进行编译操作。
rm -f main *.o
make
#此时make会去读取makefile的内容,并根据内容直接去给它编译相关的文件。
3. 在不删除任何文件的情况下,重新执行一次编译。
make
make:`make' is up to date.
#只会进行更新操作而已。

makefile的基本语法与变量

基本的makefile规则:
目标(target):目标文件1 目标文件2
			gcc -o 欲建立的执行文件 目标文件1 目标文件2
必须作为开头

makefile当中#代表注释;
需要在命令行(例如gcc这个编译器命令)的第一个字符;
目标(target)与依赖文件(就是目标文件)之间需以【:】隔开。

如果想要两个以上的操作时,例如执行一个命令就直接清楚掉所有的目标文件和执行文件
vim makefile
main: main.o haha.o sin_value.o cos_value.o
		gcc -o main.o haha.o sin_value.o cos_value.o -lm
clean:
		rm -f main main.o haha.o sin_value.o cos_value.o
make clean #通过make以clean为目标。

可以利用【变量】来简化makefile:
vim makefile
LIBS=-lm
OBJS=main.o haha.o sin_value.o cos_value.o
main:${OBJS}
		gcc -o main ${OBJS} ${LIBS}
clean:
		rm -f main ${OBJS}

gcc会主动读取CFLAGS这个环境变量,可以直接在shell里定义变量。
CFLAGS="-Wall" make clean main
vim makefile
LIBS=-lm
OBJS=main.o haha.o sin_value.o cos_value.o
CFLAGS=-Wall
main:${OBJS}
		gcc -o main ${OBJS} ${LIBS}
clean:
		rm -f main ${OBJS}
环境变量使用的规则:make后加的最优先;makefile里的第二;shell环境变量里的第三。
同时,
【$@】:代表目前的目标(target)
gcc -o $@ ${OBJS} ${LIBS}

Tarball的管理和建议

1. 获取原始文件
2. 获取步骤流程:README\INSTALL等相关文件
3. 依赖属性软件安装
4. 建立makefile,以自动检测程序(configure或config)检测操作系统,并建立makefile这个文件
5. 用make这个程序,并使用该目录下的makefile作为它的参数配置文件,来进行make(编译或其他)的操作。
6. 安装:以make这个程序,并以makefile这个参数配置文件,根据install这个目标(target)的指定来安装到正确的路径。

1. ./configure:建立makefile
2. make clean
3. make:执行文件和源代码以及makefile还在本目录下
4. make install:将上一步的内容安装到预定的目录中。
5. 如果安装成功,必须手动将这个软件的man page 写入/etc/man_db.conf中。

一般Tarball软件安装的建议事项(如何删除?如何升级?)

  • 最好将Tarball的原始数据解压缩到/usr/local/src当中;
  • 安装时,最好安装到/usr/local这个默认路径下
  • 考虑未来的反安装步骤,最好可以将每个软件单独安装在/usr/loacal下面;
  • 为安装到单独目录的软件的man page加入man path查找

如果你安装的软件放置到 /usr/local/software/ ,那么在man page查找的设置中,可能就要在/etc/man_db.conf内的40-50行左右,写下如下一行:
MANPATH_MAP /usr/local/software/bin /usr/local/software/man
但现在除了专属软件,一般很少用Tarball了。


21.4.4 一个简单的范例

cd /usr/local/src
tar -zxvf /rot/ntp-4.2.8p3.tar.gz
./configure --help | more #查询可用的参数有哪些
./configure --prefix=/usr/local/ntp \
> --enable-all-clocks --enable-parse-clocks #开始建立makefiles
--prefix后面接的就是【这个软件未来要安装的路径】
其他参数就是看help的解释了。
特别留意关于gcc的检查,且最后一定要成功创建Makefile才行。
make clean;make
make check
make install
#将其安装到/usr/local/ntp

21.4.5 利用patch更新源代码

利用diff的比对文件命令,将【两个文件之间的差异性列出来】。修改源文件即可。
vim ~/main_0.1_to_0.2.patch
diff -Naur main-0.1/cos_value.c main-0.2/cos value.c
--- main-0.1/cos_value.c 
+++ mian-0.2/cos_value.c
……省略
patch -p 数字 < patch file
是与patch_file里面列出的文件名相关,数据即代表拿掉几个【/】。
patch -p1 < ../main_0.1_to_0.2.patch
make clean main
./main
make install
main
make uninstall
更新了源代码并非软件也完成更新,还要将该软件编译后,才会是最终正确的软件,因为patch的功能主要是更新源代码而已。

21.5函数库管理

函数库又依照是否被编译到程序内部而分为动态与静态函数库。

动态与静态函数库
静态函数库
  • 扩展名:libxxx.a
  • 编译操作:直接整合到执行程序中,利用静态函数库编译成的文件会比较大一些。
  • 编译成功后的可执行文件可以独立运行,而不需要再向外部要求读取函数库的内容。
  • 若函数库升级,整个执行文件必须要重新编译才行。
动态函数库
  • 动态函数库在编译的时候,在程序里面只有一个【指针】的位置而已。也就是说,动态函数库的内容并没有被整合到执行文件当中,而是当执行文件要使用到函数库的功能时,程序才会去读取函数库来使用。
  • 编译出来的程序不能被独立执行,动态函数库【必须存在】,而且,函数库的【所在目录也不能改变】
  • 当函数库升级的时候,执行文件根本不需要重新编译的操作。

绝大多数的函数库放置在/lib64和/lib目录中。内核的函数库在/lib/modules里面。不同版本的内核提供的函数库差异性是挺大的,所以kernel2.4.xx版本的系统不要想将内核换成2.6.xx,很容易由于函数库的不同而导致很多原本可以执行的软件无法运行。

ldconfg与/etc/ld.so.conf

如果我们将常用到的动态函数库先加载到内存当中(缓存,cache),如此一来,当软件要使用动态函数库时,就不需要从头由硬盘里读出,这样不就可以提高动态函数库的读取速度。需要ldconfig和/etc/ld.so.conf的协助。
如何将动态函数库加载到高速缓存?

  1. 首先,我们必须要在/etc/ld.so.conf里面写入【想要读入高速缓存当中的动态函数库所在的目录】,注意,是目录而不是文件。

  2. 接下来则是利用ldconfig这个执行文件将/etc/ld.so.conf的数据读入缓存当中;

  3. 同时也将数据记录一份至/etc/ld.so.cache这个文件当中。

     ldconfig [-f conf] [-C chache]
     ldconfig [-p]
     范例一:假设我的MariaDB数据库函数库在/usr/lib64/mysql当中,如何读进cache
     vim /etc/ld.so.conf.d/vbird.conf
     /usr/lib64/mysql #新增一行
     ldconfig #不会显示任何信息
     ldconfig -p #列出目前所有函数库数据内容(在/etc/ld.so.cache内的数据)
     # 函数库名称 -> 该函数库实际路径
     可以自行在/etc/ld.so.conf.d/yourfile.conf再执行ldconfig就可以加载缓存
    

21.5.3 程序的动态函数库解析:ldd

判断二进制文件是否含有动态函数库
ldd [-vdr] [filename]
-v:列出所有信息,增加显示其他版本
-d:重新将数据有遗失的链接点显示出来
-r:将ELF有关的错误内容显示出来。
范例一:找出/usr/bin/passwd这个文件的函数库信息
ldd /usr/bin/passwd
范例二:找出/lib64/libc.so.6这个函数的相关函数库
ldd -v /lib64/libc.so.6
校验软件正确性
md5sum sha1sum sha256sum
md5sum/sha1sum/sha256sum [-bct] filename
md5sum/sha1sum/sha256sum [--status|--warn] --check filename
-b:使用二进制文件的读取方式,默认使用windows/dos文件格式的读取方式
-c:检验文件校验值
-t:以文本的方式来读取文件校验值
范例一:将下载的文件测试看看校验值
md5sum ntp-4.2.8p3.tar.gz
可以为系统内一些重要的文件查询md5并保存下来,写一个脚本每次打开shell进行比对,系统会更安全。

你可能感兴趣的:(Linux学习笔记--鸟哥的Linux私房菜(全))