面向云工程师的 Linux 命令行终极指南
终端是您通往云基础设施的门户。无论您是通过 SSH 连接到 EC2 实例、排查 Lambda 容器环境故障,还是配置 ECS 任务,都需要熟练地操作类 Unix 系统。本指南涵盖了云工程师日常工作中会用到的基本 Linux 命令行技能。
读完本文,您将对终端、shell、文件系统、权限和软件包管理有基本的了解。您将知道如何使用命令行工具访问远程服务器、排查问题以及自动化工作流程。
先决条件
- 类 Unix 环境(Linux、macOS 或安装了 WSL 的 Windows)
- 熟悉文本编辑器的基本操作
- AWS 账户(可选,用于特定于云的示例)
了解终端和外壳
“终端”、“shell”和“命令行”这几个词经常被混用。让我来解释一下每个术语的含义以及区分它们的重要性。
什么是终端?
终端是一种接收文本输入并呈现文本输出的程序。历史上,终端是物理设备——键盘和显示器连接到大型计算机。如今,您可以使用终端模拟器,例如 Ghostty、iTerm2 或 macOS 内置的“终端”。
打开终端应用程序后,会显示一个提示符,您可以在其中输入命令。终端本身并不解释这些命令,它只负责处理输入和输出。
什么是贝壳?
shell 是实际处理命令的程序。当你输入 echo "Hello World" 并按下回车键时,shell 会读取这段文本,求值,执行,然后返回输出。这个循环称为 REPL:读取 (Read)、求值 (Evaluate)、打印 (Print)、循环 (Loop)。
最常见的两种贝壳是:
- bash (Bourne Again Shell)——大多数 Linux 发行版的默认脚本
- zsh (Z Shell)——现代 macOS 的默认 shell
两者都是功能强大的脚本语言,可以处理变量、条件语句、循环语句和函数。本指南中的所有示例均可在 bash 和 zsh 中运行。
为什么这对 AWS 很重要
当您通过 SSH 连接到 EC2 实例时,实际上是连接到该远程机器上的一个 shell 会话。配置 Lambda 容器镜像时,您通常会编写 shell 脚本。排查 ECS 任务故障时,您需要检查 shell 输出日志。
了解 shell 意味着了解你的云基础设施如何执行命令。
让我来演示一下。打开终端并运行:
$ echo "Hello World"shell 读取此命令,将 echo 识别为程序,传递 "Hello World" 作为参数,并打印结果。现在试试:
$ expr 123456 + 7890您的输出结果显示:
131346shell 可以执行算术运算、字符串操作和复杂的逻辑运算。这就是为什么 shell 脚本是 DevOps 自动化的基础。
文件系统导航
云服务器本质上就是 Linux 机器。你需要浏览它们的文件系统来配置应用程序、查看日志和排查问题。
您当前的位置
你的 shell 始终有一个“工作目录”——也就是你当前所在的文件夹。你可以用以下命令查看:
$ pwd这将打印出你的工作目录。在 macOS 上,你可能会看到:
/Users/cindy在 Linux 系统上:
/home/cindy这是您的用户目录,您的个人文件都存放在这里。
文件路径
文件路径是文件在目录树中位置的文本表示。所有绝对路径都从根目录( / )开始。
在 Linux 系统中,您的用户主目录可能是 /home/achar ,这意味着:
- 从根目录开始
/ - 进入
home目录 - 进入
achar目录
每个目录之间用斜杠分隔。
文件列表
ls 命令列出目录内容:
$ ls您可以看到当前位置的文件和目录。添加标志可以自定义输出:
$ ls -l这将显示包含权限、所有者、文件大小和修改日期的“完整”格式文件。添加 -a 标志可显示隐藏文件:
$ ls -la隐藏文件以点号( . )开头。配置文件,例如 .bashrc 或 .zshrc ,默认情况下是隐藏的。
更改目录
使用 cd 浏览文件系统:
$ cd /var/log这会将您移动到 /var/log ,系统日志就存储在这里。请检查您的新位置:
$ pwd输出显示 /var/log 。
要返回上一级目录,请使用特殊别名 .. :
$ cd ..现在你位于 /var 下。要从任何位置返回你的主目录:
$ cd ~波浪号( ~ )是您主目录的别名。
相对路径与绝对路径
绝对路径以 / 开头,并且可以从任何位置开始使用:
$ cd /var/log/nginx相对路径从您当前的位置开始:
$ cd nginx只有当当前位置存在 nginx 目录时,此方法才有效。
AWS 背景:EC2 日志文件
当您通过 SSH 连接到运行 Web 应用程序的 EC2 实例时,通常需要查看日志。应用程序日志通常位于:
/var/log- 系统和服务日志/var/log/nginx或/var/log/apache2- Web 服务器日志/var/log/mysql- 数据库日志
要查看您的 Web 服务器错误日志:
$ cd /var/log/nginx
$ ls -l你会看到类似 access.log 和 error.log 的文件。无论是在本地还是在远程服务器上进行故障排除,此工作流程都相同。
处理文件
你需要不断地读取、创建、修改和删除文件。让我来为你介绍一些基本命令。
读取文件内容
cat 命令会打印整个文件:
$ cat /etc/hosts这将显示系统的主机名映射。对于大型文件, cat 会将所有内容都显示在屏幕上,导致信息过载。
阅读部分内容
对于大型文件,请使用 head 查看前几行:
$ head -n 10 /var/log/syslog这显示了前 10 行。同样, tail 显示最后几行:
$ tail -n 20 /var/log/syslog-n 标志指定行数。
以下日志文件
在排查运行中应用程序的问题时,您需要查看新写入的日志条目。使用 tail -f :
$ tail -f /var/log/nginx/access.log它会不断显示新行。按 Ctrl+C 停止。
在文件中搜索
grep 命令用于搜索文本模式:
$ grep "error" /var/log/syslog此命令会打印所有包含“error”的行。默认情况下,搜索区分大小写。要进行不区分大小写的搜索:
$ grep -i "error" /var/log/syslog要递归搜索目录:
$ grep -r "database connection" /var/log这会搜索 /var/log 及其子目录中的所有文件。
查找文件
find 命令可以按名称或模式查找文件:
$ find /var/log -name "*.log"此列表显示 /var/log 目录下所有以 .log 结尾的文件。星号 ( * ) 是通配符,可匹配任何字符。
查找最近 24 小时内修改过的文件:
$ find /var/log -mtime -1创建文件
touch 命令会创建空文件:
$ touch test.txt如果 test.txt 已存在, touch 会更新其修改时间戳,但不会更改其内容。
创建目录
使用 mkdir 创建新目录:
$ mkdir project使用一条命令创建嵌套目录:
$ mkdir -p project/src/components-p 标志会根据需要创建父目录。
搬迁和重命名
mv 命令既可以移动文件,也可以重命名文件:
$ mv old-name.txt new-name.txt将文件移动到另一个目录:
$ mv config.json /etc/myapp/复制文件
cp 命令用于复制文件:
$ cp source.txt destination.txt递归复制目录:
$ cp -r source-dir destination-dir删除文件
rm 命令用于删除文件:
$ rm unnecessary-file.txt删除目录及其内容:
$ rm -r old-directory警告: 命令行没有回收站。删除的文件将永久丢失。
AWS 背景:S3 和本地文件
使用 S3 时,您经常需要在 EC2 实例和 S3 存储桶之间同步文件。AWS CLI 使用一些常见的命令:
$ aws s3 cp local-file.json s3://my-bucket/data/此操作会将本地文件复制到 S3。下载方式:
$ aws s3 cp s3://my-bucket/data/config.json ./这些模式与标准文件操作类似。理解本地文件操作能让云存储操作变得直观易懂。
权限和用户
类 Unix 系统拥有强大的权限管理系统。这对于符合 HIPAA 标准的架构至关重要,因为在 HIPAA 标准下,需要限制对受保护健康信息(PHI)的访问。
了解权限字符串
运行 ls -l 后,你会看到类似这样的权限字符串:
-rw-r--r-- 1 achar staff 1234 Nov 13 09:30 file.txt
drwxr-xr-x 5 achar staff 160 Nov 13 09:31 directory让我来分析一下第一串字符串: -rw-r--r--
第一个字符表示类型:
-= 常规文件d= 目录
剩下的九个字符分成三组,每组三个:
- 所有者权限 (读写):文件的所有者
- 组权限 (r--):文件所在组中的用户
- 其他权限 (r--):其他所有人
每个组拥有三种权限:
r= 读取w= 写入x= 执行
短横线( - )表示权限被拒绝。
所以 -rw-r--r-- 的意思是:
- 主人会读写
- 群组成员可以阅读
- 其他人可以阅读
- 没有人能执行
检查您的用户
您的用户名:
$ whoami查看您所属的群组:
$ groups更改权限
chmod 命令用于修改权限。其语法如下:
u= 用户(所有者)g= 组o= 其他a= 所有
授予所有者执行权限:
$ chmod u+x script.sh要移除其他用户的写入权限:
$ chmod o-w sensitive-data.txt设置所有人的权限:
$ chmod a+r public-file.txt您可以合并更改:
$ chmod u=rwx,g=rx,o=r program.sh这将所有者设置为读/写/执行权限,组设置为读/执行权限,其他用户设置为只读权限。
执行权限
对于文件,执行权限允许将文件作为程序运行。对于目录,执行权限允许进入该目录。
下载脚本后,通常需要使其可执行:
$ chmod +x deploy.sh
$ ./deploy.sh./ 前缀会明确地在当前目录中运行脚本。
所有权变更
chown 命令用于更改文件所有权。这需要更高的权限:
$ sudo chown nginx:nginx /var/www/html/index.html这会将 nginx 和组都更改为 nginx 。语法为 user:group 。
根用户
root 用户是拥有所有权限的超级用户。以 root 用户身份运行命令功能强大,但也非常危险。
sudo 命令允许您以 root 用户身份执行单个命令:
$ sudo systemctl restart nginx系统会提示您输入密码。正确输入密码后,该命令将以 root 权限运行。
医疗保健背景:HIPAA 合规性
构建符合 HIPAA 标准的系统时,文件权限用于保护 PHI(受保护的健康信息)。数据库凭证、加密密钥和患者数据文件必须具有受限权限。
一个安全的配置文件可能包含:
$ chmod 600 /etc/myapp/database.conf这样可以确保只有所有者才能读取或写入文件。其他任何组成员或其他人都无法访问该文件。
您的 EC2 实例的 IAM 角色应遵循最小权限原则——仅授予所需的最低权限。同样,文件权限也应在保证功能的前提下尽可能严格。
程序和可执行文件
了解程序的执行方式有助于排查部署问题并编写更好的自动化脚本。
编译型程序与解释型程序
程序分为两种类型:
编译后的程序在执行前会被转换成机器代码。像 Go、Rust 和 C 这样的语言会生成二进制文件——包含处理器指令的可执行文件。这些文件可以直接在你的硬件上运行,无需额外的软件。
解释型程序需要解释器才能执行。Python 脚本需要 Python 解释器。Shell 脚本需要 shell(bash 或 zsh)。
当你运行已编译的程序时:
$ /usr/bin/nginx操作系统加载该二进制文件并执行它。
运行解释型程序时:
$ python3 app.pyPython 解释器读取 app.py ,解析它,并执行其中的指令。
谢邦斯
Shell 脚本和 Python 脚本通常以 shebang 开头——这是一个特殊的首行,用于指示要使用的解释器:
#!/bin/bash
echo "This is a bash script"或者对于 Python 来说:
#!/usr/bin/env python3
print("This is a Python script")shebang 行告诉操作系统要调用哪个解释器。有了正确的 shebang 行和执行权限,你就可以直接运行脚本:
$ chmod +x script.py
$ ./script.py如果没有 shebang,则需要显式指定解释器:
$ python3 script.py寻找项目
which 命令显示程序的所在位置:
$ which python3输出结果可能显示:
/usr/bin/python3这会告诉你 Python 解释器的安装位置。
AWS 上下文:Lambda 执行环境
AWS Lambda 函数运行在执行环境(本质上是小型 Linux 容器)中。将 Python 代码部署到 Lambda 时,AWS 会提供 Python 解释器。您的代码将作为解释型程序运行。
对于性能要求极高的工作负载,您可以将编译后的二进制文件部署为自定义 Lambda 运行时。例如,Go 二进制文件启动速度更快,内存占用也比解释型 Python 代码更低。
理解这种区别有助于你做出架构决策。需要微秒级的响应速度?使用编译型语言。需要快速开发?解释型语言效果很好。
环境变量和 PATH
环境变量用于配置程序,而无需将值硬编码到程序中。PATH 变量是您将要使用的最重要的 PATH 变量。
PATH 是什么?
PATH 是一个环境变量,其中包含一个以冒号分隔的目录列表。当你运行命令时,你的 shell 会在这些目录中搜索匹配的可执行文件。
检查您的路径:
$ echo $PATH你会看到类似这样的内容:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin这意味着 shell 会按顺序搜索:
/usr/local/bin/usr/bin/bin/usr/sbin/sbin
当你输入 python3 时,shell 会找到 /usr/bin/python3 并执行它。你不需要输入完整路径。
添加到 PATH
您安装的程序通常需要添加到 PATH 环境变量中。要为当前会话添加目录:
$ export PATH="$PATH:/home/achar/bin"这会将 /home/achar/bin 添加到您现有的 PATH 环境变量中。现在可以通过名称访问该目录中的程序。
要使此设置永久生效,请将 export 命令添加到 shell 配置文件中:
- bash:
~/.bashrc - zsh:
~/.zshrc
编辑文件:
$ nano ~/.zshrc在末尾添加:
export PATH="$PATH:/home/achar/bin"保存并退出。新的 shell 会话会将此目录添加到 PATH 环境变量中。
要将更改应用到当前会话:
$ source ~/.zshrc创建环境变量
使用 export 设置环境变量:
$ export DATABASE_URL="postgresql://localhost:5432/mydb"程序可以读取此变量。在 Python 中:
import os
db_url = os.getenv("DATABASE_URL")
print(f"Connecting to {db_url}")AWS 上下文:Lambda 环境变量
Lambda 函数大量使用环境变量。您可以在 AWS 控制台中设置环境变量,也可以通过基础设施即代码 (IaC) 设置:
# Lambda function code
import os
import boto3
bucket_name = os.getenv("S3_BUCKET_NAME")
s3 = boto3.client("s3")在您的 CloudFormation 或 Terraform 配置中:
resource "aws_lambda_function" "processor" {
function_name = "data-processor"
environment {
variables = {
S3_BUCKET_NAME = "patient-records-bucket"
LOG_LEVEL = "INFO"
}
}
}这种模式将配置与代码分离——对于多环境部署(开发、测试、生产)至关重要。
医疗保健背景:安全凭证
切勿将数据库密码或 API 密钥硬编码到代码中。请使用环境变量:
$ export DB_PASSWORD="$(aws secretsmanager get-secret-value --secret-id prod-db --query SecretString --output text)"此操作会从 AWS Secrets Manager 中检索密钥并将其存储在环境变量中。您的应用程序无需在源代码中暴露密码即可读取该环境变量。
为符合 HIPAA 法规,请审核所有环境变量的使用情况。确保敏感值来自安全来源(例如 Secrets Manager),而不是明文文件。
输入、输出和流
程序通过三个标准流进行通信:标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。
标准输出
当程序打印结果时,它会将输出写入 echo 输出(stdout)。echo 命令就演示了这一点:
$ echo "Hello"文本会出现在您的终端中,因为默认情况下标准输出会定向到那里。
重定向输出
您可以使用 > 将标准输出重定向到文件:
$ echo "Log entry" > application.log这将创建 application.log ,其内容为“日志条目”。如果该文件已存在, > 将覆盖它。
要追加而不是覆盖,请使用 >> :
$ echo "Another entry" >> application.log标准误差
程序会将错误信息写入标准错误流(stderr),这是一个与标准输出(stdout)不同的流。这种分离使得你可以区别于常规输出来处理错误信息。
大多数命令会将错误写入标准错误输出(stderr):
$ ls nonexistent-directory您会看到一条错误消息。要将 stderr 重定向到文件:
$ ls nonexistent-directory 2> errors.log2> 语法重定向 stderr(文件描述符 2)。要同时重定向 stdout 和 stderr:
$ command > output.log 2> errors.log或者将它们合并到一个文件中:
$ command > combined.log 2>&1标准输入
程序可以从标准输入读取数据。bash 中的 read 命令就演示了这一点:
#!/bin/bash
echo "What is your name?"
read name
echo "Hello, $name"运行此脚本时,它会等待您的输入。
管道
管道运算符( | )将一个程序的标准输出连接到另一个程序的标准输入:
$ cat application.log | grep "ERROR"这段代码读取 application.log ,然后筛选出包含“ERROR”的行。管道操作可以创建强大的命令链。
找出10个最常见的错误信息:
$ grep "ERROR" application.log | sort | uniq -c | sort -rn | head -10分析如下:
grep提取错误行sort按字母顺序排列它们uniq -c统计重复项sort -rn按数值反向排序head -10显示前 10 名
AWS 背景:CloudWatch 日志
当您的 Lambda 函数向标准输出 (stdout) 写入内容时,AWS 会将其捕获到 CloudWatch Logs 中。您的 Python 代码:
def lambda_handler(event, context):
print(f"Processing event: {event}")
return {"statusCode": 200}print 语句会将内容写入标准输出,该输出会显示在 CloudWatch 中:
$ aws logs tail /aws/lambda/my-function --follow了解 stdout/stderr 有助于设计有效的日志记录策略。错误信息应输出到 stderr,正常操作信息输出到 stout。
软件包管理器
软件包管理器可自动执行软件安装、依赖关系解析和更新。它们对于维护云基础设施至关重要。
Linux:apt
在基于 Ubuntu 和 Debian 的系统中,使用 apt :
$ sudo apt update这将刷新软件包索引(可用软件的数据库)。
安装软件包:
$ sudo apt install nginx这将安装 Nginx Web 服务器及其所有依赖项。软件包管理器:
- 下载 Nginx 及其依赖项
- 所有部件均安装在正确位置
- 配置系统路径
- 设置 systemd 服务(如果适用)
要移除包裹:
$ sudo apt remove nginxmacOS:Homebrew
在 macOS 系统中,Homebrew 是事实上的软件包管理器:
$ brew install python3这将安装 Python 3 并将其自动添加到您的 PATH 环境变量中。
更新所有已安装的软件包:
$ brew upgradePython:pip
Python 有自己的包管理器:
$ pip install boto3这将安装适用于 Python 的 AWS 开发工具包。请使用 requirements.txt 管理项目依赖项:
boto3==1.26.137
requests==2.28.2
psycopg2-binary==2.9.5安装文件中的所有内容:
$ pip install -r requirements.txtAWS 背景:EC2 用户数据
启动 EC2 实例时,您可以通过用户数据运行初始化脚本。这通常涉及包管理器:
#!/bin/bash
apt-get update
apt-get install -y nginx python3-pip
pip3 install boto3
# Configure application
systemctl enable nginx
systemctl start nginx该脚本在实例首次启动时运行,安装依赖项并启动服务。
医疗保健背景:可审计的部署
为了符合 HIPAA 标准,您需要可审计的部署流程。软件包管理器可以通过以下方式提供帮助:
- 显式地对依赖项进行版本控制
- 创建可复现的环境
- 跟踪每台服务器上安装的内容
您的 requirements.txt 将成为您的合规性文档的一部分,准确证明哪些软件版本可以处理 PHI。
故障排除框架
当东西坏了的时候——而它肯定会坏——请遵循以下系统方法。
第一步:识别症状
究竟是什么环节出了问题?请具体说明:
- 应用程序返回 502 错误
- “数据库连接超时”
- Lambda 函数超出内存限制
像“它不起作用”这样模糊的问题会浪费时间。
步骤二:检查日志
日志包含了大部分答案。对于 Web 服务器而言:
$ tail -100 /var/log/nginx/error.log应用程序日志:
$ journalctl -u myapp.service -n 100对于 AWS 服务,请查看 CloudWatch Logs:
$ aws logs tail /aws/lambda/my-function --since 10m步骤三:验证权限
权限问题会导致很多故障。请检查文件权限:
$ ls -l /var/www/html/config.php所有者的说法正确吗?权限是否过于限制?
检查您的用户权限:
$ groups你是否加入了正确的群组?
第四步:测试连接性
网络问题很常见。请测试连接:
$ curl https://api.example.com/health对于数据库:
$ telnet database.example.com 5432如果连接败,请检查安全组、网络访问控制列表和防火墙规则。
步骤五:验证环境变量
许多问题源于环境变量缺失或错误:
$ echo $DATABASE_URL步骤 6:本地复现
尝试在开发机器上重现该问题。如果本地无法重现,则问题出在环境因素上——很可能是服务器的配置或权限问题。
实际案例:部署 Python Web 应用程序
让我逐步演示如何在 EC2 实例上完整部署这些概念。
配置实例
启动一个 Ubuntu 22.04 EC2 实例。通过 SSH 连接:
$ ssh -i keypair.pem ubuntu@ec2-xx-xx-xx-xx.compute-1.amazonaws.com安装依赖项
更新软件包索引:
$ sudo apt update安装 Python 和 pip:
$ sudo apt install -y python3-pip python3-venv nginx创建应用程序结构
创建目录:
$ mkdir -p /home/ubuntu/myapp
$ cd /home/ubuntu/myapp创建虚拟环境:
$ python3 -m venv venv
$ source venv/bin/activate安装应用程序依赖项
创建 requirements.txt :
flask==2.3.0
gunicorn==20.1.0
boto3==1.26.137
psycopg2-binary==2.9.5安装:
$ pip install -r requirements.txt配置环境变量
创建 .env 文件:
export DATABASE_URL="postgresql://user:password@db.example.com:5432/mydb"
export S3_BUCKET="patient-records-bucket"
export AWS_REGION="us-east-1"加载它:
$ source .env创建应用程序
写入 app.py :
from flask import Flask, jsonify
import boto3
import os
app = Flask(__name__)
s3 = boto3.client("s3", region_name=os.getenv("AWS_REGION"))
bucket = os.getenv("S3_BUCKET")
@app.route("/health")
def health():
return jsonify({"status": "healthy"})
@app.route("/files")
def list_files():
response = s3.list_objects_v2(Bucket=bucket, MaxKeys=10)
files = [obj["Key"] for obj in response.get("Contents", [])]
return jsonify({"files": files})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)本地测试:
$ python app.py打开另一个终端进行测试:
$ curl http://localhost:5000/health配置 systemd 服务文件
创建 systemd 服务文件:
$ sudo nano /etc/systemd/system/myapp.service添加:
[Unit]
Description=My Flask Application
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
Environment="PATH=/home/ubuntu/myapp/venv/bin"
EnvironmentFile=/home/ubuntu/myapp/.env
ExecStart=/home/ubuntu/myapp/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:5000 app:app
[Install]
WantedBy=multi-user.target启用并启动:
$ sudo systemctl enable myapp
$ sudo systemctl start myapp
$ sudo systemctl status myapp配置 Nginx
创建 Nginx 配置:
$ sudo nano /etc/nginx/sites-available/myapp添加:
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}启用该网站:
$ sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl reload nginx验证部署
在本地计算机上进行测试:
$ curl http://ec2-xx-xx-xx-xx.compute-1.amazonaws.com/health你应该看看:
{"status": "healthy"}故障排除
如果不起作用,请检查日志:
$ sudo journalctl -u myapp -n 50
$ sudo tail -50 /var/log/nginx/error.log常见问题:
- 权限被拒绝 :请使用
ls -l检查文件权限 - 连接被拒绝 :请使用
systemctl status myapp验证 Gunicorn 是否正在运行 - 502 Bad Gateway :Nginx 无法连接到 Gunicorn——请检查代理配置
该工作流程演示了终端、shell、文件导航、权限、环境变量、软件包管理和故障排除——所有这些都在一个真实的部署场景中。