在一个充满新工具和多样化开发环境的世界里,任何开发人员或工程师学习一些基本的系统管理命令几乎是必要的。特定的命令和包可以帮助开发人员组织、排除故障和优化他们的应用程序,并且在出现问题时,可以向操作员和系统管理员提供有价值的诊断信息。
无论您是新的开发人员还是想要管理自己的应用程序,以下 20 个基本的系统管理命令都可以帮助您更好地了解您的应用程序。 它们还可以帮助您向系统管理员描述问题,以排除为什么应用程序可能在本地工作但在远程主机上不工作的原因。 这些命令适用于 Linux 开发环境、容器、虚拟机 (VM) 和裸机。
1. curl
curl 传输 URL。 使用此命令来测试应用程序的端点或与上游服务端点的连接。 curl 可用于确定您的应用程序是否可以访问另一项服务(例如数据库),或检查您的服务是否健康。
例如,假设您的应用程序抛出一个 HTTP 500 错误,表明它无法访问 MongoDB 数据库
$ curl -I -s myapplication:5000
HTTP/1.0 500 INTERNAL SERVER ERROR
-I 选项显示标头信息,-s 选项使响应正文静音。 从您的本地桌面检查数据库的端点
$ curl -I -s database:27017
HTTP/1.0 200 OK
那么问题可能是什么? 检查您的应用程序是否可以从应用程序主机访问数据库以外的其他位置
$ curl -I -s https://open-source.net.cn
HTTP/1.1 200 OK
这似乎没问题。 现在尝试从应用程序主机访问数据库。 您的应用程序正在使用数据库的主机名,因此首先尝试该主机名
$ curl database:27017
curl: (6) Couldn't resolve host 'database'
这表明您的应用程序无法解析数据库,因为数据库的 URL 不可用,或者主机(容器或 VM)没有可用于解析主机名的域名服务器。
2. python -m json.tool / jq
发出 curl 后,API 调用的输出可能难以阅读。 有时,您可能需要对 JSON 输出进行美化打印,以找到特定的条目。 Python 有一个内置的 JSON 库可以帮助您。 您可以使用 python -m json.tool 来缩进和组织 JSON。 要使用 Python 的 JSON 模块,请将 JSON 文件的输出通过管道传递到 python -m json.tool 命令。
$ cat test.json
{"title":"Person","type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"age":{"description":"Age in years","type":"integer","minimum":0}},"required":["firstName","lastName"]}
要使用 Python 库,请使用 -m(模块)选项将输出通过管道传递到 Python。
$ cat test.json | python -m json.tool
{
"properties": {
"age": {
"description": "Age in years",
"minimum": 0,
"type": "integer"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
"required": [
"firstName",
"lastName"
],
"title": "Person",
"type": "object"
}
对于更高级的 JSON 解析,您可以安装 jq。 jq 提供了一些选项,可以从 JSON 输入中提取特定的值。 要像上面的 Python 模块一样进行美化打印,只需将 jq 应用于输出即可。
$ cat test.json | jq
{
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": [
"firstName",
"lastName"
]
}
3. ls
ls 列出目录中的文件。 系统管理员和开发人员经常发出此命令。 在容器领域,此命令可以帮助确定您的容器映像的目录和文件。 除了查找您的文件之外,ls 还可以帮助您检查您的权限。 在下面的示例中,由于权限问题,您无法运行 myapp。 当您使用 ls -l 检查权限时,您会意识到权限在 -rw-r--r-- 中没有“x”,这仅是读取和写入权限。
$ ./myapp
bash: ./myapp: Permission denied
$ ls -l myapp
-rw-r--r--. 1 root root 33 Jul 21 18:36 myapp
4. tail
tail 显示文件的最后一部分。 您通常不需要每一行日志来排除故障。 相反,您想检查日志中关于您最近对应用程序的请求的内容。 例如,您可以使用 tail 来检查当您向 Apache HTTP 服务器发出请求时,日志中发生了什么。

opensource.com
-f 选项指示“follow”选项,该选项在将日志行写入文件时输出日志行。 该示例有一个后台脚本,每隔几秒钟访问一次端点,并且日志记录该请求。 您也可以使用 tail 来查看文件的最后 100 行,而不是实时跟踪日志, 使用 -n 选项。
$ tail -n 100 /var/log/httpd/access_log
5. cat
cat 连接并打印文件。 您可能会发出 cat 来检查您的依赖项文件的内容,或者确认您已经在本地构建的应用程序的版本。
$ cat requirements.txt
flask
flask_pymongo
上面的示例检查您的 Python Flask 应用程序是否已将 Flask 列为依赖项。
6. grep
grep 搜索文件模式。 如果您在另一个命令的输出中寻找特定的模式,grep 会突出显示相关的行。 使用此命令搜索日志文件、特定进程等等。 如果您想查看 Apache Tomcat 是否启动,您可能会被行数淹没。 通过将该输出通过管道传递到 grep 命令,您可以隔离指示服务器启动的行。
$ cat tomcat.log | grep org.apache.catalina.startup.Catalina.start
01-Jul-2017 18:03:47.542 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 681 ms
7. ps
ps 命令,是 procps-ng 包的一部分,该包提供了用于调查进程 ID 的有用命令,显示正在运行的进程的状态。 使用此命令来确定正在运行的应用程序或确认预期的进程。 例如,如果您想检查正在运行的 Tomcat Web 服务器,您可以使用 ps 及其选项来获取 Tomcat 的进程 ID。
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 2 18:55 ? 00:00:02 /docker-java-home/jre/bi
root 59 0 0 18:55 pts/0 00:00:00 /bin/sh
root 75 59 0 18:57 pts/0 00:00:00 ps -ef
为了更具可读性,请使用 ps 并将其通过管道传递到 grep。
$ ps -ef | grep tomcat
root 1 0 1 18:55 ? 00:00:02 /docker-java-home/jre/bi
8. env
env 允许您设置或打印环境变量。 在进行故障排除时,您可能会发现检查错误的环境变量是否阻止您的应用程序启动很有用。 在下面的示例中,此命令用于检查您的应用程序主机上设置的环境变量。
$ env
PYTHON_PIP_VERSION=9.0.1
HOME=/root
DB_NAME=test
PATH=/usr/local/bin:/usr/local/sbin
LANG=C.UTF-8
PYTHON_VERSION=3.4.6
PWD=/
DB_URI=mongodb://database:27017/test
请注意,该应用程序正在使用 Python,并且具有连接到 MongoDB 数据库的环境变量。
9. top
top 显示和更新排序的进程信息。 使用此监视工具来确定哪些进程正在运行以及它们消耗了多少内存和 CPU。 一种常见的情况是,您运行一个应用程序,但它在一分钟后死亡。 首先,您检查应用程序的返回错误,这是一个内存错误。
$ tail myapp.log
Traceback (most recent call last):
MemoryError
您的应用程序真的内存不足了吗? 为了确认,请使用 top 来确定您的应用程序消耗了多少 CPU 和内存。 当发出 top 命令时,您会注意到一个 Python 应用程序正在使用大部分 CPU,并且其内存使用量不断攀升,您怀疑它是您的应用程序。 在它运行时,您点击“C”键以查看完整的命令并反向工程该进程是否是您的应用程序。 结果证明它是您的内存密集型应用程序 (memeater.py)。 当您的应用程序耗尽内存时,系统会使用内存不足 (OOM) 错误将其终止。

opensource.com

opensource.com
除了检查您自己的应用程序之外,您还可以使用 top 来调试利用 CPU 或内存的其他进程。
10. netstat
netstat 显示网络状态。 此命令显示正在使用的网络端口及其传入连接。 但是,netstat 不是 Linux 开箱即用的。 如果您需要安装它,您可以在 net-tools 包中找到它。 作为在本地进行实验或将应用程序推送到主机的开发人员,您可能会收到一个错误,指出端口已被分配或地址已被使用。 使用带有协议、进程和端口选项的 netstat 表明 Apache HTTP 服务器已经在下面的主机上使用端口 80。

opensource.com
11. ip
如果 ip 地址在您的主机上不起作用,则必须使用 iproute2 包安装它。 子命令 address(或简称 ip a)显示您的应用程序主机上的接口和 IP 地址。 您可以使用 ip address 来验证您的容器或主机的 IP 地址。 例如,当您的容器连接到两个网络时,ip address 可以显示哪个接口连接到哪个网络。 对于简单的检查,您可以始终使用 ip address 命令来获取主机的 IP 地址。 下面的示例显示 Web 层容器在接口 eth0 上的 IP 地址为 172.17.0.2。
$ ip address show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether d4:3b:04:9e:b2:c2 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.3/27 brd 10.1.1.31 scope global dynamic noprefixroute eth0
valid_lft 52072sec preferred_lft 52072sec
12. lsof
lsof 列出与您的应用程序关联的打开文件。 在某些 Linux 机器映像上,您需要使用 lsof 包安装 lsof。 在 Linux 中,几乎所有与系统的交互都被视为文件。 因此,如果您的应用程序写入文件或打开网络连接,lsof 将反映该交互作为一个文件。 与 netstat 类似,您可以使用 lsof 来检查监听端口。 例如,如果您想检查端口 80 是否正在使用中,您可以使用 lsof 来检查哪个进程正在使用它。 在下面,您可以看到 httpd (Apache) 在端口 80 上监听。 您还可以使用 lsof 来检查 httpd 的进程 ID,检查 Web 服务器的二进制文件所在的 /usr/sbin/httpd。

opensource.com
打开文件列表中的打开文件的名称有助于查明进程的来源,特别是 Apache。
13. df
您可以使用 df(显示可用磁盘空间)来排除磁盘空间问题。 当您在容器编排器上运行您的应用程序时,您可能会收到一条错误消息,指示容器主机上缺少可用空间。 虽然磁盘空间应由系统管理员管理和优化,但您可以使用 df 来确定目录中的现有空间,并确认您是否确实没有空间。
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 7.7G 0 7.7G 0% /dev
/dev/mapper/RHEL-Root 50G 16G 35G 31% /
/dev/nvme0n1p2 3.0G 246M 2.8G 9% /boot
/dev/mapper/RHEL-Home 100G 88G 13G 88% /home
/dev/nvme0n1p1 200M 9.4M 191M 5% /boot/efi
/dev/sdb1 114G 55G 54G 51% /run/media/tux/red
-h 选项以人类可读的格式打印信息。 默认情况下,如示例所示,df 提供根目录下所有内容的结果,但您也可以通过将目录作为命令的一部分来限制结果(例如 df -h /home)。
14. du
要检索有关哪些文件占用目录中磁盘空间的更详细的信息,您可以使用 du 命令。 例如,如果您想找出哪个日志占用了 /var/log 目录中的最多空间,您可以使用 du 以及 -h(人类可读)选项和 -s 选项(总大小)。
$ du -sh /var/log/*
1.8M /var/log/anaconda
384K /var/log/audit
4.0K /var/log/boot.log
0 /var/log/chrony
4.0K /var/log/cron
4.0K /var/log/maillog
64K /var/log/messages
上面的例子展示了 /var/log 目录下最大的目录是 /var/log/audit。你可以结合使用 du 和 df 命令来确定应用程序主机上磁盘空间的使用情况。
15. id
要检查运行应用程序的用户,可以使用 id 命令来返回用户身份。下面的例子使用 Vagrant 来测试应用程序并隔离其开发环境。当你登录到 Vagrant box 后,如果你尝试安装 Apache HTTP Server (一个依赖项),系统会提示你不能以 root 身份执行该命令。要检查你的用户和组,执行 id 命令,你会发现你以 "vagrant" 用户身份在 "vagrant" 组中运行。
$ dnf -y install httpd
Loaded plugins: fastestmirror
You need to be root to perform this command.
$ id
uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
要更正此问题,你必须以超级用户身份运行该命令,这将提供更高的权限。
16. chmod
当你第一次在主机上运行应用程序二进制文件时,你可能会收到 "permission denied"(权限被拒绝)的错误消息。正如 ls 命令的示例中所示,你可以检查应用程序二进制文件的权限。
$ ls -l
total 4
-rw-rw-r--. 1 vagrant vagrant 34 Jul 11 02:17 test.sh
这表明你没有执行权限(没有 "x")来运行该二进制文件。 chmod 可以更正权限,使你的用户能够运行该二进制文件。
$ chmod +x test.sh
[vagrant@localhost ~]$ ls -l
total 4
-rwxrwxr-x. 1 vagrant vagrant 34 Jul 11 02:17 test.sh
正如示例中所示,这会使用执行权限更新权限。现在,当你尝试执行你的二进制文件时,应用程序不会抛出 permission-denied 错误。Chmod 在你将二进制文件加载到容器中时也可能很有用。它可以确保你的容器具有执行二进制文件的正确权限。
17. dig / nslookup
域名服务器 (DNS) 帮助将 URL 解析为一组应用服务器。但是,你可能会发现 URL 无法解析,这会导致应用程序的连接问题。例如,假设你尝试从应用程序的主机访问 mydatabase URL 上的数据库。相反,你收到一个 "cannot resolve"(无法解析)错误。要进行故障排除,你可以尝试使用 dig (DNS 查找实用程序) 或 nslookup (查询 Internet 名称服务器) 来找出应用程序似乎无法解析数据库的原因。
$ nslookup mydatabase
Server: 10.0.2.3
Address: 10.0.2.3#53
** server can't find mydatabase: NXDOMAIN
使用 nslookup 显示 mydatabase 无法解析。尝试使用 dig 解析会产生相同的结果。
$ dig mydatabase
; <<>> DiG 9.9.4-RedHat-9.9.4-50.el7_3.1 <<>> mydatabase
;; global options: +cmd
;; connection timed out; no servers could be reached
这些错误可能由许多不同的问题引起。如果你无法调试根本原因,请联系你的系统管理员进行进一步调查。对于本地测试,此问题可能表明你的主机的域名服务器配置不正确。要使用这些命令,你需要安装 BIND Utilities 包。
18. firewall-cmd
传统上,防火墙是在 Linux 上使用 iptables 命令配置的,尽管它仍然普遍存在,但实际上它已经在很大程度上被 nftables 替代了。firewall-cmd 是 nftables 的一个友好的前端,并且是许多发行版默认附带的。此命令可帮助你设置规则,以控制你的计算机允许的网络流量(包括传出和传入)。这些规则可以分组到区域中,因此你可以根据需要快速轻松地从一组规则切换到另一组规则。
命令语法很简单。 你使用该命令和一些选项,所有这些选项都以有助于你几乎构造可读句子的方式命名。 例如,要查看你当前所在的区域
$ sudo firewall-cmd --get-active-zones``
corp
interfaces: ens0
dmz
interfaces: ens1
在此示例中,你的计算机具有两个网络设备,一个分配给 corp
区域,而另一个分配给 dmz
区域。
要查看每个区域允许的内容,可以使用 --list-all
选项
$ sudo firewall-cmd --zone corp --list-all
corp
target: default
interfaces: ens0
services: cockpit dhcpv6-client ssh
ports:
protocols:
[...]
添加服务同样容易
$ sudo firewall-cmd --add-service http --permanent
$ sudo firewall-cmd --reload
与 firewall-cmd 的交互旨在直观,并且它具有广泛的预定义服务集合,以及直接编写 nft 规则的功能。 一旦开始使用 firewall-cmd,你就可以下载我们的 firewall-cmd 速查表 以帮助你记住其最重要的选项。
19. sestatus
你通常会发现企业管理的应用程序主机上强制执行 SELinux(一种 Linux 安全模块)。 SELinux 为主机上运行的进程提供最小权限访问,从而防止潜在的恶意进程访问系统上的重要文件。 在某些情况下,应用程序需要访问特定文件,但可能会引发错误。 要检查 SELinux 是否阻止了应用程序,请使用 tail 和 grep 在 /var/log/audit 日志中查找 "denied" 消息。 否则,你可以使用 sestatus 检查该 box 是否启用了 SELinux。
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
上面的输出表明应用程序的主机已启用 SELinux。 在你的本地开发环境中,你可以更新 SELinux 以使其更加宽松。 如果你需要远程主机的帮助,你的系统管理员可以帮助你确定允许你的应用程序访问所需文件的最佳实践。 如果你经常与 SELinux 交互,请下载我们的 SELinux 速查表 以供快速参考。
20. history
当你发出如此多的命令进行测试和调试时,你可能会忘记有用的命令! 每个 shell 都有一个 history 命令的变体。 它显示了自会话开始以来你发出的命令的历史记录。 你可以使用 history 记录你用于对应用程序进行故障排除的命令。 例如,当你在此文章的过程中发出 history 命令时,它会显示你尝试和学习的各种命令。
$ history
1 clear
2 df -h
3 du
如果你想执行以前历史记录中的命令,但又不想重新输入,该怎么办? 在命令编号前使用 ! 重新执行。

opensource.com
当确定你的应用程序在一个开发环境中工作,但在另一个开发环境中可能不工作的原因时,基本命令可以增强你的故障排除专业知识。 许多系统管理员利用这些命令来调试系统问题。 了解一些这些有用的故障排除命令可以帮助你与系统管理员沟通并解决应用程序的问题。
本文最初于 2017 年 7 月发布,并由编辑进行了更新。
31 条评论