服务器常用命令

操作系统

一般来说,我们能接触到桌面级操作系统有 Windows、MacOS、Linux。
在服务器中,操作系统大多是 Linux,而且也大不会是桌面版的 Linux,都是命令行的。

而 Linux 的发行版实在太多了,我们这次讲的,是基于 Ubuntu 这个操作系统。跟真正专业的其它一些 Linux 版本而言,Ubuntu 是不够专业;但是,对我们来说,足够足够足够了。
我第一次接触 Linux 的时候,用的是 Gentoo,就是为了让自己更『专业』一些,似乎也没有什么效果,现在基本忘记了当时学到了些什么。

我们继续吧,从 HTLM+CSS,居然开讲服务器了,是不是有点奇怪?
HTML+CSS 只是一个我们接触技术的触点,不要被其局限住,毕竟,我们主要的目的是将技术的一些基本逻辑,呈现于大家的眼前。最终网站的直接物理载体是服务器,作为一个基本技能,也是绕不开的。

对了,开始的时候,把服务器搞坏了,也很正常,不着急,现在的 VPS 重装一下系统也是很方便的。

软件的安装

服务器上也是由各种软件组成的,有提供 Web 服务的、安全策略的、文本编辑器、带宽状况查看的,只不过都是命令行形式的。

一般称 软件的管理包管理
在 Ubuntu 上,比如我们安装一个软件的名字叫 nano,那么执行命令行 apt-get install nano -y 就可以了。最后一个 -y 表示如果出现询问 (Yes/No) 的就直接同意安装, 如果有多个软件一起安装,就直接 apt-get install app1 app2 app3 就可以了。
有时候,可能需要查询下某个软件是否存在,则使用 apt-cache search name 就可以了。
一般在执行这些之前,会运行一次 apt-get update,表示更新下软件列表的信息。从哪里更新呢?这个配置信息在 /etc/apt/sources.list 里,不过一般情况下,不需要管这个。
如果没有必要,不要去执行 apt-get upgrade,这会对已安装的软件进行(版本的)升级,而服务器跟普通家用电脑的最大区别,它 求稳,没有必要,就不要改变已经安装了的软件的版本。

路径

cd 某个路径,表示进入某个文件夹下面。
ls 则表示显示当前目录的子文件,当然也可以指定某个路径,即 ls 某个路径ls 这个命令有其它一些参数,比如可以试试 ls -hl

在路径中,~ 表示当前用户路径的意思,比如 cd ~,表示进入当前用户的目录,比如 root 用户,进入的是 /root/
如果一个文件夹是以 . 开头的,默认它就是隐藏的文件夹,不少系统的配置信息文件名,是 . 开头的。

命令

服务器上每个软件,都有对应的命令进行操作。
一般情况下,以 ls 这个命令为例,当不清楚它的用途的时候,ls --help 就会显示帮助信息,有些命令可能是直接跟 help 就可以了,而不是 --help,这些都是脚本命令源作者决定和控制的。
以后再接触下去,你也可以自己完成一个直接被调用的命令来。

对了,一般情况下,命令行窗口都会自动尝试补全,连按两下 Tab 键,如果有可能补全的话,就会显示对应的可能。不但对命令如此,路径也是一样。

命令与路径

Python 作为一个广泛使用的脚本语言,基本上是各个 Linux 内的标配,我们在命令行里直接输入 python,就会进入 Python 的交互环境。(注: 『交互环境』是指有输入、有对应输出,比如输入了 1+1,回车键之后,得到 2,这就是产生了交互。)
问题来了,当我们输入 python 的时候,到底发生了什么?这就要涉及到操作系统的基本 环境 的问题。

python 并不是一个直接的路径,它是一个路径的映射,它实际上的路径基本上位于 /usr/bin/python,那这个映射关系是如何产生的?
操作系统内基本上都有 PATH 这个的全局变量,里面是一个列表性质的路径集合,用 : (冒号)分割,比如 PATH 是a:b:c,那么当我们尝试去运行 python 的时候,是会依次查询 a/pythonb/pythonc/python 这样的可执行路径是否存在。
一般 Linux 下默认安装了 Python,而 Windows 则会在自己安装 Python(环境) 的过程中,将 Python 可执行的目录添加到了全局的 PATH 变量中。
比如,我们执行 echo $PATH (打印 PATH 这个变量),会有如下类似的结果:

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Python 是脚本语言、动态语言,那么 Python 程序 是指 Python 本身,还是用 Python 语法写的具体(某个脚本)文件呢?Python 环境 是什么? Python 解释器又是什么?
除了 Python 这门语言之外,其它脚本语言也有类似的问题。我们不要局限于中文对某些 关键词 如何定义,有些时候,同一个词在不同环境下表示不同意思,而不同的词又表达了同样的意思,语言、文字在被作为交流工具的时候,有其不准确的一方面。
就Python 而言,某个 .py 文件 (比如 my_python_script.py) 是在 /usr/bin/python (这个环境)中被运行,实际上相当于完整地运行了 /usr/bin/python my_python_script.py,这时候 /usr/bin/python 可以认为是一个 Python 的环境,当然,它也叫 Python 解释器,就是解释 my_python_script.py后并运行它。
有时候,我们说,安装 Python 程序,其实单纯是指安装了 Python 自身,也就是 Python 解释器,当然这个解释器,默认已经配备了一些基本环境,有常用的 package 以供调用。当我们写了一个 Python 脚本(比如 my_python_script.py),这个脚本文件也叫 Python 程序,更准确的说法,应该是 使用 Python 语法写下的脚本并需要 Python 解释器运行的脚本文件,但日常交流,肯定不会这么说。

PATH 出发,我们讲了一些动态语言的基本概念。还是那句话,技术都是有迹可循的
对了,如果使用计划任务 crontab,或者在某个脚本程序内调用另外的命令行,那很可能需要补全完整的命令路径,这些场合下,/user/bin/python my_script.py 能执行,而直接的 python my_script.py 则未必能执行;因为这种间接的调用,当前的 环境 可能会缺失。

变量

在 Shell (可以简单理解为当前的命令行窗口) 下,是有变量的,以 $ 开头,比如: echo $var 就是打印(显示) var 这个变量。
全局的 PATH 就是一个变量,我们手工安装了某个程序,但不在默认的 PATH 目录列表下,又希望直接调用它,那么可以尝试去修改 PATH 这个变量,比如 export PATH=$PATH:/usr/local/go/bin:/root/.cargo/bin,如果希望它每次都能起作用,那么可以直接 nano ~/.bashrc,将这行命令添加到最后,然后 source ~/.bashrc 触发一次生效。
除了修改已有的变量之外,export 也会需要指定一些特定的变量,比如某些软件的设置项会从系统环境的变量中获得。

文本的编辑

在 Ubuntu 上,一般建议使用 nano 这个文本编辑器就可以了。
nano 不是预装的软件,所以一般要执行 apt-get install nano 进行安装。
如果你会用 Vim,那用 Vim 也很好,但是对于新手而言,或者并不打算在服务器运维上太深入的话,nano 就足够了。以 Vim 而言,新手基本上会有这样的问题: 1,怎么没法输入?2,怎么保存?3,怎么退出……

nano 的操作方式很简单。nano 具体文件的路径,就可以对这个文件进行编辑了,如果不存在,最后保存的时候,就会自动创建。使用快捷键 Control+X,可以退出并进行保存,其它的快捷键,自己有需要时可以进一步了解,比如 Cnmtrol+K,可以删除光标所在的当前行。
文本的编辑,很重要,因为有不少 Linux 中的配置,都需要使用文本编辑器进行修改,而服务器端的 Linux,基本上不会出现可视化的界面操作,都是命令行。

管道 (pipe)

单独一个 |管道符,它在命令行中是比较常见的,比如 A | B,就是执行 A 之后,将结果推送给 B 来执行。
一个实际的例子: cat /var/log/my_log.txt | grep hello| 之前的命令是读取了 my_log.txt 里的数据,然后传给 grep,让它进行搜索,找到有 hello 的文本行。

重定向

> 是重定向(写入)到一个文件,>> 是追加内容到文件,如果文件不存在则创建文件。它们一般是跟其它命令合起来使用的。
我们可以这样试验:

  1. nano test.txt, 然后输入 hello world 进行保存、退出;
  2. cat test.txt > test2.txt,然后再 cat text2.txt 的内容;
  3. cat text.txt >> test3.txt,连续执行两次,然后再 cat text3.txt 的内容。

这个 重定向 是蛮常用的,比如将命令行中获得的结果,暂时存到某个文本文件中,或者追加某些内容到某个配置文件中。

常用的一些命令

cat & head & tail

cat 是直接读取某个文档(整个);head从头部开始,而 tail 则是从尾部开始,都不是整个文档读取。
可以跟一个参数 -n 数字 ,表示读取几行,比如 tail my.txt -n 100 表示从尾部开始,读取 100 行。
多数情况下,会和 | grep 连用,比如我们在查找日志的时候,判断可能哪里出问题,经常会如此用。
对了,如果是 cat 一篇文档的时候,这个文档一般不能太大,比如说上 GB 的,请使用 head 或者 tail 吧。

df 与磁盘

执行 df 可以显示当前服务器的磁盘使用情况,示例如下:

root@my_server:~# df -hl
Filesystem      Size  Used Avail Use% Mounted on
udev            3.9G     0  3.9G   0% /dev
tmpfs           799M   57M  742M   8% /run
/dev/vda1       158G  6.4G  144G   5% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
overlay         158G  6.4G  144G   5% /var/lib/docker/

一般,我们需要了解下当前服务器的硬盘情况,有个软件叫 smartmontools,可以让你了解一般硬盘的情况,比如生产商、通电时间。

sudo apt-get install -y smartmontools
sudo smartctl -a /dev/sda

注意: /dev/sda 中的 dev 是 device (设备) 的意思,sda 是一个硬盘设备,但有些可能是 sdd (SSD 硬盘),有些可能是 vda1 (常见 VPS 上的磁盘),可以自己执行命令 df 查看大概。

top

相当于任务监视器,快捷键 Q 或者 Control+C 可以退出。

ps

查看进程的状况。
你可以分别执行下面三个命令,看效果如何:

ps
ps -A
ps -A u

ps 具体的参数,如果有兴趣,可以自己在使用的过程中,再了解。比如: 查看进程,按内存从大到小, ps -e -o "%C : %p : %z : %a" | sort -k5 -nr;查看进程,按CPU利用率从大到小排序, ps -e -o "%C : %p : %z : %a" | sort -nr

非常有意思的一点,或者说是需要特别提醒一下,不要轻易的在自己服务器上安装第三方监控系统的服务、软件,如果真的使用了,那么请务必不要启用某个进程、服务的过程中暴露敏感信息。一个简单的例子吧,比如电子币 Grin,它的钱包如果要处于监听状态,是需要密码的,假设在启动这个钱包的时候,顺便直接使用了密码作为参数启动起来,那么,进程信息中就能看到这个密码了,而一般情况下,这个密码肯定是你常用的密码之一……

kill

在 ps 命令中,可以获得进程的 ID,也叫 pid (是一个整数), kill 某个pid 可以将对应的进程杀掉。
kill 某个pid -9 强制杀掉,kill 某个pid -HUP 则是通知进程,一般程序如果对此有所对应,则能实现动态更新配置,而不用真正杀死进程。

grep

文本搜索。一般跟 cat、tail、ps 这些命令结合起来使用。

&& 与 ||

cmd1 && cmd2 表示两个命令连续执行, && 在 Javascript 中,也表示 并且 (对应 Pyton 中的 and) 的意思,而 ||或者 (对应 Python 中的 or)。

其它的

自己发现吧,遇到问题的时候,多使用搜索引擎查询就可以了。
毕竟,我们去连接服务器,只是要将其使用起来而已。
全端系列的后续课程,涉及到具体场景的时候,可能会再对服务器中需要了解的技术、操作做进一步的阐述。