从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_运维

第二章 配置文件

每个 Linux 程序都是一个可执行文件,几乎每个程序的行为都可以通过修改其配置文件来按照你的偏好或需求去定制,所以修改配置文件是使用 Linux 的重中之重。

Linux中 一切皆文件。


CentOS 网络配置
####################################

在 RHEL 或者 CentOS 等 Redhat 系的系统中,跟网络有关的配置文件如下:

  • /etc/host.conf 配置域名服务客户端的控制文件
  • /etc/hosts 完成主机名映射为IP地址的功能
  • /etc/resolv.conf 域名服务客户端的配置文件,用于指定域名服务器的位置
  • /etc/sysconfig/network 包含了主机最基本的网络信息,用于系统启动
  • /etc/sysconfig/network-script/ 系统启动时初始化网络的一些信息
  • /etc/xinetd.conf 定义了由超级进程 xinetd 启动的网络服务
  • /etc/networks 完成域名与网络地址的映射
  • /etc/protocols 设定了主机使用的协议以及各个协议的协议号
  • /etc/services 设定主机的不同端口的网络服务

[Linux]# vi /etc/sysconfig/network-scripts/eth0

网络故障排除思路


  1. 检查硬件,网口灯是否亮起,网线是否畅通
  2. 检查配置文件是否有错误,书写及语法错误等
  3. 检查本机网络协议是否正确: ping 127.0.0.1
  4. 检查本机网卡链路是否正确: ping 本机IP地址
  5. 检查网关是否正确: ping 网关IP地址
  6. 检查外部连通性: ping www.baidu.com

开机自动挂载硬盘
####################################

每次 Linux 系统启动时都会加载 /etc/fstab/etc/mtab 两个配置文件,用于自动挂载硬盘。想要开机自动挂载额外的硬盘,只需在配置文件中加入相关信息。

在开始修改配置文件前,需要注意一些限制条件:

  • 根目录 / 是必须挂载的﹐而且一定要先于其它硬盘
  • 其它 mount point 必须是已建立的目录,可任意指定,但要遵守系统目录架构原则 (FHS)
  • 所有 mount point 在同一时间之内﹐只能挂载一次。
  • 所有 partition 在同一时间之内﹐只能挂载一次。

先看一个 /etc/fstab 的例子:

[Linux]$ cat /etc/fstab
# Device                              Mount point  filesystem parameters    dump fsck
/dev/mapper/centos-root                   /       xfs     defaults            0 0
UUID=94ac5f77-cb8a-495e-a65b-2ef7442b837c /boot   xfs     defaults            0 0
/dev/mapper/centos-home                   /home   xfs     defaults            0 0
/dev/mapper/centos-swap                   swap    swap    defaults            0 0
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

文件格式


配置文件分为六列, 分别代表六种信息:

[硬件名/UUID等]  [挂载点]  [文件系统]  [文件系统参数]  [dump]  [fsck]
  • 1.

第一栏:磁盘文件名

这个字段可以填写的数据主要有三种:

  • 磁盘设备的文件名,如 /dev/sda1
  • 磁盘设备的 :doc:UUID <../Chapter03/00_uuid> 名称,如 UUID=xxx
  • 磁盘设备的 LABEL 名称,例如 LABEL=xxx

每个文件系统都支持上面三种格式,所以喜欢哪项就填哪项,无所谓的!

第二栏:挂载点

挂载文件的目录

第三栏:磁盘分区的格式

指定分区的格式,包括 xfs, ext4, vfat, reiserfs, nfs 等。

第四栏:文件系统参数

一般使用 defaults 即可,详细信息如下:

================ ======================
参数 内容意义
================ ======================
async/sync 异步/同步,磁盘是否以异步方式运作,预设为 async
auto/noauto 自动/非自动,文件系统是否被主动测试,预设为 auto。
rw/ro 读写/只读,分区以可读写或只读的方式挂载
exec/noexec 可执行/不可执行,默认不设置此参数
user/nouser 允许/不允许挂载,是否允许普通用户 mount 挂载磁盘。一般为 nouser
suid/nosuid 具有/不具有 suid,如果不存放执行命令,可以设定为 nosuid
defaults 同时具有 rw, suid, dev, exec, auto, nouser, async 等参数
================ ======================

第五栏:能否支持 dump 备份

dump 是一个用来做为备份的命令,不过现在有太多的备份方案了,所以可以不用理会这个项目,直接输入 0。

第六栏:是否以 fsck 检验扇区

早期开机的流程中,会检验本机的文件系统是否完整。 这种方式主要是通过 fsck 来实现,现在的 xfs 文件系统具有自动检验功能,不适用此方法,直接输入 0。

小技巧


当编辑 /etc/fstab 配置文件时输入的数据错误,会导致系统无法正常开机。可以进入单人维护模式去重新修改配置文件然后重启。如果 / 目录是 read only 状态无法保存修改,则需要重新挂载并修改权限:

[Linux]# mount -n -o remount,rw /
  • 1.

CentOS 设置网口静态 IP
####################################

手动修改配置文件 ,设置对应网口的 IP 等信息。配置文件路径 /etc/sysconfig/network-scripts/*

最小设置示例


# 文件名对应网口名,CentOS 8 默认配置文件
[Linux]# vi /etc/sysconfig/network-scripts/ifcfg-eth0


DEVICE="eth0"
BOOTPROTO="static"
BROADCAST="192.168.0.255"
HWADDR="00:16:36:1B:BB:74"
IPADDR="192.168.0.100"
NETMASK="255.255.255.0"
ONBOOT="yes"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

参数简要解释:

  • DEVICE 网卡的设备别名(默认即可,不建议修改)
  • BOOTPROTO 获得 ip 地址的方式,常见的参数:Static(静态 ip)、dhcp(通过 dhcp 获取 ip)、bootip(通过 bootp 获取 ip)
  • BROADCAST 广播地址
  • HWADDR 网卡物理地址(MAC 地址,不建议修改)
  • IPADDR 静态 IP 地址
  • NETMASK 子网掩码
  • ONBOOT 系统启动时是否激活网口

设置完成后需要重启网络服务才能生效:

# CentOS 7
[Linux]# service network restart
或
[Linux]# systemctl restart network.service

# CentOS 8
[Linux]# nmcli c reload
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

其它配置说明:

- TYPE=Ethernet    网卡类型:为以太网
- PROXY_METHOD=none    代理方式:关闭状态
- BROWSER_ONLY=no    只是浏览器:否
- BOOTPROTO=dhcp    网卡的引导协议
- DEFROUTE=yes    默认路由
- IPV4_FAILURE_FATAL=no     是否开启致命错误检测
- IPV6INIT=yes    IPV6 是否自动初始化
- IPV6_AUTOCONF=yes     IPV6 是否自动配置
- IPV6_DEFROUTE=yes    IPV6 是否可以为默认路由
- IPV6_FAILURE_FATAL=no    IPV6 是否开启致命错误检测
- IPV6_ADDR_GEN_MODE=stable-privacy    IPV6 地址生成模型
- NAME=etho    网络接口名称,即配置文件名后半部分。
- UUID=f47bde51-fa78-4f79-b68f-d5dd90cfc698    通用唯一识别码
- PREFIX=24    子网掩码
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

修改网关


[Linux]# vi /etc/sysconfig/network

NETWORKING=yes
HOSTNAME=localhost.localdomain
GATEWAY=192.168.191.2 #网关地址
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

查看网关命令(二选一)

# GATEWAY 列为网关
[Linux]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.120.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.0.0     192.168.120.1   255.255.0.0     UG    0      0        0 eth0
10.0.0.0        192.168.120.1   255.0.0.0       UG    0      0        0 eth0
0.0.0.0         192.168.120.240 0.0.0.0         UG    0      0        0 eth0


# link src 后为网关
[Linux]# ip route show
default via 192.168.1.1 dev wlp82s0 proto dhcp metric 600 
169.254.0.0/16 dev wlp82s0 scope link metric 1000 
172.16.40.0/24 dev vmnet1 proto kernel scope link src 172.16.40.1 
172.16.51.0/24 dev vmnet8 proto kernel scope link src 172.16.51.1 
192.168.1.0/24 dev wlp82s0 proto kernel scope link src 192.168.1.108 metric 600
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

OpenSSH 服务
####################################

SSH 为 Secure Shell 的缩写,简单地说,SSH 是建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。

OpenSSH 是这种协议的开源实现或实体,OpenSSH 分为客户端 openssh-client 与服务端 openssh-server。在很多 Linux 发行版中,客户端是默认安装的,所以只需要安装服务端,安装完成后默认启动。

apt install openssh-server
  • 1.

配置文件


OpenSSH 的配置文件在 /etc/ssh 目录 ,此外还有一些安装时生成的密钥。

  • /etc/ssh/sshd_config:主配置文件
  • /etc/ssh/ssh_host_ecdsa_key:ECDSA 私钥。
  • /etc/ssh/ssh_host_ecdsa_key.pub:ECDSA 公钥。
  • /etc/ssh/ssh_host_key:用于 SSH 1 协议版本的 RSA 私钥。
  • /etc/ssh/ssh_host_key.pub:用于 SSH 1 协议版本的 RSA 公钥。
  • /etc/ssh/ssh_host_rsa_key:用于 SSH 2 协议版本的 RSA 私钥。
  • /etc/ssh/ssh_host_rsa_key.pub:用于 SSH 2 协议版本的 RSA 公钥。
  • /etc/pam.d/sshd:PAM 配置文件。

… attention

如果重装 sshd,密钥会全部重新生成,导致客户端重新连接服务器时跳出警告,拒绝连接。为了避免这种情况,可以在重装 sshd 时,先备份 ``/etc/ssh`` 目录,重装后再恢复这个目录。

用户使用 ssh-keygen 生成的密钥文件存放在 ``~/.ssh/`` 目录下,文件权限如下:



    [Linux]$ ls -l ~/.ssh
    total 12
    -rw------- 1 glenn glenn 1823 Nov 13 10:24 id_rsa
    -rw-r--r-- 1 glenn glenn  400 Nov 13 10:24 id_rsa.pub
    -rw-r--r-- 1 glenn glenn 1106 Nov 13 21:09 known_hosts

    [Linux]$ ls -la ~ | grep ssh
    drwx------  2 glenn glenn  4096 Nov 13 10:28 .ssh
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

主配置文件:

# 监听的端口号,默认 22 端口
Port 22
# 监听地址,默认监听所有
ListenAddress 
ListenAddress 0.0.0.0
# 支持的 SSH 协议版本号。2 表示仅支持 SSH-2,2,1 表示同时支持 SSH-1 和 SSH-2
Protocol 2,1
# HostKey 是主机私钥文件存放的位置
# 一台主机可以拥有多个不同的私钥。rsa1 仅用于 SSH-1,dsa 和 rsa 仅用于 SSH-2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# 创建非特权子进程来处理接入请求,有效防止有缺陷的子进程提升权限,加强系统安全
UsePrivilegeSeparation yes
# 在 SSH-1 协议下,服务器密钥重新生成的时间周期。0 表示永不重新生成;默认 3600(秒)
KeyRegenerationInterval 3600
# 服务器密钥的位数
ServerKeyBits 1024
# 日志消息发送的方式,有效值 DAEMON、USER、AUTH、LOCAL0~7
SyslogFacility AUTH
# 日志等级(详细程度)。可用值 QUIET、FATAL、ERROR、INFO、VERBOSE、DEBUG1~3
LogLevel INFO
# 用户完成认证的时限。0 表示无限制;默认值是 120(秒)
LoginGraceTime 120
# 是否允许 root 登录
PermitRootLogin yes
# 是否在接受连接前对用户主目录和相关的配置文件进行权限检查。强烈建议使用默认值 yes
StrictModes yes
# 是否允许使用纯 RSA 公钥认证,仅用于 SSH-1
RSAAuthentication yes
# 是否允许公钥认证,仅用于 SSH-2
PubkeyAuthentication yes
# 是否取消使用 ~/.ssh/.rhosts 来做为认证,推荐设为 yes
IgnoreRhosts yes
# 专门用于 version 1 进行认证,推荐设为 no
RhostsRSAAuthentication no
# 这个与上面的项目类似,不过用于 version 2
HostbasedAuthentication no
# 是否在 RhostsRSA 或 Hostbased 身份验证过程中忽略 ~/.ssh/known_hosts 文件的配置
IgnoreUserKnownHosts no
# 是否允许密码为空的用户远程登录
PermitEmptyPasswords no
# 是否允许质疑-应答认证。支持所有 login.conf 允许的认证方式
ChallengeResponseAuthentication no
# 是否允许使用密码认证
PasswordAuthentication yes
# 是否要求用户使用 Kerberos 认证
KerberosAuthentication no
# 如果使用了 AFS 且用户有 Kerberos 5 TGT,会在访问用户家目录前尝试获取 AFS  token
KerberosGetAFSToken no
# 如果 Kerberos 密码认证失败,那么还将通过其它的认证机制(如 /etc/passwd)
KerberosOrLocalPasswd yes
# 是否在用户退出登录后自动销毁用户的 ticket
KerberosTicketCleanup yes
# 是否允许使用基于 GSSAPI 的用户认证
GSSAPIAuthentication no
# 是否在用户退出登录后自动销毁用户凭证缓存
GSSAPICleanupCredentials yes
# 是否允许进行 X11 转发
X11Forwarding no
# X11 转发的第一个可用的显示区数字
X11DisplayOffset 10
# 是否在每次交互式登录时打印 /etc/motd 文件的内容
PrintMotd no
# 是否显示最后一位用户的登录时间
PrintLastLog yes
# 是否向客户端发送 TCP keepalive 消息,可用于检测到死连接、客户端崩溃等异常
TCPKeepAlive yes
# 是否在交互式会话的登录过程中使用 login
UseLogin no
# 未认证的连接同时在线的最多个数。默认值是 10
MaxStartups 10
# 每个连接的最多认证次数。默认值是 6
MaxAuthTries 6
# 是否对远程主机名进行反向解析,以检查此主机名是否与其 IP 地址真实对应
UseDNS no
# 在用户认证时显示的内容。none 表示禁用,仅用于 SSH-2
Banner /etc/issue.net
# 配置一个外部子系统(如:一个文件传输守护进程)。仅用于 SSH-2
Subsystem sftp /usr/lib/openssh/sftp-server
# 是否使用 PAM 模块认证
UsePAM yes
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.

应用实例


密钥登录

SSH 默认采用密码登录,这种方法有很多缺点,简单的密码不安全,复杂的密码不容易记忆,每次手动输入也很麻烦。密钥登录是比密码登录更好的解决方案。

密钥是一个非常大的数字,通过加密算法得到。SSH 一般使用非对称加密,分为公钥(public key)和私钥(private key)。其中,私钥必须私密保存,不能泄漏;公钥则是公开的,可以对外发送。它们的关系是,公钥和私钥是一一对应的,每一个私钥都有且仅有一个对应的公钥,反之亦然。

SSH 密钥登录分为三步:

  1. 客户端通过 :ref:ssh-keygen 命令 <cmd_ssh-keygen> 生成公钥和私钥。

会询问一系列问题,一路回车即可

[Linux]$ ssh-keygen -t rsa -b 2048 -C “your_email@domain.com”

  1. 将客户端的公钥上传到远程服务器。

将用户公钥文件 ~/.ssh/id_rsa.pub 保存到服务器中,密钥必须保存在服务器用户主目录的 ~/.ssh/authorized_keys 文件中。每个公钥占据一行,如果该文件不存在,可以手动创建。格式为:

[Linux]$ cat ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvpB4lUbAaEbh9u...
ssh-rsa DydZAKMcDvBJqRhUotQUwqV6HJxqoqPDlPGUUyo8RP...
  • 1.
  • 2.
  • 3.

… attention

authorized_keys 文件的权限为 644,即只有文件所有者才能写。如果权限设置不正确,SSH 服务器可能会拒绝读取该文件。
  • 1.

也可以使用命令自动将公钥上传到远程服务器:

[Linux]$ ssh-copy-id -i ~/.ssh/id_rsa.pub  user@host
  • 1.
  1. 客户端使用密钥登录服务器。
    [Linux]$ ssh user@host

为了安全性,启用密钥登录之后,最好关闭服务器的密码登录。在主配置文件中加入 PasswordAuthentication no

root 登录

一般情况下默认的配置已经很好,不需要自主配置。但有时需要增加 root 登录的权限,可以直接在文件末尾添加配置:

# vim /etc/ssh/sshd_config
PermitRootLogin yes

# 重启 OpenSSH 服务
[Linux]# systemctl restart sshd
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

yum 源配置文件
####################################

yum 源一般存放在 /etc/yum.repos.d/ 目录中,文件已 .repo 结尾。

Yum 源镜像中心提供了 centosplus, cloud, extras, fasttrack, os, updates 等软件库,最好认的软件库就是 os (系统默认的软件) 与 updates (软件升级版本) 啰!最重要的文件就是那个 “repodata” 的目录!该目录就是分析 RPM 软件后所产生的软件属性相依数据放置处!因此,当你要找软件库所在网址时, 最重要的就是该网址底下一定要有个名为 repodata 的目录存在!那就是软件库的网址了!

[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
pkgpolicy=newest
distroverpkg=redhat-release
tolerant=1
exactarch=1
retries=1

[base]
name=Fedora Core $releasever - $basearch - Base
baseurl=http://download.atrpms.net/mirrors/fedoracore/$releasever/$basearch/os
http://rpmfind.net/linux/fedora/cor...er/$basearch/os
http://mirror.clarkson.edu/pub/dist...er/$basearch/os

[updates-released]
name=Fedora Core $releasever - $basearch - Released Updates
baseurl=http://download.atrpms.net/mirrors/fedoracore/updates/$releasever/$basearch
http://redhat.linux.ee/pub/fedora/l...sever/$basearch
http://fr2.rpmfind.net/linux/fedora...sever/$basearch

... 中间省略 ...

[freshrpms]
name=FreshRPMs
baseurl=http://ayo.freshrpms.net/fedora/linux/$releasever/$basearch/freshrpms/
http://ftp.us2.freshrpms.net/linux/...arch/freshrpms/
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

第一部分(全局性设置,一般不必改动。)


[main]

cachedir: yum 缓存的目录,存储下载的 rpm 包和数据库,一般是 /var/cache/yum

debuglevel: 除错级别,0-10,默认是2。

logfile: yum 的日志文件,默认是 /var/log/yum.log

pkgpolicy: 选择安装软件包的策略。一共有两个选项,newest和last(如果你设置了多个 repository,同一软件在不同的 repository 中同时存在。yum 应该安装哪一个,如果是 newest,则 yum 会安装最新的那个版本。如果是 last,则 yum 会将服务器 id 以字母表排序,并选择最后的那个服务器上的软件安装。默认为 newest。

distroverpkg: 指定一个软件包,yum 会根据这个包判断你的发行版本,默认是 redhat-release,也可以是安装的任何针对自己发行版的 rpm 包。

exactarch: 有两个选项1和0(1代表只升级和你安装软件包 cpu 体系一致的包,例如:你安装了一个i386的 rpm,则 yum 不会用1686的包来升级这个包)。

retries: 网络连接发生错误后的重试次数(如果设为0,则会无限重试)。

tolerent: 有1和0两个选项,表示 yum 是否提示与软件包有关的错误,(1代表 yum 不会提示错误信息,默认是0)。

除了上述之外,还有一些可以添加的选项,如

exclude=,排除某些软件在升级名单之外,可以用通配符,列表中各个项目要用空格隔开,这个对于安装了诸如美化包,中文补丁的朋友特别有用。

gpgchkeck= 有 1 和 0 两个选择,分别代表是否是否进行gpg校验,如果没有这一项,默认好像也是检查的。

第二部分(个性化配置)


配置 repository 服务器了,这是最令人激动的。有了好的 repository,就如家门口开了大卖场,要什么东西稍微跑跑腿就行,对了这还是个免费的大卖场。所有服务器设置都应该遵循如下格式:

[base]: 代表软件库的名字!中括号一定要存在,里面的名称则可以随意取。但是不能有两个相同的软件库名称, 否则 yum 会不晓得该到哪里去找软件库相关软件列表档案。

name: 只是说明一下这个软件库的意义而已,重要性不高!

mirrorlist=: 列出这个软件库可以使用的映射站台,如果不想使用,可以注释掉这行;

baseurl=: 这个最重要,因为后面接的就是软件库的实际网址! mirrorlist 是由 yum 程序自行去捉映像站台, baseurl 则是指定固定的一个软件库网址!我们刚刚找到的网址放到这里来啦!

enable=1: 就是让这个软件库被启动。如果不想启动可以使用 enable=0 喔!

gpgcheck=1: 还记得 RPM 的数字签名吗?这就是指定是否需要查阅 RPM 档案内的数字签名!

gpgkey=: 就是数字签名的公钥文件所在位置!使用默认值即可

几个变量

$releasever,发行版的版本,从[main]部分的distroverpkg获取,如果没有,则根据redhat-release包进行判断。

$arch,cpu体系,如i686,athlon等

$basearch,cpu的基本体系组,如i686和athlon同属i386,alpha和alphaev6同属alpha。

CentOS下安装yum


在Linux里面依次输入下面的命令:

  1. 下载最新的 yum-3.2.28.tar.gz 并解压
    wget http://yum.baseurl.org/download/3.2/yum-3.2.28.tar.gz
    tar xvf yum-3.2.28.tar.gz
  2. 进入目录,运行安装
    cd yum-3.2.28/
    ./yummain.py install yum

如果结果提示错误: CRITICAL:yum.cli:Config Error: Error accessing file for config file:///etc/

可能是原来是缺少配置文件。在 etc 目录下面新建 yum.conf 文件,然后再次运行 yummain.py install yum,顺利完成安装。

3,最后更新系统。

yum check-update  
yum update  
yum clean all
  • 1.
  • 2.
  • 3.

定制 shell 提示符
####################################

PS(Prompt Sign)是指命令提示符,在 Linux 环境下 $PS1 是终端提示符,我们可以用预设的一些特殊符号来改变 $PS1 变量。首先,先看一下 $PS1 到变量,本例以 Ubuntu 18 为准:

[Linux]$ echo $PS1
\[\e]0;\u@\h:\w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\
[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
  • 1.
  • 2.
  • 3.

PS1 变量中各项提示符的含义:

  • \d: 日期
  • \H: 完整的主机名称
  • \h: 仅取主机的第一个名字
  • \t: 显示时间为 24 小时格式,如:HH:MM:SS
  • \T: 显示时间为 12 小时格式
  • \A: 显示时间为 24 小时格式:HH:MM
  • \u: 当前用户的账号名称
  • \v: BASH 的版本信息
  • \w: 完整的工作路径名
  • \W: 最后一个路径名
  • \#: 下达的第几个命令
  • \$: 提示字符,root 用户为 # ,普通用户为 $

同时可以通过 PS1 变量设置提示符的颜色,在 PS1 中设置字符序列颜色的格式为: \[\e[F;Bm\] 其中“F”为字体颜色,编号3037;“B”为背景色,编号4047。取消设置: \[\e[0m\]

每种字体颜色对应的代码:

  • 0=重置
  • 30=黑色
  • 31=红色
  • 32=绿色
  • 33=黄色
  • 34=蓝色
  • 35=洋红
  • 36=青色
  • 37=白色

背景颜色对应的代码:

  • 0=重置
  • 40=黑色
  • 41=红色
  • 42=绿色
  • 43=黄色
  • 44=蓝色
  • 45=洋红
  • 46=青色
  • 47=白色
  • 01=高亮显示(常用)
  • 04=underline
  • 07=反白显示
  • 08=不可见

在修改提示符时,可以先临时修改,以查看效果。等满意之后在写入配置文件 ~/.bashrc 中,使效果永久生效。

PS1 在赋值的时因为值中包含空格所以需要用单引号 ``'`` 把值包起来,同时需要注意,变量与值以等号连结,而且等号两边不能直接接空格



gavin@gavin-ubuntu:~$ PS1='\[\H\]\$ '
gavin-ubuntu$ PS1='\[\H@\u\]\$ '
gavin-ubuntu@gavin$ PS1='\[\w\]\$ '
~$ cd Documents/
~/Documents$ PS1='[\u@\h \w \A #\#]\$ '
[gavin@gavin-ubuntu ~/Documents 21:17 #6]$ PS1='\u@\W\$ '

# 个人默认的修改,带颜色版本
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ '
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

wpa_supplicant 终端连接 wifi
####################################

为了管理无线网卡驱动,并且能正常连接到无线网络,你需要一个无线连接管理工具。

如何选择一个最佳的管理方法,将依赖于下面几个因素:

  • 是否使用加密及使用加密的类型
  • 是否经常切换不同网络(如笔记本电脑)

下表按照加密和管理方式分类,列出了管理无线网络的工具。
虽然还有其他办法,但这些是最常用的。

===================== ================================ ===============
手动管理方法 无线连接管理 分配 IP 地址
===================== ================================ ===============
无加密或 WEP 加密 iw/iwconfig ip/dhcpcd/dhclient/networkd
WPA 或 WPA2 PSK 加密 iw/iwconfig + wpa_supplicant ip/dhcpcd/dhclient
===================== ================================ ===============

================= ==================
自动管理方法 工具
================= ==================
支持所以网络配置 netctl、Wicd、NetworkManager 等等
这些工具会自动安装手动配置需要的工具。
================= ==================

wpa_supplicant 最小配置


现在大部分无线网络使用 WPA/WPA2 加密,最少需要配置 wpa_supplicant 才能连接网络。另外,wpa_supplicant 目前只能连接到已经配置好 ESSID 的无线网络。

其实 wpa_supplicant 还有一个前端工具 wpa_cli。wpa_supplicant 和 wpa_cli 的关系就像服务和客户端的关系,后台运行 wpa_supplicant,使用 wpa_cli 来搜索、设置、和连接网络。不过 wpa_cli 并不是必须的软件。
  • 1.

在 Debian 环境中,需要在 /etc/network/interfaces 中配置 wpa_supplicant 的配置文件路径。

# 开机自动启动网络并使用 dhcp 配置网络 IP
# wlan0 为系统无线网卡名
auto wlp1s0
iface wlp1s0 inet dhcp

# wpa_supplicant 的配置文件路径
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

新建配置文件 /etc/wpa_supplicant/wpa_supplicant.conf ,可以加入一些配置项:

# 可有可无,启用 wpa_cli 关闭 wpa_supplicant
ctrl_interface=/var/run/wpa_supplicant

# 可有可无,只有 root 用户能读取 WPA 配置
ctrl_interface_group=0

# 可有可无,启用 wpa_supplicant 扫描和选择 AP
ap_scan=1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

使用 wpa_supplicant 命令将连接 wifi 的名称和密码添加到配置文件。wpa_supplicant
会将密码转换成密文,如果更改了密码这一步不能单纯的手动修改文件。

[Linux]$ wpa_supplicant wifi名称  wifi密码 >> /etc/wpa_supplicant/wpa_supplicant.conf
  • 1.

如果配置文件中有多个 AP 还可以手动为网络设置优先级参数 priority(0-255 的整数,数值越大级别越高)。

[Linux]$ cat /etc/wpa_supplicant/wpa_supplicant.conf
network={
        ssid="WiFi2021"
        #psk="Xy20210601Xy"
        psk=c92fe5b5f76fa8482e1c131ec4e75a5fc98bebea703493732853dfa1725b058
        priority=2
}
network={
        ssid="glenn"
        #psk="1234@4321"
        psk=9b5b71e27b1976af9aba2b27fc8473ac095e39da62dcf497bea93449dfa9990
        priority=99
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

下面是一个用 WPA supplicant 和 DHCP 连接无线网络的完整示例。

[Linux]$ ip link set dev wlp6s0 up
[Linux]$ wpa_supplicant -B -i wlp6s0 -c /etc/wpa_supplicant/wpa_supplicant.conf
[Linux]$ dhcpcd wlp6s0

要使用静态 IP,请将 dhcpcd 命令替换为:
[Linux]$ ip addr add 192.168.0.10/24 broadcast 192.168.0.255 dev wlp6s0
[Linux]$ ip route add default via 192.168.0.1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

请注意一点,对无线网络的配置是全局性的,而非针对具体的接口。

关于 WPA:


WPA 是 WiFi Protected Access 的缩写,中文含义为“WiFi 网络安全存取”。WPA 是一种基于标准的可互操作的 WLAN 安全性增强解决方案,可大大增强现有以及未来无线局域网络的数据保护和访问控制水平。

wpa_supplicant 是 wifi 客户端(client)加密认证工具,并且是一个开源的项目,已经被移植到 Linux、Windows 以及很多嵌入式系统上。它是 WPA 的应用层认证客户端,负责完成认证相关的登录、加密等工作。

wpa_supplicant 是一个独立运行的守护进程,其核心是一个消息循环,在消息循环中处理 WPA 状态机、控制命令、驱动事件、配置信息等。


修改用户目录默认文件名
####################################

通常,为了方便我会安装 Linux 中文环境,但是此时用户目录也会变成了中文。cd 下载/ 用起来很难受,所以我希望可以将目录名修改为英文或者自定义的名称。

xdg-user-dirs 就是帮助管理用户目录的工具。xdg-user-dirs-update 命令会读取配置文件 /etc/xdg/user-dirs.defaults ,并在 $HOME 下创建一整套默认的经本地化的用户目录。

$ xdg-user-dirs-update
  • 1.

运行该命令后会自动地:

  • 创建一个本地的 ~/.config/user-dirs.dirs 配置文件:应用程序通过它来查找使用特定帐号指定的用户目录。
  • 创建一个本地的 ~/.config/user-dirs.locale 配置文件:根据使用的 locale 指定语言。

本地的 ~/.config/user-dirs.dirs 和全局的 /etc/xdg/user-dirs.defaults 配置文件都使用如下的环境变量格式: XDG_DIRNAME_DIR=“$HOME/目录名”。

下边是一个例子:

~/.config/user-dirs.dirs
------------------------------------------

XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_DOWNLOAD_DIR="$HOME/Download"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_PUBLICSHARE_DIR="$HOME/Publicshare"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_VIDEOS_DIR="$HOME/Videos"

# 中文文件名
XDG_DESKTOP_DIR="$HOME/桌面"
XDG_DOCUMENTS_DIR="$HOME/文档"
XDG_DOWNLOAD_DIR="$HOME/下载"
XDG_MUSIC_DIR="$HOME/音乐"
XDG_PICTURES_DIR="$HOME/图片"
XDG_PUBLICSHARE_DIR="$HOME/公共"
XDG_TEMPLATES_DIR="$HOME/模板"
XDG_VIDEOS_DIR="$HOME/视频"




在把中文文件名修改为英文文件名时,不仅仅需要修改配置文件,还需要把文件夹名称由中文改成对应的英文(或新建英文名文件夹)。否则重启之后配置文件中对应的名称会为空。


    
    mkdir Desktop Documents Download Music Pictures Publicshare Templates Videos
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.

因为 xdg-user-dirs 会参照本地配置文件来了解正确的用户目录,所以可以自定义。若将 ~/.config/user-dirs.dirs 下 XDG_DOWNLOAD_DIR 变量设为了 $HOME/Internet,那么任何参照了该变量的程序都会改用这个目录。

注意: 和其他的配置文件一样,本地设定覆盖全局设定。另外自定义的目录要自己创建。

或者也可以用命令行修改默认目录。下列命令会产生和上面一样的效果:

$ xdg-user-dirs-update --set DOWNLOAD ~/Internet
  • 1.

查询配置好的目录

可以用 xdg-user-dirs 来查询配置好的目录路径。例如,下列命令可以查询模板目录的位置,对应于本地配置文件中 XDG_TEMPLATES_DIR 变量的值:

$ xdg-user-dir TEMPLATES
  • 1.

参考链接:


tty 终端字体
####################################

默认情况下,终端使用内核的内置字体,一般为点阵字体 [1]_ 其包含 CP437 字体集。

Linux 终端默认使用 UTF-8 编码,由于使用的是标准的兼容 VGA 的帧缓存,终端字体限定为 256 或 512 个字形。如果字体超出了256个字形,那么颜色的数量就会从 16 减少到 8。为了正确的显示符号,需要一个特殊的转换图(unimap)将符号和 Unicode 的值对应。现在大多数终端字体都具有内置的 unimap。

kbd 包提供了改变虚拟终端字体的工具。可以使用的字体存储在 ``/usr/share/kbd/consolefonts/`` 目录下(各发行版的存储路径略有不同,CentOS 下路径为 ``/lib/kbd/consolefonts`` ),那些以 ``.psfu`` 或者 ``.psfu.gz`` 结尾的字体具有内置的 Unicode 转换映射,可用于终端字体。

psfu,psfu.gz – 点阵字体。 ``s`` 代表屏幕, ``f`` 代表字体, ``u`` 代表 Unicode, ``gz`` 用 gzip 压缩(不适用于X.Org)。
  • 1.
  • 2.
  • 3.

预览和测试


showconsolefont 命令会以表格形式显示可用字与字符:

$ showconsolefont
  • 1.

setfont 可以暂时改变字体(预览字体效果),只要指定字体名称即可(字体位于 /usr/share/kbd/consolefonts/),比如:

$ setfont lat2-16
  • 1.

如果对新换的字体不满意,可以用 setfont 命令恢复至默认字体(就算终端显示乱码,将命令「盲打」执行依然有效):

$ setfont



setfont 只作用于当前正在使用的终端。其它终端无论活跃与否都不受影响。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

配置文件


systemd-vconsole-setup 是一个用于配置虚拟控制台的辅助程序, 它既可以一次性配置所有虚拟控制台,也可以通过指定 TTY 参数单独配置某个特定的虚拟控制台。在系统启动过程中,初始化虚拟控制台时,它将被 systemd-udevd(8) 调用。 systemd-vconsole-setup.service 服务也会在内部调用该程序。 而该程序也会通过调用 loadkeys(1) 与 setfont(8) 来配置虚拟控制台的键盘映射与字体。

在修改 vconsole.conf 之后,既可以通过直接调用此程序来刷新控制台的设置, 也可以通过 systemctl restart 或 systemctl start 命令来刷新控制台的设置。

/etc/vconsole.confFONT 变量可以用来在启动时设置字体,对于所有终端都有效。如果没用 vconsole.conf 配置文件,手动创建即可。

注意:配置文件的位置各发行版的位置不尽相同,在 Debian 中的配置文件为 /etc/default/console-setup

若要显示 Č, ž, đ, š, Ł, ę, ą, ś 之类的字符,请使用 lat2-16.psfu.gz 这个字体:

/etc/vconsole.conf

...
FONT=lat2-16
  • 1.
  • 2.
  • 3.
  • 4.

这代表使用 ISO/IEC 8859 字符的第二部分,尺寸设置为 16。你可以使用其它值更改字体尺寸(如 lat2-08)。

如果开机时字体没有任何变化,或只变化一下就恢复原样,有可能是因为显卡驱动引导时字体被复位,然后终端被切至帧缓冲 (framebuffer)。提前加载图形驱动可以避免这个问题。

调整控制台字体太小的方法


Linux 系统默认的终端字体大小为 16px,在高分辨率屏幕下的显示效果惨不忍睹。
上边已经提到了,由于点阵字体只能清晰地显示在相应的字号下,所以要改变字体的大小,最好是调整字体。

  1. 下载 terminus 字体,官网链接: http://terminus-font.sourceforge.net/。
  2. 解压文件:
    cd ~/Download
    tar -zxvf terminus-font-4.46.tar.gz
    cd terminus-font-4.46
  3. 安装字体:
    sudo su # 提升权限
    ./configure --psfdir=/usr/share/kbd/consolefonts/
    make -j4 psf # 编译字体
    make install-psf # 安装字体

以下可选

make -j4 psf-vgaw
make install-psf-vgaw

  1. 预览字体效果:
    cd /usr/share/kbd/consolefonts/
    ls

会多出好多 ter-XXXX.psf.gz 的字体文件

预览字体效果

setfont ter-932n.psf.gz

ter-932n.psf.gz 其中 9 是代号,32 代表高度,n 表示 normal,还有 b 表示 bold 等。

点阵字体在处理 ``0 o O 1 l i`` 等字符时十分容易混淆,这里推荐另一款字体:http://www.fial.com/~scott/tamsyn-font/ 或 http://pelulamu.net/unscii/

将 *.psf.gz 文件放在字体目录下,在配置时请使用绝对路径指定字体。
  • 1.
  • 2.
  • 3.

… [1] 点阵字体:每种字形的每种形式和每种尺寸的图像都由点或者像素组成的矩阵构成。由于位图的原故,点阵字体只能清晰地显示在相应的字号下,很难进行缩小和放大。对于太小的字,点阵字体常常比其它类型的字体有更好的显示效果。常见的点阵字体格式有 bdf,pcf,fnt,hbf 等。


登陆管理器
####################################

登录管理器也叫显示管理器(Display Manager),它会提供给用户一个图形化的登录界面。当用户输入正确的用户名和密码时,登录管理器会开始一个会话(窗口管理器或者桌面环境)。 一个图形服务器只能由一个登录管理器来管理,但是系统中可以安装多个登录管理器。

显示管理器列表


控制台

  • CDM_ :控制台显示管理器
  • Console TDM_ :扩展自xinit,由纯粹的Bash脚本编写的
  • nodm_ :支持自动登录的简单显示管理器。

桌面环境

  • GDM_ :GNOME 显示管理器。
  • LightDM_ :跨桌面的显示管理器,可以使用各种前端写的任何工具。
  • LXDM_ :LXDE 显示管理器 (独立于桌面环境) (lxdm)
  • MDM:使用在Linux Mint中的显示管理器,GDM2的分支项目。
  • SDDM_ :基于QML的显示管理器,替代KDE4的KDM,推荐搭配Plamsa5或LXQt使用。
  • XDM_ :X 显示管理器支持XDMCP(适合服务器的宿主机)。
    … _CDM: https://github.com/ghost1227/cdm
    … _Console TDM: http://code.google.com/p/t-display-manager/
    … _nodm: http://enricozini.org/sw/nodm/
    … _GDM: http://projects.gnome.org/gdm/gdm
    … _LightDM: https://www.freedesktop.org/wiki/Software/LightDM/
    … _LXDM: https://en.wikipedia.org/wiki/LXDE
    … _SDDM: https://github.com/sddm/sddmsddm
    … _XDM: http://www.x.org/archive/X11R7.5/doc/man/man1/xdm.1.html

加载显示管理器


以 SDDM 为例,配置开机启动:

# systemctl enable sddm.service
  • 1.

执行上述命令后,登录管理器应当能正常工作了。如果不是的话,可能是 default.target 没有指向 graphical.target。

启用 SDDM 后, /etc/systemd/system/ 应该创建 display-manager.service 软链接,可以用 --force 覆盖已有链接。

$ ls -l /etc/systemd/system/display-manager.service

[...] /etc/systemd/system/display-manager.service -> /usr/lib/systemd/system/sddm.service
  • 1.
  • 2.
  • 3.

LightDM ( Light Display Manager )


LightDM 是一个跨桌面显示管理器,其目的是成为 X org X 服务器的标准显示管理器。我们之所以编写一个新的显示管理器,是因为从 XDM 以来出现了很多新的显示管理器(通常基于 XDM 源代码),但这些项目之间的差别很小,主要是在GUI(比如说不同的开发工具包) 和性能上面的差别。我们想用一个通用的显示管理器来管理它们,并允许各自的差异。

它的特点有:

  • 跨桌面 - 支持不同的桌面环境。
  • 支持多种显示技术(X,Wayland, …)。
  • 轻量级 - 低内存使用,高性能。
  • 支持定制会话。
  • 支持远程登录(XDMCP,VNC,XDMCP,可插拔)。

主要配置文件:

/usr/share/lightdm/lightdm.conf.d/*.conf
/etc/lightdm/lightdm.conf.d/*.conf
/etc/lightdm/lightdm.conf
  • 1.
  • 2.
  • 3.

启用自动登录

编辑 LightDM 配置文件 /etc/lightdm/lightdm.conf ,取消 autologin-user 的注释,并添加要自动登陆的用户名:

autologin-user=username
  • 1.

你必须是 autologin 组的成员才能使用自动登录:

# groupadd autologin
# gpasswd -a username autologin
  • 1.
  • 2.

命令行工具

LightDM 提供一个命令行工具, dm-tool. 它可用来锁定当前 seat, 切换会话,等等。这对’极简’窗口管理器和测试非常有用。要列出可用命令,运行:

$ dm-tool --help
  • 1.

更改背景图片/颜色

如果您想使用一个纯色 (非图片) 的背景,只需将 background 变量设置为十六进制的颜色。

例如:

background=#000000
  • 1.

如果需要在 greeter 上使用自定义图片,请修改 /etc/lightdm/lightdm.conf 中的 background 变量值。例如:

background=/usr/share/pixmaps/black_and_white_photography-wallpaper-1920x1080.jpg
  • 1.

注意: 建议将 PNG 或 JPG 文件放到 /usr/share/pixmaps ,因为 LightDM 用户需要有背景文件的读取权限。

改变你的头像

首先确保已安装 accountsservice 软件包,然后如下设置,把 username 替换为目标用户的登录名。文件名中不要加 .png 后缀:

[User]
Icon=/var/lib/AccountsService/icons/username
  • 1.
  • 2.

注意: 头像格式最好为PNG,确保文件的权限为 644 。


Linux Desktop Entry 文件解析
####################################

在 Windows 平台上,在开始菜单下有一个“所有程序”,我们安装的所有软件都可以在这个列表中找到(见下图)。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_示例_02

现代 Linux 桌面系统也提供了此项功能。目前,KDE 和 GNOME 桌面系统都使用 Desktop Entry 文件标准来描述程序启动配置信息。Desktop Entry 文件标准是由 FreeDesktop.org_ 制定的,目前最新的版本是 Desktop Entry Specification 1.0_ 。

大多数软件在安装时都会加入所有程序列表中以方便访问。然而,如果是你自己从源代码中编译的程序或者自己下载的压缩格式的软件,那它们就不会添加到程序列表中,每次你都需要打开终端来执行它的二进制文件。显然这个过程很无聊也很麻烦,想解决这个问题需要自己建立.desktop文件,并放到相应的目录中。

… _FreeDesktop.org: http://freedesktop.org/wiki/

… _Desktop Entry Specification 1.0: https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html

Desktop Entry 文件


Desktop Entry 文件以 .desktop 为后缀名。以 Linux GNOME 桌面系统为例,用户打开应用程序浏览器后(见下图)会看见很多应用程序快捷方式。事实上,每个应用程序快捷方式都和一个 Desktop Entry 文件相对应。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_运维_03

这些 Desktop Entry 文件通常被存放在 /usr/share/applications/ 或者 ~/.local/share/applications/ 等目录下。从文件浏览器进入这些目录,点击相应的 Desktop Entry 文件同样可以启动相对应的应用程序。

假设当前 /usr/share/applications/ 目录下有一文件 cbt.desktop ,用任意文件编辑软件打开 cbt.desktop ,将看到如下内容:

[Desktop Entry]
Version = 1.0
Encoding = UTF-8
Name = Quick Start Tour
GenericName = User Tutorial
Comment = Computer Based Training tutorial to \
     guide and help you learn how to use the Desktop
Exec =
gnome-open /usr/share/doc/manual/sled-gnome-cbt_en/index.html
Icon = cbt
StartupNotify = true
Terminal = false
Type = Application
Categories = GNOME;Application;Documentation;
OnlyShowIn = GNOME;
X-SuSE-translate = true
Name[cs] = Rychlá prohlídka systému
Comment[cs] = V?ukov? program seznamující u?ivatele
       se základy pracovního prost?edí
GenericName[cs] = U?ivatelsk? tutoriál
Name[hu] = Rendszerbemutató
Comment[hu] = A munkaállomés használatát bemutató segédlet
GenericName[hu] = Felhasználói segédlet
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

本文将在下一节中结合上述 cbt.desktop 文件内容重点解析 Desktop Entry 的文件结构。读者可以从中深入领会上述各条语句的具体含义。

Desktop Entry 文件结构


Desktop Entry 文件通常以字符串 [Desktop Entry] 开始。Desktop Entry 文件的内容是由若干“关键字 = 数值”配对的 Entry 组成的。例如:Version 就是一个关键字,关键字 Version 对应的数值是 1.0 。Desktop Entry 文件标准定义了一系列标准关键字(标准关键字分为必选和可选两种)。以下是对重点关键字的解析:

Version [可选]

指定当前 Desktop Entry 文件所遵循的 Desktop Entry 标准版本。

Encoding [1.0 版本不推荐使用]

指定当前 Desktop Entry 文件中特定字符串所使用的编码方式。尽管 Desktop Entry 文件标准 1.0 不再推荐使用该关键字,但由于历史原因该关键字仍然广泛出现在现有的 Desktop Entry 文件中。

Name [必选]

指定相关应用程序的名称。比如在上边打开的 cbt.desktop 中关键字 “Name” 的数值是 “Quick Start Tour”。进入 /usr/share/applications 目录,就可以看见 cbt.desktop 文件所定义的快捷方式的显示样式(见下图)。当然,这些定义在应用程序浏览器中同样适用。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_实例_04

GenericName [可选]

指定相关应用程序的通用名称。比如在上边打开的 cbt.desktop 中关键字 “GenericName” 的数值是 “User Tutorial”。打开应用程序浏览器,就可以看见字符串 “User Tutorial” 显示在程序名称的下边(见下图)。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_示例_05

Comment [可选]

指定当前 Desktop Entry 的简单描述。

Type [必选]

指定 Desktop Entry 文件的类型。常见的 “Type” 数值是 “Application” 和 “Link”。“Type = Application” 表示当前 Desktop Entry 文件指向了一个应用程序;而 “Type = Link” 表示当前 Desktop Entry 文件指向了一个 URL (Uniform Resource Locator)。

Exec [可选]

关键字 “Exec” 只有在 “Type” 类型是 “Application” 时才有意义。“Exec” 的数值定义了启动指定应用程序所要执行的命令,在此命令是可以带参数的。

URL [可选]

关键字 “URL” 只有在 “Type” 类型是 “Link” 时才有意义。“URL” 的数值定义了该 Desktop Entry 文件指向的 URL。例如:

Type = Link
URL = http://www.ibm.com/developerworks
  • 1.
  • 2.

双击含有上述内容的 Desktop Entry 文件将启动 web 浏览器,并打开指定网页。

Icon [可选]

指定当前 Desktop Entry 文件在应用程序浏览器或是在文件浏览器中所显示的图标。如果关键字 “Icon” 的数值是绝对路径,那么所指定图标文件将被使用;反之,Linux 系统将使用 Icon Theme Specification_ 在系统中指定图标目录下所需要使用的图标文件。比如在上边打开的 “cbt.desktop” 中关键字 “Icon” 的数值是 “cbt”,它实际对应着系统指定图标目录下的图片文件 “cbt.png”。

… _Icon Theme Specification: https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html

StartupNotify [可选]

指定布尔值(true 或是 false)。该关键字只有在 “Type” 类型是 “Application” 时才有意义。其数值的含义由规范 Startup Notification Protocol Specifications_ 定义,在此不再详述。

… _Startup Notification Protocol Specifications: https://specifications.freedesktop.org/startup-notification-spec/startup-notification-latest.txt

Terminal [可选]

指定应用程序(即关键字"Exec"的数值)是否需要在终端窗口中运行。和 “StartupNotify” 一样,关键字 “StartupNotify” 的数值也是布尔值,并且该关键字只有在 “Type” 类型是 “Application” 时才有意义。本文将在下一节中给出关键字 “Terminal” 的具体使用方法。

Categories [可选]

指定应用程序在菜单中显示的类别。关键字 “Categories” 只有在 “Type” 类型是 “Application” 时才有意义。具体菜单分类由规范 Desktop Specification Menu_ 具体定义。

… _Desktop Specification Menu: https://specifications.freedesktop.org/menu-spec/latest/

OnlyShowIn 和 NotShowIn [可选]

指定应用程序是否在特定 Linux 桌面系统(例如:GNOME 或 KDE)中显示(显示由 “OnlyShowIn” 定义,不显示由 “NotShowIn” 定义)。具体定义请参考 Desktop Specification Menu_ 。

… _Desktop Specification Menu: https://specifications.freedesktop.org/menu-spec/latest/

X-SuSE-translate [SUSE Linux特有]

关键字 “X-SuSE-translate” 是 SUSE Linux 特有的。“X-SuSE-translate” 符合 SUSE RPM Package 风格。“X-SuSE-translate” 数值表示是否要对关键字 “Name” 和 “GenericName” 进行翻译。

本地化关键字 [LOCALE]

根据 “Desktop Entry Specification” 规范 [1]_ ,在关键字后加上字符串 “[LOCALE]” 就可以对该关键字进行特定的本地化定义。“LOCALE” 的合法取值为:

LOCALE= lang_COUNTRY.ENCODING@MODIFIER
  • 1.

在此,域 “_COUNTRY”,“.ENCODING” 和 “@MODIFIER” 是可以被忽略的。当指定 Desktop Entry 文件被解析时,解析器应当根据当前 POSIX locale 来正确获取本地化的关键字数值。比如在上边打开的 “cbt.desktop” 中就分别定义了在 “cs” 和 “hu” 语言环境下关键字 “Name”,“Comment” 和 “GenericName” 的不同数值。

其余关键字

除了上述在清单1中出现的关键字外,“Desktop Entry Specification” 还定义了 “Hidden”,“TryExec”,“MimeType” 等可选关键字。用户可以根据需要进行选取。

分析运行 Desktop Entry 文件


Desktop Entry 文件是一种常见的 Linux 文件格式,很多 Linux 程序需要对该种文件提供支持。在此,本文给出分析运行 Desktop Entry 文件的基本思路。

分析 Desktop Entry 文件内容

操作 Desktop Entry 文件的第一步是获取文件的内容。假设有一个 Desktop Entry 文件,其路径信息存储在变量 pPath 中:

const char* pPath;
  • 1.

下列代码将把该文件内容读入内存 “buffer” 中。

int file_size = 0;
char *file_contents = NULL;
char *buffer = NULL;

if( eel_read_entire_file ( pPath, &file_size, &file_contents ) == GNOME_VFS_OK )
{
    buffer = (char *)g_realloc ( file_contents, file_size + 1 );
    buffer[file_size] = '\0';
}
else
{
    return 1;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

获取 Desktop Entry 文件内容后,就可进一步分析文件内容。在此,分析的重点是获取关键字 “Type”,“Exec”/“URL”,以及 “Terminal” 的数值。首先定义结构 DestopEntryType:

enum DestopEntryType
{
    Application, // Type = Application
    Link,             // Type = Link
    Unknown
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

下列程序将提取关键字 “Type”,“Exec”/“URL” 和 “Terminal” 的数值,并把这些数值分别存储在变量 “type”,“uri"和"bTerminal” 中。

DestopEntryType type = Unknown;
char *uri = NULL;
bool bTerminal = false;

GnomeDesktopItem *desktop_file;

desktop_file = gnome_desktop_item_new_from_string( NULL, buffer, file_size,
(GnomeDesktopItemLoadFlags)0, NULL );
if ( !desktop_file )
{
    g_free( buffer );
    return 1;
}

const char *strType = gnome_desktop_item_get_string( desktop_file, "Type" );
if ( !strType )
{
    g_free( buffer );
    gnome_desktop_item_unref ( desktop_file );
    return 1;
}

if ( 0 == strcmp( strType, "Application" ) )    //type = Application
{
    const char *exec_str = gnome_desktop_item_get_string( desktop_file, "Exec" );
    if( !exec_str )
    {
        g_free( buffer );
        gnome_desktop_item_unref( desktop_file );
        return 1;
    }
   uri = g_strdup( exec_str );
    type = Application;

    const char *strTerminal = gnome_desktop_item_get_string( desktop_file, "Terminal" );
    if ( strTerminal )
    {
        if ( 0 == strcmp( "true", strTerminal ) )
            bTerminal = true;
        else
            bTerminal = false;
    }
}
else if(strcmp(strType, "Link") == 0)    //type = Link
{
    uri = g_strdup( gnome_desktop_item_get_string( desktop_file, "URL" ) );
    type = Link;
}

    g_free( buffer );
    gnome_desktop_item_unref( desktop_file );
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.

运行 “Type = Application” 类型 Desktop Entry 文件

有了关键字 “Type”,“Exec” 和 “Terminal” 的数值,就可如下运行 Desktop Entry 文件。

if ( type == Application )
{
    if( bTerminal )
        eel_gnome_open_terminal_on_screen( uri, NULL );
    else
        eel_gnome_shell_execute_on_screen( uri, NULL);
    g_free( uri );
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

运行 “Type = Link” 类型 Desktop Entry 文件

有了关键字 “Type”,“URL” 和 “Terminal” 的数值,就可如下运行 Desktop Entry 文件。

if ( type == Link )
{
    gnome_url_show( uri, NULL );
    g_free( uri );
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

创建 Desktop Entry 文件实例


在这部分中,将给出创建 Desktop Entry 文件的两个具体实例。这两个实例的目标都是要创建自动访问 IBM DeveloperWorks 网站的快捷方式,具体运行结果(见下图)。这两个实例将使用不同的方法实现这一目标。第一个实例将创建的文件类型是 “Application” 的 Desktop Entry 文件 “VisitDeveloperWorks-Application.desktop”;第二个实例将创建的文件类型是 “Link” 的 Desktop Entry 文件 “VisitDeveloperWorks-Link.desktop”。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_linux_06

创建 “Type = Application” Desktop Entry 文件实例

假设系统指定图标目录下存有图片文件 “gaim.png”。编辑文件 “VisitDeveloperWorks-Application.desktop”(见下图),并把结果存于 /usr/share/applications/ 目录下。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_示例_07

该文件的核心内容是将应用程序图标设置为 “gaim.png” 文件,将 Desktop Entry 文件的类型设置为 “Application”,并将应用程序所要执行的命令设置为 “firefox http://www.ibm.com/developerworks” 。编辑完成后,在文件浏览器和应用程序浏览器下(见下图)就可以看见该实例的显示样式。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_linux_08

创建 “Type = Link” Desktop Entry 文件实例

对上述 “VisitDeveloperWorks-Application.desktop” 文件进行修改(见下图),并将文件更名为 “VisitDeveloperWorks-Link.desktop”,保存于 /usr/share/applications/ 目录下。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_运维_09

该文件的核心内容是将 Desktop Entry 文件的类型设置为 “Link”,并将 Desktop Entry 文件指向的 URL 设置为 “http://www.ibm.com/developerworks” 。编辑完成后,在文件浏览器下(见下图)就可以看见该实例的显示样式。值得注意的是,由于该实例并不是一个应用程序,因此在应用程序浏览器下是看不到相应快捷方式的。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_学习_10

结束语


Desktop Entry 文件是 Linux KDE 和 Linux GNOME 桌面系统中标准的程序启动配置描述方式,本文对该文件格式的定义和应用进行了深入的探讨。

… [1] 详见:https://specifications.freedesktop.org/desktop-entry-spec/latest/index.html


systemd:

Systemd 进程管理工具
############################

历史上,Linux 的启动管理一直采用 init 进程,但是 init 有两个明显的缺点:

  1. 启动时间长。init 进程是串行启动,只有前一个进程启动完,才会启动下一个进程。容易出现阻塞,并且开机时间较长。
  2. 启动脚本复杂。init 进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。现在 Systemd 已经取代了 initd 成为了大多数发行版的标准配置,Systemd 为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

Systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂。事实上,现在还有很多人反对使用 Systemd,理由就是它过于复杂,与操作系统的其他部分强耦合,违反 “keep simple, keep stupid” 的 Unix 哲学。

Unit


systemd 所管理的所有系统资源都称作 Unit(单位),通过 systemd 命令集可以方便的管理 Unit。

Unit 一共分为 12 种。

  • Service unit:系统服务以 .service 结尾
  • Target unit:多个 Unit 构成的一个组以 .target 结尾
  • Device Unit:硬件设备以 .device 结尾
  • Mount Unit:文件系统的挂载点以 .mount 结尾
  • Automount Unit:自动挂载点以 .mount 结尾
  • Path Unit:文件或路径以 .path 结尾
  • Scope Unit:不是由 Systemd 启动的外部进程
  • Slice Unit:进程组
  • Snapshot Unit:Systemd 快照,可以切回某个快照
  • Socket Unit:进程间通信的 socket,以 .sockets 结尾
  • Swap Unit:swap 文件以 .swap 结尾
  • Timer Unit:定时器以 .timer 结尾

使用 systemctl 控制单元时,通常不需要使用单元文件的全名(例如 sshd.service ),只使用简写的方式即可,Systemd 会自动补全文件的后缀名。

  • 无扩展名时默认以 .service 为扩展名。例如 netcfg 和 netcfg.service 是等价的。
  • 挂载点会自动转化为相应的 .mount 单元。例如 /home 等价于 home.mount 。
  • 设备会自动转化为相应的 .device 单元,所以 /dev/sda2 等价于 dev-sda2.device 。
    有一些单元的名称包含一个 @ 标记(例如:name@string.service ),这意味着它是模板单元 name@.service 的一个实例。 string 被称作实例标识符,在 systemctl 调用模板单元时,会将其当作一个参数传给模板单元,模板单元会使用这个传入的参数代替模板中的 %I 指示符。
    在实例化之前,systemd 会先检查 name@string.suffix 文件是否存在(如果存在,就直接使用这个文件)。大多数情况下,包含 @ 标记都意味着这个文件是模板。如果一个模板单元没有实例化就调用,该调用会返回失败,因为模板单元中的 %I 指示符没有被替换。

systemctl list-units 命令可以查看当前系统的所有 Unit 。

# 列出正在运行的 Unit
[Linux]# systemctl list-units

# 列出所有 Unit,包括没有找到配置文件的或者启动失败的
[Linux]# systemctl list-units --all

# 列出所有没有运行的 Unit
[Linux]# systemctl list-units --all --state=inactive

# 列出所有加载失败的 Unit
[Linux]# systemctl list-units --failed

# 列出所有正在运行的、类型为 service 的 Unit
[Linux]# systemctl list-units --type=service
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

systemctl status 命令用于查看系统状态和单个 Unit 的状态。

# 显示系统状态
[Linux]# systemctl status

# 显示单个 Unit 的状态
[Linux]# sysystemctl status bluetooth.service
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。

# 立即启动一个服务
[Linux]# systemctl start apache.service

# 立即停止一个服务
[Linux]# systemctl stop apache.service

# 重启一个服务
[Linux]# systemctl restart apache.service

# 杀死一个服务的所有子进程
[Linux]# systemctl kill apache.service

# 重新加载一个服务的配置文件
[Linux]# systemctl reload apache.service

# 重载所有修改过的配置文件
[Linux]# systemctl daemon-reload

# 显示某个 Unit 的所有底层参数
[Linux]# systemctl show httpd.service
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

Unit 配置文件


每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。

Systemd 默认从目录 /etc/systemd/system/ 读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录 /usr/lib/systemd/system/ ,真正的配置文件存放在那个目录。

============================== =============================
文件说明 路径
============================== =============================
服务启动的脚本启动路径 /usr/lib/systemd/system
开机自启服务存放路径 /etc/systemd/system/multi-user.target.wants/
默认运行级别配置文件 /etc/systemd/system/default.target
============================== =============================

在系统配置文件中,还有一个 /lib/systemd/system/ 目录,其实 /usr/lib/systemd/system/ 目录中的文件是 /lib/systemd/system 目录下文件的硬链接,可以使用 ``ls -li`` 命令查看对比两个文件。
  • 1.

systemctl enable 命令用于在上面两个目录之间,建立符号链接关系。

[Linux]# systemctl enable sshd.service
# 等同于
[Linux]# ln -s '/usr/lib/systemd/system/sshd.service' '/etc/systemd/system/multi-user.target.wants/sshd.service'
  • 1.
  • 2.
  • 3.

如果配置文件里面设置了开机启动, systemctl enable 命令相当于激活开机启动。

与之对应的, systemctl disable 命令用于在两个目录之间,撤销符号链接关系,相当于撤销开机启动。

systemctl list-unit-files 命令用于列出所有配置文件。

# 列出所有配置文件,命令输出一个列表。
[Linux]# systemctl list-unit-files

UNIT FILE                                      STATE
proc-sys-fs-binfmt_misc.automount              static
systemd-ask-password-wall.path                 static
apt-daily-upgrade.service                      static
apt-daily.service                              static
autovt@.service                                enabled
bootlogd.service                               masked
...
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

这个列表显示每个配置文件的状态,一共有四种。

  • enabled:已建立启动链接
  • disabled:没建立启动链接
  • static:该配置文件没有[Install]部分(无法执行),只能作为其他配置文件的依赖
  • masked:该配置文件被禁止建立启动链接

注意,从配置文件的状态无法看出,该 Unit 是否正在运行。这必须执行前面提到的 systemctl status 命令。修改 Unit 配置文件后,需要重新加载配置文件,然后重新启动,否则修改不会生效。

Target


启动计算机的时候,需要启动大量的 Unit。如果每一次启动,都要一一写明本次启动需要哪些 Unit,显然非常不方便。Systemd 的解决方案就是 Target。

简单说,Target 就是一个 Unit 组,包含许多相关的 Unit 。启动某个 Target 的时候,Systemd 就会启动里面所有的 Unit。从这个意义上说,Target 这个概念类似于"状态点",启动某个 Target 就好比启动到某种状态。

传统的init启动模式里面,有 RunLevel 的概念,跟 Target 的作用很类似。不同的是,RunLevel 是互斥的,不可能多个 RunLevel 同时启动,但是多个 Target 可以同时启动。

# 查看当前系统的所有 Target
[Linux]# systemctl list-unit-files --type=target

# 查看一个 Target 包含的所有 Unit
[Linux]# systemctl list-dependencies multi-user.target

# 查看启动时的默认 Target
[Linux]# systemctl get-default

# 设置启动时的默认 Target
[Linux]# systemctl set-default multi-user.target

# 切换 Target 时,默认不关闭前一个 Target 启动的进程,
[Linux]# systemctl isolate 命令改变这种行为,
# 关闭前一个 Target 里面所有不属于后一个 Target 的进程
[Linux]# systemctl isolate multi-user.target
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

日志管理


Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。

:ref:journalctl <cmd_journalctl> 功能强大,用法非常多。

# 查看所有日志(默认情况下 ,只保存本次启动的日志)
[Linux]# journalctl

# 查看内核日志(不显示应用日志)
[Linux]# journalctl -k

# 查看系统本次启动的日志
[Linux]# journalctl -b
[Linux]# journalctl -b -0

# 查看上一次启动的日志(需更改设置)
[Linux]# journalctl -b -1

# 查看指定时间的日志
[Linux]# journalctl --since="2012-10-30 18:17:16"
[Linux]# journalctl --since "20 min ago"
[Linux]# journalctl --since yesterday
[Linux]# journalctl --since "2015-01-10" --until "2015-01-11 03:00"
[Linux]# journalctl --since 09:00 --until "1 hour ago"

# 显示尾部的最新10行日志
[Linux]# journalctl -n

# 显示尾部指定行数的日志
[Linux]# journalctl -n 20

# 实时滚动显示最新日志
[Linux]# journalctl -f

# 查看指定服务的日志
[Linux]# journalctl /usr/lib/systemd/systemd

# 查看指定进程的日志
[Linux]# journalctl _PID=1

# 查看某个路径的脚本的日志
[Linux]# journalctl /usr/bin/bash

# 查看指定用户的日志
[Linux]# journalctl _UID=33 --since today

# 查看某个 Unit 的日志
[Linux]# journalctl -u nginx.service
[Linux]# journalctl -u nginx.service --since today

# 实时滚动显示某个 Unit 的最新日志
[Linux]# journalctl -u nginx.service -f

# 合并显示多个 Unit 的日志
[Linux]# journalctl -u nginx.service -u php-fpm.service --since today

# 查看指定优先级(及其以上级别)的日志,共有8级
# 0: emerg
# 1: alert
# 2: crit
# 3: err
# 4: warning
# 5: notice
# 6: info
# 7: debug
[Linux]# journalctl -p err -b

# 日志默认分页输出,--no-pager 改为正常的标准输出
[Linux]# journalctl --no-pager

# 以 JSON 格式(单行)输出
[Linux]# journalctl -b -u nginx.service -o json

# 以 JSON 格式(多行)输出,可读性更好
[Linux]# journalctl -b -u nginx.serviceqq
 -o json-pretty

# 显示日志占据的硬盘空间
[Linux]# journalctl --disk-usage

# 指定日志文件占据的最大空间
[Linux]# journalctl --vacuum-size=1G

# 指定日志文件保存多久
[Linux]# journalctl --vacuum-time=1years
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.

Systemd 命令集合


Systemd 并不是一个命令,而是一组命令,涉及到系统管理的方方面面。

systemctl
++++++++++++++++++++++++++++++++

:ref:systemctl <cmd_systemctl> 是 Systemd 的主命令,用于管理系统。

# 重启系统
[Linux]# systemctl reboot

# 关闭系统,切断电源
[Linux]# systemctl poweroff

# 让系统进入冬眠状态
[Linux]# systemctl hibernate

# 让系统进入交互式休眠状态
[Linux]# systemctl hybrid-sleep

# 启动进入救援状态(单用户状态)
[Linux]# systemctl rescue

# 列出所有已启动的服务
systemctl list-units --type=service

# 查看 systemd 管理的所有单元
systemctl list-unit-files
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

systemd-analyze
++++++++++++++++++++++++++++++++

:ref:systemd-analyze <cmd_systemd-analyze> 命令用于查看启动耗时。

# 查看启动耗时
[Linux]# systemd-analyze

# 查看每个服务的启动耗时
[Linux]# systemd-analyze blame

# 显示瀑布状的启动过程流
[Linux]# systemd-analyze critical-chain

# 显示指定服务的启动流
[Linux]# systemd-analyze critical-chain atd.service
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

hostnamectl
++++++++++++++++++++++++++++++++

:ref:hostnamectl <cmd_hostnamectl> 命令用于查看当前主机的信息。

# 显示当前主机的信息
[Linux]# hostnamectl

# 设置主机名。
[Linux]# hostnamectl set-hostname rhel7
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

localectl
++++++++++++++++++++++++++++++++

:ref:localectl <cmd_localectl> 命令用于查看本地化设置。

# 查看本地化设置
[Linux]# localectl

# 设置本地化参数。
[Linux]# localectl set-locale LANG=en_GB.utf8
[Linux]# localectl set-keymap en_GB
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

timedatectl
++++++++++++++++++++++++++++++++

:ref:timedatectl <cmd_timedatectl> 命令用于查看当前时区设置。

# 查看当前时区设置
[Linux]# timedatectl

# 显示所有可用的时区
[Linux]# timedatectl list-timezones

# 设置当前时区
[Linux]# timedatectl set-timezone America/New_York
[Linux]# timedatectl set-time YYYY-MM-DD
[Linux]# timedatectl set-time HH:MM:SS
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

loginctl
++++++++++++++++++++++++++++++++

:ref:loginctl <cmd_loginctl> 命令用于查看当前登录的用户。

# 列出当前 session
[Linux]# loginctl list-sessions

# 列出当前登录用户
[Linux]# loginctl list-users

# 列出显示指定用户的信息
[Linux]# loginctl show-user name
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

Systemd 定时器
############################

Systemd 定时器与 cron 作业类似,但是 Systemd 定时器可以做到 cron 作业无法做到的一些事情。例如,Systemd 定时器可以在特定事件发生后的一段时间后触发一段脚本或者程序去执行,例如开机、启动、上个任务完成,甚至于定时器调用的上个服务单元的完成的时刻。

其实每个 Linux 系统在安装完成后,都会或多或少的运行多个定时器任务,可以使用 systemctl status *timer 命令来查看主机上的所有的定时器单元。

[linux]$ systemctl status *timer
● logrotate.timer - Daily rotation of log files
   Loaded: loaded (/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Sun 2021-07-25 10:47:45 CST; 3 days ago
  Trigger: Thu 2021-07-29 00:00:00 CST; 10h left
     Docs: man:logrotate(8)
           man:logrotate.conf(5)

● apt-daily.timer - Daily apt download activities
   Loaded: loaded (/lib/systemd/system/apt-daily.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Sun 2021-07-25 10:47:45 CST; 3 days ago
  Trigger: Wed 2021-07-28 18:56:21 CST; 5h 3min left

● apt-daily-upgrade.timer - Daily apt upgrade and clean activities
   Loaded: loaded (/lib/systemd/system/apt-daily-upgrade.timer; enabled; vendor preset: en
   Active: active (waiting) since Sun 2021-07-25 10:47:45 CST; 3 days ago
  Trigger: Thu 2021-07-29 06:59:12 CST; 17h left
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

每个定时器至少有六行相关信息:

  • 第一行是定时器名字和定时器目的的简短介绍
  • Loaded: 定时器的状态,是否已加载,定时器单元文件的完整路径以及预设信息。
  • Active: 活动状态,包括该定时器激活的日期和时间。
  • Trigger: 定时器下次被触发的日期和时间和距离触发的大概时间。
  • Triggers: 被定时器触发的事件或服务名称。
  • Docs: 相关文档的指引。
  • 最后一行是计时器最近触发的服务实例的日志条目。

创建定时器


在创建定时器之前,必须要有一个 Systemd 启动单元。

/etc/systemd/system 目录下创建 myMonitor.timer 定时器单元文件,添加如下代码:

# This timer unit is for testing
# By David Both
# Licensed under GPL V2
#
[Unit]
Description=Logs some system statistics to the systemd journal
Requires=myMonitor.service
[Timer]
Unit=myMonitor.service
OnCalendar=*-*-* *:*:00
[Install]
WantedBy=timers.target
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

其中,Unit 是需要运行的单元(脚本或程序)。OnCalendar 是时间格式,--* ::00,应该会每分钟触发一次定时器去执行 myMonitor.service 单元。

时间格式


Systemd 定时器使用 OnCalendar 的基础格式是 DOW YYYY-MM-DD HH:MM:SS 。DOW(星期几)是选填的,其他字段可以用一个星号( * )来匹配此位置的任意值。所有的日历时间格式会被转换成标准格式。如果时间没有指定,它会被设置为 00:00:00 。如果日期没有指定但是时间指定了,那么下次匹配的时间可能是今天或者明天,取决于当前的时间。月份和星期可以使用名称或数字。每个单元都可以使用逗号分隔的列表。单元范围可以在开始值和结束值之间用 .. 指定。

指定日期有一些有趣的选项,波浪号( ~ )可以指定月份的最后一天或者最后一天之前的某几天。 / 可以用来指定星期几作为修饰符。

这里有几个在 OnCalendar 表达式中使用的典型时间格式例子。

============================== ==============================
日期事件格式 描述
============================== ==============================
*-*-* 00:15:30 每年每月每天的 0 点 15 分 30 秒
Weekly 每个周一的 00:00:00
Mon *-*-* 00:00:00 同上
Mon 同上
Wed 2020-*-* 2020 年每个周三的 00:00:00
Mon…Fri 2021-*-* 2021 年的每个工作日(周一到周五)的 00:00:00
2022-6,7,8-1,15 01:15:00 2022 年 6、7、8 月的 1 到 15 号的 01:15:00
Mon *-05~03 每年五月份的下个周一同时也是月末的倒数第三天
Mon…Fri *-08~04 任何年份 8 月末的倒数第四天,同时也须是工作日
*-05~03/2 五月末的倒数第三天,然后 2 天后再执行一次。表达式使用了波浪号(~)。
*-05-03/2 五月的第三天,然后每两天重复一次直到 5 月底。表达式使用了破折号(-)。
============================== ==============================

测试时间格式

Systemd 提供了一个绝佳的工具用于检测和测试定时器中日历时间事件的格式。systemd-analyze calendar 工具解析一个时间事件格式,提供标准格式和其他有趣的信息,例如下次匹配的日期和时间,以及距离下次触发之前大概时间。

首先,看看未来没有时间的日(注意 Next elapse 和 UTC 的时间会根据你当地时区改变):

[student@studentvm1 ~]$ systemd-analyze calendar 2030-06-17
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

现在添加一个时间,在这个例子中,日期和时间是当作无关的部分分开解析的:

[root@testvm1 system]# systemd-analyze calendar 2030-06-17 15:21:16
  Original form: 2030-06-17                
Normalized form: 2030-06-17 00:00:00        
    Next elapse: Mon 2030-06-17 00:00:00 EDT
       (in UTC): Mon 2030-06-17 04:00:00 UTC
       From now: 10 years 0 months left    
  Original form: 15:21:16                  
Normalized form: *-*-* 15:21:16            
    Next elapse: Mon 2020-06-15 15:21:16 EDT
       (in UTC): Mon 2020-06-15 19:21:16 UTC
       From now: 3h 55min left              
[root@testvm1 system]#
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

为了把日期和时间当作一个单元来分析,可以把它们包在引号里。你在定时器单元里 OnCalendar= 时间格式中使用的时候记得把引号去掉,否则会报错:

[root@testvm1 system]# systemd-analyze calendar "2030-06-17 15:21:16"
Normalized form: 2030-06-17 15:21:16        
    Next elapse: Mon 2030-06-17 15:21:16 EDT
       (in UTC): Mon 2030-06-17 19:21:16 UTC
       From now: 10 years 0 months left    
[root@testvm1 system]#
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

现在我们测试下 Table2 里的例子。我尤其喜欢最后一个:

[root@testvm1 system]# systemd-analyze calendar "2022-6,7,8-1,15 01:15:00"
  Original form: 2022-6,7,8-1,15 01:15:00
Normalized form: 2022-06,07,08-01,15 01:15:00
    Next elapse: Wed 2022-06-01 01:15:00 EDT
       (in UTC): Wed 2022-06-01 05:15:00 UTC
       From now: 1 years 11 months left
[root@testvm1 system]#
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

让我们看一个例子,这个例子里我们列出了时间表达式的五个经过时间。

[root@testvm1 ~]# systemd-analyze calendar --iterations=5 "Mon *-05~3"
  Original form: Mon *-05~3                
Normalized form: Mon *-05~03 00:00:00      
    Next elapse: Mon 2023-05-29 00:00:00 EDT
       (in UTC): Mon 2023-05-29 04:00:00 UTC
       From now: 2 years 11 months left    
       Iter. #2: Mon 2028-05-29 00:00:00 EDT
       (in UTC): Mon 2028-05-29 04:00:00 UTC
       From now: 7 years 11 months left    
       Iter. #3: Mon 2034-05-29 00:00:00 EDT
       (in UTC): Mon 2034-05-29 04:00:00 UTC
       From now: 13 years 11 months left    
       Iter. #4: Mon 2045-05-29 00:00:00 EDT
       (in UTC): Mon 2045-05-29 04:00:00 UTC
       From now: 24 years 11 months left    
       Iter. #5: Mon 2051-05-29 00:00:00 EDT
       (in UTC): Mon 2051-05-29 04:00:00 UTC
       From now: 30 years 11 months left    
[root@testvm1 ~]#
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

这些应该为你提供了足够的信息去开始测试你的 OnCalendar 时间格式。systemd-analyze 工具可用于其他有趣的分析,我会在这个系列的下一篇文章来探索这些。

精确时间执行任务

定时器并不会在精确的时间去执行。Systemd 定时器被故意设计成在规定时间附近随机波动的时间点触发,这样设计的初衷是为了防止多个服务在完全相同的时刻被触发。举个例子,系统管理员可以用 Weekly,Daily 等时间格式。这些快捷写法都被定义为在某一天的 00:00:00 执行。当多个定时器都这样定义的话,有很大可能它们会同时执行。

大部分情况下,这种概率抖动的定时器是没事的。当调度类似执行备份的任务,只需要它们在下班时间运行,这样是没问题的。系统管理员可以选择确定的开始时间来确保不和其他任务冲突,例如 01:05:00 这样典型的 cron 作业时间,但是有很大范围的时间值可以满足这一点。在开始时间上的一个分钟级别的随机往往是无关紧要的。

然而,对某些任务来说,精确的触发时间是个硬性要求。对于这类任务,你可以向单元文件的 Timer 块中添加如下声明来指定更高的触发时间跨度精确度(精确到微秒以内):

AccuracySec=1us
  • 1.

时间跨度可用于指定所需的精度,以及定义重复事件或一次性事件的时间跨度。它能识别以下单位:

  • usec,us,µs
  • msec,ms
  • seconds,second,sec,s
  • minutes,minute,min,m
  • hours,hour,hr,h
  • days,day,d
  • weeks,week,w
  • months,month,M(定义为 30.44 天)
  • years,year,y(定义为 365.25 天)

运行定时器


Systemd 定时器可以被配置成根据其他 systemd 单元状态发生改变时触发。举个例子,定时器可以配置成在系统开机、启动后,或是某个确定的服务单元激活之后的一段时间被触发。这些被称为单调计时器。“单调”指的是一个持续增长的计数器或序列。这些定时器不是持久的,因为它们在每次启动后都会重置。

下表列出了一些定时器的简短定义,同时有 OnCalendar 定时器,它们被用于指定未来有可能重复的某个确定时间。详细信息请查看 systemd.timer 的手册页。

===================== =====================
定时器 定义
===================== =====================
OnActiveSec= 一个与定时器被激活的那一刻相关的定时器。
OnBootSec= 一个与机器启动时间相关的计时器。
OnStartupSec= 一个与服务管理器首次启动相关的计时器,与 OnBootSec 类似,主要区别于在 Linux 中用户的服务管理器通常在首次登录后启动,而不是机器启动后。
OnUnitActiveSec= 一个与将要激活的定时器上次激活时间相关的定时器。
OnUnitInactiveSec= 一个与将要激活的定时器上次停用时间相关的定时器。
OnCalendar= 一个有日期事件表达式语法的实时(即时钟)定时器。查看 systemd.time(7) 的手册页获取更多与日历事件表达式相关的语法信息。除此以外,它的语义和 OnActiveSec= 类似。
===================== =====================

计时器可使用同样的简写名作为它们的时间跨度,即我们之前提到的 AccuracySec 表达式,但是 systemd 将这些名字统一转换成了秒。举个例子,比如你想规定某个定时器在系统启动后五天触发一次事件;它可能看起来像 OnBootSec=5d。如果机器启动于 2020-06-15 09:45:27,这个定时器会在 2020-06-20 09:45:27 或在这之后的一分钟内触发。


Systemd 开机自动挂载硬盘
####################################

Systemd 的 Mount Unit 单元可以实现挂载硬盘,并且可以设定为开机自启动。相较于使用 /etc/fstab 文件来实现开机自动挂载硬盘,采用 Systemd 的方式更灵活,也不会因为配置错误导致无法开机,所以比较适合折腾。

新建挂载文件


/usr/lib/systemd/system/ 目录下,新建文件并以 .mount 结尾。

[linux]# cat /usr/lib/systemd/system/home-disk.mount

[Unit]
Description=mount my videos disk
After=home.mount

[Mount]
#What=UUID=ea8d7bf8-384d-412b-b9eb-b92f702fc360
What=/dev/sdb2
Where=/home/user/Videos
Type=ext4
Options=defaults

[Install]
WantedBy=multi-user.target
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

在加入开机启动之前,首先应该测试一下挂载文件的正确性:

[Linux]$ systemctl start home-disk.mount
  • 1.

添加开机启动


[Linux]# systemctl enable home-disk.mount
  • 1.

Systemd 开机自启脚本
####################################

因为现在的 Linux 系统很多默认使用 systemd,所以网上流传的很多 init 开机自启脚本的方法已经过时。

下边介绍一种 systemd 的方法。

新建服务启动区块


Systemd 的配置文件在 /usr/lib/systemd/system 下,并且以 .service 结尾。

新建并编辑配置文件,下边是一个简单的示例:

[Unit]
Description=Customize the  script
After=network.target sshd-keygen.service

[Service]
ExecStart=/root/init.sh

[Install]
WantedBy=multi-user.target
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

Unit

[Unit] 区块通常是配置文件的第一个区块,用来定义 Unit 的元数据,以及配置与其他 Unit 的关系。它的主要字段如下。

  • Description:简短描述
  • Documentation:文档地址
  • Requires:强依赖,如果指定的 Unit 启动失败,那么当前 Unit 会失败
  • Wants:弱依赖,如果指定的 Unit 启动失败,不影响当前 Unit 启动
  • Before:在指定的 Unit 启动之前,启动当前 Unit
  • After:在指定的 Unit 启动之后,启动当前 Unit
  • Conflicts:指定的 Unit 不能与当前 Unit 同时运行
  • Condition:当前 Unit 运行时必须满足的条件,否则不会运行
  • Assert:当前 Unit 运行时必须满足的条件,否则会启动失败
    After 和 Before 字段只涉及启动顺序,不涉及依赖关系。
    Wants 和 Requires 字段只涉及依赖关系,与启动顺序无关,默认情况下是同时启动。

当某 Web 应用需要 sql 数据库储存数据时。如果在配置文件中,只定义在 sql 之后启动 Web 服务,而没有定义强依赖 sql。上线后,如果 sql 启动失败,该 Web 应用将无法使用。

Service

[Service] 区块用来定义如何启动当前服务,只有 Service 类型的 Unit 才有这个区块。它的主要字段如下。

  • Type:定义启动时的进程行为。它有以下几种值。
  • Type=simple:默认值,执行 ExecStart 指定的命令,启动主进程
  • Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
  • Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
  • Type=dbus:当前服务通过 D-Bus 启动
  • Type=notify:当前服务启动完毕,会通知 Systemd,再继续往下执行
  • Type=idle:若有其他任务执行完毕,当前服务才会运行
  • ExecStart:启动当前服务时执行的命令
  • ExecStartPre:启动当前服务之前执行的命令
  • ExecStartPost:启动当前服务之后执行的命令
  • ExecReload:重启当前服务时执行的命令
  • ExecStop:停止当前服务时执行的命令
  • ExecStopPost:停止当其服务之后执行的命令
  • KillMode:定义 Systemd 如何停止当前服务。
  • KillMode=control-group:当前控制组里的所有子进程,都被杀掉(默认值)
  • KillMode=process:只杀死主进程
  • KillMode=mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
  • KillMode=none:没有进程会被杀掉,只是执行服务的 stop 命令。
  • RestartSec:自动重启当前服务间隔的秒数
  • Restart:定义何种情况 Systemd 会自动重启当前服务
  • Restart=no:退出后不会重启(默认值)
  • Restart=on-success:只有正常退出时(退出状态码为 0),才会重启
  • Restart=on-failure:非正常退出时,包括被信号终止和超时,才会重启
  • Restart=on-abnormal:只有被信号终止和超时,才会重启
  • Restart=on-abort:只有在收到没有捕捉到的信号终止时,才会重启
  • Restart=on-watchdog:超时退出,才会重启
  • Restart=always:不管是什么退出原因,总是重启
  • RestartSec:定义 Systemd 重启服务之前,需要等待的秒数
  • TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
  • Environment:指定当前服务的环境变量参数文件
    在所有的启动设置之前,都可以加上一个连词号 - ,表示“抑制错误”,即发生错误的时候,不影响其他命令的执行。比如 EnvironmentFile=-/etc/sysconfig/sshd ,表示即使 sshd 文件不存在,也不会抛出错误。

Install

[Install] 通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下。

  • WantedBy:一个或多个 Target(服务组),当 Unit 激活时(开机自启动)符号链接会放入 /etc/systemd/system/ + Target 名 + .wants 后缀构成的子目录中
  • RequiredBy:一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 * Target 名 + .required 后缀构成的子目录中
  • Alias:当前 Unit 可用于启动的别名
  • Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit
    一般来说,常用的 Target 有两个:一个是 multi-user.target,表示多用户命令行状态;另一个是 graphical.target,表示图形用户状态,它依赖于 multi-user.target。
    可以使用 systemctl get-default 查看系统默认的启动 Target。
[Linux]$ systemctl get-default
  graphical.target
  • 1.
  • 2.

Unit 配置文件的完整字段清单,请参考官方文档。

添加开机自启服务


  1. 添加开机自动启动服务,系统会自动增加由 /lib/systemd/system/ 到 /etc/systemd/system/multi-user.target.wants/ 下的软链接。
    systemctl enable httpd.service
  2. 移除开机自动启动服务,删除 /etc/systemd/system/multi-user.target.wants 下的软链接。
    systemctl disable httpd.service
  3. 查看开机是否启动
    systemctl status httpd.service (服务详细信息)
    systemctl is-active httpd.service (仅显示是否 Active)
  4. 查看开机自启动的程序
    ls /etc/systemd/system/multi-user.target.wants/
  5. 列出所有已启动的服务
    systemctl list-units --type=service
  6. 列出启动失败的单元
    systemctl --failed
  7. 查看 systemd 单元加载及活动情况
    systemctl
  8. 查看 systemd 管理的所有单元
    systemctl list-unit-files

vsftpd 配置文件
############################

vsftpd(very secure FTP daemon)是一个完全免费、开源的 ftp 服务器软件,支持很多其他的 FTP 服务器所不支持的特征。比如:非常高的安全性需求、带宽限制、良好的可伸缩性、可创建虚拟用户、支持IPv6、速率高等。

在 vsftpd 的诸多文件中,所有的配置都是基于 vsftpd.conf 的。

=============================== ================
文件 说明
=============================== ================
/etc/vsftpd.conf 主配置文件
/usr/sbin/vsftpd 主程序
/etc/pam.d/vsftpd PAM 认证文件
/etc/ftpusers 禁止使用的用户列表,每行一个用户名
/etc/vsftpd/user_list 禁止或允许使用的用户列表。详见 userlist_deny
/srv/ftp 匿名用户主目录
/etc/logrotate.d/vsftpd.log 日志文件
=============================== ================

主配置文件


vsftpd 的主配置文件路径为 /etc/vsftpd.conf ,在修改配置文件时,注释掉行可以关闭默认配置,修改前请备份。

  • anonymous_enable 是否允许匿名登录服务器
  • local_enable 是否允许本地用户登录服务器
  • write_enable 是否允许本地用户具有写权限
  • local_umask 本地用户的文件掩码
  • local_root 系统用户登录路径
  • anon_root 匿名用户登录路径
  • chroot_local_user 是否锁定用户登录目录为其根目录
  • anon_upload_enable 是否允许匿名用户上传文件,须开启 write_enable 选项
  • anon_mkdir_write_enable 是否允许匿名用户创建新文件夹
  • dirmessage_enable 是否激活目录欢迎信息功能
  • xferlog_enable 如果启用此选项,系统将会记录服务器上传和下载的日志文件,默认日志文件为 /var/log/vsftpd.log,也可以通过 xferlog_file 选项设定
  • xferlog_file=/var/log/vsftpd.log 服务器上传、下载的日志存储路径
  • xferlog_std_format 以 xferlog 格式记录日志文件
  • syslog_enable 是否将日志写入系统日志中
  • connect_from_port_20=YES 开启主动模式后是否启用默认的 20 端口监听
  • chown_uploads 是否允许改变上传文件的属主,与下面选项配合使用
  • chown_username 改变上传文件的属主,输入一个系统用户名,whoever:任何人
  • idle_session_timeout 数据传输中断间隔时间
  • data_connection_timeout 数据连接超时时间
  • nopriv_user=ftpsecure 运行 vsftpd 需要的非特权系统用户
  • use_localtime 是否使用主机的时间,默认使用 GMT 时间,比北京时间晚 8小时,建议设定为 YES
  • ascii_upload_enable 以 ASCII 方式上传数据
  • ascii_download_enable 以 ASCII 方式下载数据
  • ftpd_banner 登录 FTP 服务器时显示的欢迎信息
  • chroot_list_enable 用户是否具有访问自己目录以外文件的权限,设置为 YES 时,用户被锁定在自己的 home 目录中
  • chroot_list_file=/etc/vsftpd/chroot_list 不能访问自己目录以外的用户名,需要和 chroot_list_enable 配合使用
  • ls_recurse_enable 是否允许递归查询
  • listen 是否让 vsftpd 以独立模式运行,由 vsftpd 自己监听和处理连接请求
  • listen_ipv6 是否支持 IPV6
  • userlist_enable 是否阻止 ftpusers 文件中的用户登录服务器
  • userlist_deny 是否阻止 user_list 文件中的用户登录服务器
  • tcp_wrappers 是否使用 tcp_wrappers 作为主机访问控制方式
  • max_client 允许的最大客户端连接数,0 为不限制
  • max_per_ip 同一 IP 允许的最大客户端连接数,0 为不限制
  • local_max_rate 本地用户的最大传输速率(单位:B/s),0 为不限制
  • anon_max_rate 匿名用户的最大传输速率
    修改完配置文件,需要使用 systemclt restart vsftpd 命令重启服务才能生效。

应用实例


  1. 匿名用户登录最小配置
    ++++++++++++++++++++++++++++++++++++

不以独立模式运行

listen=NO

支持 IPV6,如不开启 IPV4 也无法登录

listen_ipv6=YES

匿名用户登录

anonymous_enable=YES

系统用户登录

local_enable=YES

对文件具有写权限,否则无法上传

write_enable=YES

允许匿名用户上传文件

anon_upload_enable=YES

允许匿名用户新建文件夹

anon_mkdir_write_enable=YES

匿名用户删除文件和重命名文件

anon_other_write_enable=YES

匿名用户的掩码(022 的实际权限为 666-022=644)

anon_umask=022

匿名用户访问路径

anon_root=/var/www/html/web

指定端口号

listen_port=5001

使用主机时间

use_localtime=YES
pam_service_name=vsftpd

由于 vsftpd 增强了安全检查,如果用户被限定在其主目录下,则用户的主目录不能具有写权限,如果还有写权限,就会报该错误:

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

要修复这个错误,可以删除用户的写权限 chmod a-w /var/www/html/web
或者在 vsftpd 的配置文件中增加下列两项:

chroot_local_user=YES 
 allow_writeable_chroot=YES
  • 1.
  • 2.
  1. 设置禁止登录的用户账号
    ++++++++++++++++++++++++++++++++++++

当主配置文件中包括以下设置时,vsftpd.user_list 中的用户账号被禁止登录

userlist_enable=YES
userlist_deny=YES
userlist_enable=YES
  • 1.
  • 2.
  • 3.

userlist_deny 和 userlist_enable 选项限制用户登录服务器,可以有效阻止 root,apache,www 等系统用户登录服务器,从而保证服务器的分级安全性。

userlist_enable=YES
ftpusers 中用户允许访问,user_list 中用户允许访问

userlist_enable=NO
ftpusers 中用户禁止访问,user_list 中用户允许访问

userlist_deny=YES
ftpusers 中用户禁止访问,user_list 中用户禁止访问

userlist_deny=NO
ftpusers 中用户禁止访问,user_list 中用户允许访问

userlist_deny=YES
userlist_enable=YES
ftpusers 中用户禁止访问,user_list 中用户禁止访问

userlist_deny=NO
userlist_enable=YES
ftpusers 中用户禁止访问,user_list 中用户允许访问

  1. 修改默认端口
    ++++++++++++++++++++++++++++++++++++

FTP 服务器默认端口号是 21,出于安全目的,有时需修改默认端口号。自定义端口号范围 5001 至 65535。参见 :doc:计算机端口详解 <../Chapter03/00_port>

listen_port=5001

FTP 数字代码的意义


===== ======
代码 意义
===== ======
110 重新启动标记应答
120 服务在多久时间内 ready
125 数据链路端口开启,准备传送
150 文件状态正常,开启数据连接端口
200 命令执行成功
202 命令执行失败
211 系统状态或是系统求助响应
212 目录的状态
213 文件的状态
214 求助的讯息
215 名称系统类型
220 新的联机服务 ready
221 服务的控制连接端口关闭,可以注销
225 数据连结开启,但无传输动作
226 关闭数据连接端口,请求的文件操作成功
227 进入 passive mode
230 使用者登入
250 请求的文件操作完成
257 显示目前的路径名称
331 用户名称正确,需要密码
332 登入时需要账号信息
350 请求的操作需要进一部的命令
421 无法提供服务,关闭控制连结
425 无法开启数据链路
426 关闭联机,终止传输
450 请求的操作未执行
451 命令终止:有本地的错误
452 未执行命令:磁盘空间不足
500 格式错误,无法识别命令
501 参数语法错误
502 命令执行失败
503 命令顺序错误
504 命令所接的参数不正确
530 未登入
532 储存文件需要账户登入
550 未执行请求的操作
551 请求的命令终止,类型未知
552 请求的文件终止,储存位溢出
553 未执行请求的的命令,名称不正确
===== ======


VNC 远程桌面
####################################

VNC 是基于 RFB(Remote FrameBuffer)的一款开源的远程桌面控制软件。它由客户端、服务端和一个协议组成。

开源的 VNC 衍生出了三个重大的分支版本(RealVNC,VNC tight 和 UltraVNC),其中 Real VNC 是当前跨平台的主流应用,分为全功能商业版和免费版。

安装 VNC Server


yum 安装,CentOS 5.3 yum 源自带了 vnc 与 vnc-server。

[Linux]# yum install vnc

[Linux]# yum install vnc-server
  • 1.
  • 2.
  • 3.

配置 VNC Server


VNC Server 的配置文件为 /etc/sysconfig/vncservers,在文件末尾添加以下两句:

# 由于 root 用户使用的是第一个 VNC Server,我们添加 Server 是从 2 开始的,所以这里桌面号是 2,用户名是 hubery。
VNCSERVERS="2:hubery"

# 桌面分辨率为 800*600,阻止图形桌面通过 TCP 端口,不能通过 WEB 访问 vncserver,不能通过不安全的方式从远程登录。
VNCSERVERARGS[2]="-geometry 800x600 -nolisten tcp -nohttpd -localhost"
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

关于参数配置说明:

  • -geometry 表示桌面分辨率,默认为 1024x768
  • -nohttpd 表示不监听 HTTP 端口(58xx)
  • -nolisten tcp 表示不监听 TCP 端口(60xx)
  • -localhost 只允许从本机访问
  • AlwaysShared 默认只允许一个 VNCVIEWER 连接,此参数表示同一个显示端口允许多用户同时登录
  • -depth 表示色深,参数有 8,16,24,32.
  • SecurityTypes None 登录不需要密码认证 VncAuth 默认值,要密码认证。

VNC 使用的起始端口是 5900 和 5800,桌面号是 2 时,VNC Viewer 访问的端口是 5902,WEB 方式(java)访问的端口号是 5802。

root 用户的配置也是这个文件,若要配置需要在文件末尾同样加上类似以上两句。

以上配置,vncserver 将在服务启动时打开 vncserver :2。

防火墙配置


如果不熟悉防火墙 iptables,可以直接关掉(重启失效):

[Linux]# iptables -L

或
[Linux]# service iptables stop
  • 1.
  • 2.
  • 3.
  • 4.

但一般不建议这样做,我们需要在防火墙里打开某些端口:

[Linux]# iptables -I INPUT -p tcp --dport 5901:5902 -j ACCEPT
[Linux]# iptables -I INPUT -p udp --dport 5901:5902 -j ACCEPT
  • 1.
  • 2.

同样,上述操作在计算机重启之后也会失效,以下操作将配置保存到配置文件,使其永久生效:

[Linux]# service iptables save
  • 1.

启动 VNC Server


在启动 Server 之前需要给远程控制设置一个访问密码:

[Linux]# su hubery
[Linux]$ vncpasswd
Password:
Verify:
[Linux]$ vncserver :2
xauth:  creating new authority file /home/hubery/.Xauthority

New 'localhost:2 (hubery)' desktop is localhost:2

Creating default startup script /home/hubery/.vnc/xstartup
Starting applications specified in /home/hubery/.vnc/xstartup
Log file is /home/hubery/.vnc/localhost:2.log

[Linux]$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

关闭某个 vncserver:

[Linux]$ vncserver -kill :2
  • 1.

VNC Viewer 访问


我的 VNC 客户端是在 Win XP 下安装的 TigerVNC Viwer,可以从其官网免费下载。安装 VNC Viewer 后以 Server_IP:桌面号的形式访问。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_示例_11

桌面配置(可选)


以上配置登陆之后得到的是 twm 桌面,看起来像一个终端,但它还是桌面,我们可以从命令行启动桌面应用,例如 firefox,但是一般人是用不习惯、不会去用它的,可以换其它的桌面吗?当然可以,其配置文件为 ~/.vnc/xstartup,将 twm 修改为 gnome-session 或 startkde 即可切换成 gnome 或 kde。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_运维_12

#!/bin/sh

# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
# twm &
gnome-session &
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

切换之后重启服务是必须的:

[Linux]# service vncserver restart

或

[Linux]# su hubery
[hubery@localhost .vnc]$ vncserver -kill :2
Killing Xvnc process ID 20353
[hubery@localhost .vnc]$ vncserver :2

New 'localhost:2 (hubery)' desktop is localhost:2

Starting applications specified in /home/hubery/.vnc/xstartup
Log file is /home/hubery/.vnc/localhost:2.log

[hubery@localhost .vnc]$
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

使用 Viewer 重新登陆,你会发现我们熟悉的桌面又回来了:

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_实例_13

安全访问 VNC(可选)


如果直接使用 vncviewer 来进行访问,有两点不利因素:

  1. 口令传输是明文,很容易被侦听到。
  2. 防火墙需要打开 59xx 端口,这在通常的单位里是不可能的。

幸运的是,我们有 ssh 这个强大的工具,我们可以使用 ssh 隧道来保护通讯过程,下面就进行简单介绍。

我依然使用 Win XP 下的 Tiger VNC 做客户端,其实对于 Linux 下也是可以的(更简单)。

  1. 在 Session 下配置 Host Name 为 Server IP,Port 为 SSH 端口 22;

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_学习_14

  1. 在 Connection > SSH > Tunnels 配置 Source port 为 VNC Server 端口号 5902,Destination 为 localhost:5902,并 Add 添加;

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_linux_15

  1. 使用 TigerVNC Viewer 访问,地址现在是 localhost:2。

从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第二章:配置文件_运维_16

至此,我们使用了加密的 VNC,而且也不需要配置防火墙打开端口,也就是说使用 ssh 隧道在没有步骤三的情况下也是有效的。