从头到尾快速学习一遍Linux,高级工程师多年实践实战经验精华总结和实例示例,第六章:核心运维技术工具常见错误及解决方法。
常见错误及解决方法
躺过的各种坑,都在这里…
安装 Debian 时缺少无线网卡固件
#############################################
笔记本电脑安装 Debian 10,检测网卡时出现以下错误提示:
Some of your hardware needs non-free firmware files to operate.
The firmware can be loaded from removable media, such as a USB stick or floopy.
The missing firmware files are: iwlwifi-5000-5.ucode iwlwifi-5000-4.ucode
iwlwifi-5000-3.ucode iwlwifi-5000-2.ucode iwlwifi-5000-1.ucode
If you have such media available now, insert it, and continue.
Load missing firmware from removable media?
<Yes> <No>
简单翻译一下:
您的一些硬件需要非自由固件文件才能运转。固件可以从可移动介质加载,比如 U 盘或者软盘。
缺失的固件文件是:iwlwifi-5000-5.ucode iwlwifi-5000-4.ucode iwlwifi-5000-3.ucode iwlwifi-5000-2.ucode iwlwifi-5000-1.ucode
如果现在您有可用的介质,请将其插入,然后继续。
从可移动介质加载缺失的固件吗?
<是> <否>
什么是固件?
有些硬件除了需要设备驱动程序之外,还要在使用之前加载固件(firmware)或微码(microcode)。这对于网卡(特别是无线网卡)来说很常见,但有些 USB 设备甚至是硬盘控制器也需要加载固件。对于许多显卡,可以在毋须固件的情况下使用基本的功能,但使用高级功能就需要先安装合适的固件到系统中。
有些老的设备需要固件才能工作,这些固件被厂商永久性地置于设备的 EEPROM/Flash 芯片中。现今新设备不再采用这种方式嵌入固件,因此固件必须在系统引导的时候从宿主系统上传到设备中。
根据 Debian GNU/Linux 项目的标准,大多数情况下这些固件属于 non-free,不能被包含在主发行版或安装系统里面。如果设备驱动程序被包含到发行版里面,并且 Debian GNU/Linux 可以合法地发布固件,它通常被单独地放置在仓库的 non-free 区里面。
然而,这并不意味着该硬件不能在安装时使用。从 Debian GNU/Linux 5.0 开始,debian-installer 支持从可移动的介质,比如 U 盘,加载固件或包含固件的软件包。
假如 debian-installer 提示需要固件文件而您又没有该固件,或者不想装非自由的固件到系统上,您可以试着跳过固件加载。有些情况下驱动程序只是在特定情况下提示需要额外的固件,而这个设备在很多系统上可以不使用它就能工作(这通常出现在使用 tg3 驱动的网卡上)。
如何加载缺失的固件
如上所述,大部分情况下,没有固件设备就无法工作;有时没有固件不会影响基本的功能,但增强功能就无法使用。
如果没有设备驱动程序所需的固件,debian-installer 将显示对话框要求加载缺失的固件。假如选取了选项,debian-installer 将扫描现有设备松散的固件文件或包含固件的软件包。如果搜索到,固件会被复制到正确的位置 /firmware
,然后加载驱动程序模块。
具体哪些设备会被扫描和支持哪个文件系统,取决于系统的架构、安装方法和安装的阶段。特别是在安装的早期阶段,从 FAT 格式的软盘或 U 盘加载固件更容易成功。在 i386 和 amd64 上固件可以从 MMC 或 SD 卡加载。
假如了解设备毋需固件也可以工作,或者设备在安装时并不需要使用,您可以跳过加载固件。
debian-installer 只提示安装过程中加载的内核模块所需的固件。并不是所有驱动程序都包含在 debian-installer 中,特别是 radeon 没有,因此这意味着一些设备在安装结束时的功能可能与开始时没有什么不同。因此,您的一些硬件可能没有充分发挥其潜力。如果您怀疑是这样,或者只是好奇,那么可以检查 dmesg 命令在新引导的系统上的输出并搜索“固件”名称。
准备介质
官方的 CD 映像不含商用的固件。这些固件通常是从移动介质,比如 U 盘来加载。另外,包含这些商用固件的非官方的 CD 位于 http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/。制作这种 U 盘(或者其他的介质,比如硬盘分区或者软盘)时,固件文件或软件包必须放置在文件系统的根目录或者名为 /firmware
的目录下。推荐使用 FAT 文件系统,因为在安装过程的早期阶段它肯定能被支持。
大多数固件的压缩包和 zip 文件可以从这里获得: http://cdimage.debian.org/cdimage/unofficial/non-free/firmware/
下载对应版本的压缩包或 zip 文件,然后解压到介质的文件系统里面。
如果您需要的固件没有包含在压缩包里面,可以从档案库(non-free 部分)下载特定的固件。以下概要列出大多数固件软件包,但不保证完整,有些还是非固件软件包: http://packages.debian.org/search?keywords=firmware
也可以复制单独的固件文件到介质。要求不严的固件还可以从已经安装的系统或硬件制造商那里获得。
固件和安装好的系统
任何安装期间加载的固件会自动被复制到安装好的系统。多数情况下这可以保证需要固件的设备可以在系统重新启动之后正常工作。然而,如果安装好的系统运行在与安装程序不同的内核版本,有可能由于版本的偏差造成固件不能加载。
如果固件从一个固件软件包加载,debian-installer 会为安装好的系统也安装该软件包,并自动添加软件包仓库的 non-free 部分到 APT 的 sources.list。这样做的优点在于如果有固件的新版本存在会自动更新。
如果安装过程中跳过加载固件,相关的设备可能无法在安装好的系统中工作,直到手动安装好固件或软件包。
如果固件从不严格的固件文件加载,复制到安装好的系统的固件将不会自动更新,除非对应的固件软件包(如果有的话)在系统安装之后安装。
进入系统之后如何安装固件?
如果安装的时候跳过了加载缺失的固件文件,在系统安装完成之后,只需要将固件文件放在 /lib/firmware/
目录下即可。如果目录不存在,请新建目录 makir /lib/firmware/ 。
/lib/firmware/ 目录不存在也可能是没有安装 firmware。请安装 apt-get install firmware-*
。再将固件文件放在 /lib/firmware/ 目录下即可。
参考链接
Debian GNU/Linux 安装手册 <https://www.debian.org/releases/stable/i386/>
_Intel wifi 固件下载 1 <https://wireless.wiki.kernel.org/en/users/Drivers/iwlwifi>
_Intel wifi 固件下载 2 <https://github.com/OpenELEC/iwlwifi-firmware/tree/master/firmware>
_
在终端中把命令放到后台执行
##########################
在终端中执行命令时,在程序命令之后加上 &
字符,可以启动一个程序并将它放到后台运行。
可以用 jobs
命令查看后台执行程序的列表,用 fg %1
将程序拉到前台来(1 为后台的编号,默认为 1 所有 fg = fg %1),这样就可以用 Ctrl-c 来杀死程序。
[me@linuxbox ~]$ xlogo &
[1] 28236
[me@linuxbox ~]$ jobs
[1]+ Running xlogo &
[me@linuxbox ~]$ fg %1
xlogo
如果在输入命令时,忘记加上 &
字符,又或者在程序执行过程中才发现需要很长的时间执行完程序,那么这时怎么将程序放到后台去执行呢?
只需要两步:
- Ctrl-z 停止当前进程,并移动到后台。
bg %1
在后台执行程序
系统备份与还原
############################
在一个折腾无极限的年纪,手残、尝鲜、测试…谁都不能保证你的 Linux 每次都能顺利启动,提前做好系统备份会是一个明智的选择。
网上有好多的 tar
命令备份方法,但是按方法测试后一次都没有成功过。
转而求其次,使用 dd
命令备份系统,简单直接。缺点是装系统时需要提前设计分区,系统备份需要占用单独的分区。
操作步骤
- 使用
df -h
命令查看系统分区,确定根目录的磁盘号 - 使用
dd if=/dev/sda of=/dev/sdb
命令备份磁盘分区,sda 为根分区,sdb 为备份分区
两步系统就备份完成,如果需要还原系统,只需要颠倒分区位置 dd if=/dev/sdb of=/dev/sda
。
未找到命令的解决办法
####################################
由于 Linux 的发行版多种多样,有时在终端中输入部分常用命令会找不到,如下:
[Linux]$ fdisk
bash: Command 'fdisk' not found
原因分析:
首先应该使用 :ref:whereis 命令 <cmd_whereis>
查看系统中是否包含该命令,如果没有找到命令则需要安装。
由于部分命令运行时需要 root 权限,在某些发行版中会将其放入 /sbin
目录中,而在命令搜索路径 $PATH
中又不包含 /sbin
目录,所以会导致未找到命令。
# 查找 fdisk 命令的路径
[Linux]$ whereis fdisk
fdisk: /sbin/fdisk /usr/share/man/man8/fdisk.8.gz
# 查看命令搜索路径
[Linux]$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
解决方法:
方法一: 使用 su -
命令直接切换到 root 用户及其环境变量中,注意 su 命令后要带有中划线。
方法二: 使用 <Ctrl+Alt+F1-7> 切换虚拟终端,以 root 用户登陆。
方法三: 将没有的命令路径添加到 $PATH
变量中(如果想永久生效请将 export PATH=/sbin
添加到配置文件中)。
# 临时修改变量
[Linux]$ PATH=$PATH:/sbin
通过 GitHub 发布网站
##########################
发布一个网页并不是三言两语就能简单说明的,这主要是因为有太多方法可以去完成。现在,只需 3 步就可以通过 Github 在线发布网站。
-
创建一个新的资源库(repository)来存放网页文件。
资源库名为 name.github.io(name 为资源库名)。
-
将你的网页文件上传到资源库。
确保资源库中有一个 index.html 首页文件。
-
访问 name.github.io 来查看网站(资源库名为 gavin,请访问 gavin.github.io)。
网站可能需要几分钟才能投入使用。如果它不能立即工作,请等待几分钟再试一次。
想要了解更多,请看 GitHub Pages Help
_ 。
本文摘自 DMN web docs
_ 。
… _GitHub Pages Help
: https://help.github.com/categories/github-pages-basics/
… _DMN web docs
: https://developer.mozilla.org/zh-CN/docs/Learn/Getting_started_with_the_web/Publishing_your_website
隐藏 lost+found 文件夹
############################
使用 ext2/ext3/ext4 格式化硬盘后,当挂载硬盘时会自动产生一个 lost+found/
目录,用来存放 fsck 过程中部分修复的文件。在日常使用系统时,这个文件夹可以忽略,所以最好在文件管理器中隐藏 lost+found/
文件夹。
在 LInux 中主要有两种隐藏文件的方法:
- 重命名文件法,通过以点(“.”)前缀重命名一个文件或文件夹的方式隐藏文件
- 非重命名文件法,通过
.hidden
文件指定隐藏的文件或文件夹
因为 lost+found/
是系统自动创建的文件,所以使用第二种方法隐藏文件。
.hidden 文件
一些文件管理器,比如 Nautilus、Nemo、Caja 和 Thunar,支持一种很原始的方法来隐藏文件,不需要重命名。只需在想要隐藏文件的地方创建一个 .hidden
文件,然后把想隐藏的文件名和文件夹名一行一个地加进来。
.hidden 文件只需要写入文件名,如果要隐藏文件夹,末尾不能带有 ``/`` 目录分隔符。
将 ISO 镜像设置为本地源
############################
软件源就是一个应用程序的安装库,很多很多的应用软件都在这个库里面。它可以是网络服务器、光盘,甚至是硬盘上的一个目录。通常大家都会设置网络源,但在一些特殊情况下(如没有网卡驱动),需要从本地安装软件或驱动,这时将 ISO 文件设置为软件源就很实用。
Debian
以下操作需要 root权限。
- 挂载 iso 文件:
mount -t iso9660 -o loop /mnt/debian-x.x.x-amd64-DVD-1.iso /media/cdrom/
注意:挂载到的目录,和步骤 3 使用的是同一个目录。
-
备份 /etc/apt/sources.list,并清空(注释)文件内容。
-
添加本地源:
apt-cdrom -m -d /media/cdrom/ add
- 更新一下:
apt-get update
Centos(待测试)
操作系统:CentOS 5.5 ,需要 root 权限。
- 挂载 iso 文件到挂载点:
mount -o loop /mnt/iso/CentOS5.iso /mnt/cdrom
- 备份并修改 yum 的配置文件:
# 备份文件
cd /etc/yum.repos.d/
cp CentOS-Media.repo CentOS-Media.repo.bak
# 修改文件
vi CentOS-Media.repo
[c5-media]
name=CentOS-$releasever - Media
baseurl=file:///mnt/ # 表明 yum 源在 /mnt 目录下,其它的源注释掉
# baseurl=file:///media/CentOS/
# file:///media/cdrom/
# file:///media/cdrecorder/
gpgcheck=1
enabled=1 # 启用 yum
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
- 清除缓存
yum clean all
yum list
SSH 断开后使进程仍在后台运行
#######################################
对于 Linux 运维,经常会使用 ssh 登录到服务器。如果任务需要很长时间或不间断运行,在关闭终端窗口或网络不稳定的情况下,任务就会中断。
当然这只对于普通程序,不包括如 mysqld、httpd 这样的守护进程。
原因分析:
[root@DigMouse ~]# ping www.baidu.com > /dev/null &
[1] 21945
[root@DigMouse ~]# pstree -H 21945
systemd─┬─AliYunDun───17*[{AliYunDun}]
├─AliYunDunUpdate───3*[{AliYunDunUpdate}]
├─acpid
├─2*[agetty]
├─aliyun-service───5*[{aliyun-service}]
├─atd
├─cron
├─dbus-daemon
├─nscd─┬─{nscd) S 1 434 43
│ └─9*[{nscd}]
├─ntpd───ntpd
├─python3
├─rpcbind
├─rsyslogd─┬─{in:imklog}
│ ├─{in:imuxsock}
│ └─{rs:main Q:Reg}
├─sshd───sshd───bash─┬─ping
│ └─pstree
├─systemd-journal
├─systemd-logind
├─systemd-network
├─systemd-udevd
├─vsftpd
└─wrapper─┬─java───13*[{java}]
└─{wrapper}
当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。
从上面的例子可以看出当前所处的 bash 是 sshd 的子进程,当 ssh 断开连接时,HUP 信号会影响到它下面的所有子进程,包括 ping 进程。
解决思路:
- 让进程运行在新的 session(会话)里即不属于此终端的子进程。
- 让进程忽略 HUP 信号
解决方法:
- nohup 命令
========================
功能:不挂断地运行命令,忽略HUP信号。
语法:nohup command &
实例:
[root@DigMouse ~]# nohup ping www.baidu.com &
[1] 22050
[root@DigMouse ~]# nohup: ignoring input and redirecting stderr to stdout
[root@DigMouse ~]# ls
nohup.out
[root@DigMouse ~]# cat nohup.out
PING www.wshifen.com (103.235.46.39) 56(84) bytes of data.
64 bytes from 122.225.57.246: icmp_seq=1 ttl=56 time=48.6 ms
64 bytes from 122.225.57.246: icmp_seq=2 ttl=56 time=47.8 ms
64 bytes from 122.225.57.246: icmp_seq=3 ttl=56 time=49.9 ms
64 bytes from 122.225.57.246: icmp_seq=4 ttl=56 time=49.5 ms
# 从另一个终端执行以下命令
[root@DigMouse ~]# ps -ef | grep ping
root 22050 21736 0 21:01 pts/0 00:00:00 ping www.baidu.com
root 22070 21736 0 21:04 pts/0 00:00:00 grep ping
关闭此终端,打开另一个终端使用 ps 命令,查看到后台有 ping 进程在运行。
终端输出将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出将重定向到 $HOME/nohup.out 文件中。
- setsid命令
=========================
功能:在新的会话中运行程序
语法:setsid command
实例:
[root@DigMouse ~]# setsid ping www.baidu.com > /dev/null
[root@DigMouse ~]# ps -ef | grep ping
UID PID PPID C STIME TTY TIME CMD
root 22146 1 0 21:14 ? 00:00:00 ping www.baidu.com
root 22152 21736 0 21:15 pts/0 00:00:00 grep ping
[root@DigMouse ~]#
从上例可以看出 ping 进程的 PID 是 22146,进程的父 ID(PPID) 是 init 而不是当前终端的进程 ID,可与 nohup 比较。
- 将"&"也放入“()”内执行命令
===============================
将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行
[root@DigMouse ~]# (ping www.baidu.com > /dev/null &)
[root@DigMouse ~]# ps -ef | grep ping
root 22202 1 0 21:22 pts/0 00:00:00 ping www.baidu.com
root 22204 21736 0 21:22 pts/0 00:00:00 grep ping
[root@DigMouse ~]#
进程的父 ID 是 init 而不是当前终端的进程 ID,因而关闭终端无任何影响。
- disown 命令
================================
用 disown -h jobspec 来使某个作业忽略 HUP 信号。
用 disown -ah 来使所有的作业都忽略 HUP 信号。
用 disown -rh 来使正在运行的作业忽略 HUP 信号。
当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用 jobs 来查看它,但是依然能够用 ps -ef 查找到它。
但是还有一个问题,这种方法的操作对象是作业,如果我们在运行命令时在结尾加了"&"来使它成为一个作业并在后台运行,那么就万事大吉了,我们可以通过 jobs 命令来得到所有作业的列表。但是如果并没有把当前命令作为作业来运行,如何才能得到它的作业号呢?答案就是用 CTRL-z(按住Ctrl键的同时按住z键)了!
CTRL-z 的用途就是将当前进程挂起(Suspend),然后我们就可以用 jobs 命令来查询它的作业号,再用 bg jobspec 来将它放入后台并继续运行。
需要注意的是,如果挂起会影响当前进程的运行结果,请慎用此方法。
# 将程序放入后台,暂停执行(挂起进程)
[root@DigMouse ~]# ping www.baidu.com > /dev/null
^Z
[1]+ Stopped ping www.baidu.com > /dev/null
[root@DigMouse ~]# jobs
[1]+ Stopped ping www.baidu.com > /dev/null
# 执行后台的作业
[root@DigMouse ~]# bg %1
[1]+ ping www.baidu.com > /dev/null &
[root@DigMouse ~]# jobs
[1]+ Running ping www.baidu.com > /dev/null &
# 此时 jobs 还是能看到 ping 后台任务的。
[root@DigMouse ~]# ps -ef | grep ping
root 22256 21736 0 21:32 pts/0 00:00:00 ping www.baidu.com
root 22273 21736 0 21:35 pts/0 00:00:00 grep ping
[root@DigMouse ~]# disown -h %1
# 需要断开链接后,重新登录
[root@DigMouse ~]# ps -ef | grep ping
root 22256 1 0 21:32 ? 00:00:00 ping www.baidu.com
root 22390 22381 0 21:50 pts/1 00:00:00 grep ping
- screen 命令(未做测试)
==============================
此命令非常强大。如果非常多的命令都需要忽略 HUP 命令,screen 可以解决这一问题。screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。
- 用 screen -dmS session name 来建立一个处于断开模式下的会话(并指定其会话名)。
- 用 screen -list 来列出所有会话。
- 用 screen -r session name 来重新连接指定会话。
- 用快捷键 CTRL-a d 来暂时断开当前会话。
此时 bash 是 screen 的子进程,而 screen 是 init(PID为1)的子进程。那么当 ssh 断开连接时,HUP 信号自然不会影响到 screen 下面的子进程了。
disown, & 和 nohup 的区别
总结来说:
&: 将进程置于后台,使 Shell 不用等待它的结束而继续接受用户输入(stdin)。
disown: 将进程从 jobs 列表中移除, 但依然与 Shell 有连接
nohup: 将进程与父 Shell 完全脱离,且子进程不会接受 NOHUP 信号,并不能用 fg 或者 jobs 命令找到它。
关闭终端响铃
####################################
在使用终端自动补全功能时会发出讨厌的嘟嘟声,可通过编辑配置文件 /etc/inputrc
关闭终端响铃:
# 取消该行的注释,或添加该行
[Linux]# vim /etc/inputrc
set bell-style none
关闭 vi 响铃
在 vi 的配置文件 /etc/virc
中,添加一行:
set vb t_vb=
注意:vim 的配置文件是 /etc/vimrc
。
xfce4+i3 环境配置
####################################
i3wm 是一个极简主义的平铺管理器,它能以无缝、不重叠的方式智能地排列屏幕上的窗口。其他平铺管理器包括 xmonad 和 wmii 等。
i3wm 窗口管理器底层使用 Xorg server,xfce4.16 也使用 Xorg server 底层操作,所以两者可以无缝的衔接。
i3wm 状态栏配置繁琐,直接使用 xfce4 的状态栏配置,简洁高效。
操作环境要求:
- Debian11 操作系统
- xfce4.16 桌面环境
状态栏配置
启动 i3 窗口管理器后,默认的配置文件目录是 ~/.config/i3/config
。
1. 注释掉 i3 默认的状态栏配置
# bar {
# status_command i3status
# }
2. 添加 xfce4 状态栏
# 添加 xfce4 状态栏
exec --no-startup-id xfce4-panel --disable-wm-check
# 启动 xfce4 电源管理模块
exec --no-startup-id xfce4-power-manager
一些细节调整:
- 在状态栏中加入多桌面,并设置成按钮,关闭桌面名显示。
- 输入法图标强制大小显示。
- 时间设置成 24 小时带秒显示。
桌面背景
xfce4 默认使用 LightDM 登陆管理器。修改登陆管理器背景后会同步到桌面中。
/etc/lightdm/lightdm-gtk-greeter.conf
-----------------------------------------------------------
[greeter]
background=/usr/share/pixmaps/bg.jpg
触控板点击和自然滚动
/usr/share/X11/xorg.conf.d/40-libinput.conf
-----------------------------------------------------------
Section "InputClass"
Identifier "libinput touchpad catchall"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "libinput"
# 添加以下两行,第一行开启点击,第二行双指自然滚动
Option "Tapping" "on"
Option "NaturalScrolling" "true"
EndSection
已知问题
- xfce4 锁屏管理器有 bug,锁屏后不能登陆。在设置禁用锁屏功能
- Debian11 暂时不支持 i3-gaps,设置窗口间隙。