Linux 常用命令
1 日常使用
ctrl-x ctrl-e
调用编辑器来编辑长命令ctrl-r
回溯历史命令- 暴露服务器当前目录的文件:
- Python 2:
python -m SimpleHTTPServer 7777
- Python 3:
python -m http.server 7777
- Python 2:
1.1 帮助文档
# 查看 topic 的相关文档 man topic # 搜索 keyword 的 topic man -k keyword
2 用户管理
2.1 查看用户信息
# 显示当前用户名 whoami # 显示已经登录的用户,三种命令显示风格不同 who w users # 查看用户指纹,用户 id,名字,登录状态 finger user # 查看用户的各种 id,uid,gid id user # 打印 uid id -u user # 打印 gid id -g user # 查看最近登录用户日志 last # 查看 user 的最近登录日志 last user # 查看最近登录失败的日志 lastb
2.2 修改用户信息
# 添加用户 useradd user useradd -m user # 创建用户,同时创建家目录;但不设置用户密码 # 删除用户 -r 选项删除用户并移除家目录和邮箱 userdel user userdel -r user # 添加用户,1. 调用 useradd 新建用户; 2. 创建用户的家目录; 3. 为用户设置密码 adduser user # 删除用户,2. 动员 userdel 删除用户;2. 删除用户的家目录 deluser user # 修改密码, 重置密码 passwd sudo passwd user
2.3 修改用户组
# 新建一个组 groupadd group # 将 user 添加到 group 中 usermod -aG group user # 将当前用户添加到 group 中 usermod -aG group $USER # 修改用户的登录 shell usermod -s /bin/zsh user
3 文件系统
3.1 目录操作
3.1.1 查看目录信息
# 列出当前目录的内容 ls # 只显示文件名 ls -1 # 显示隐藏文件 ls -a # 按招时间由新到旧排序 ls -t
3.1.2 修改目录
# 进入 dir 目录 cd dir # 打印当前目录 pwd # 返回到家目录 cd # 返回之前的目录 cd - # 返回之前第 N 个目录, cd -2 返回倒数第二个目录 cd -N # 返回到 git 根目录 cd $(git rev-parse --show-toplevel) # 新建目录 mkdir dir # 递归新建多级目录 mkdir -p dir1/dir2/dir3 # 目录栈的入栈和出栈 pushd dir popd # 列出当前目录栈 dirs -v
3.2 文件操作
3.2.1 查看文件信息
# 打印文件内容 cat file # 查看文件行数 wc -l file # 打印文件头部行数 head file head -n 3 file # 打印文件尾部行数 tail file tail -n 3 file # 文件的名字(不包含路径) basename file # 文件的路径(不包含名字) dirname file # 检测文件类型和编码 file file # 文件的详细信息 stat file # 分页查看, less is more, less 可以往回翻页, more 不行 less file more file # less 查看文件,直接跳到 120 行 less -n+120 /pass/to/file less +120 /pass/to/file
3.2.2 文件复制、移动和删除
# 复制文件 cp src dest # 递归复制文件 cp -rf src dest # 更新模式复制文件,即 src 比 dest 新则复制 cp -u src dest # 移动文件,重命名文件 mv src dest # 删除文件 rm file # 递归删除,非常小心地用这个命令 rm -rf dir # 创建软连接, dest 是所指向的文件,link 是软连接 # 例如: ln -s /tmp ~/Public/tmp 相当于在 ~/Public 中建了一个 tmp 软连接,指向 /tmp ln -s dest link
3.2.3 大文件分割和合并
# 按行数分割 split -l 300 largefile.txt new_file_prefix. # 按字节大小分割 split -b 10m largefile.zip new_file_prefix. # 合并文件 cat new_file_prefix.* > largefile.zip
3.2.4 更新文件信息
# 更新一下文件 touch file # 更新文件权限为 644,-R 可以递归修改 chmod 644 file # 更新文件的组/用户,-R 可以递归修改 chgrp group file chown user file # 同时更改文件的组合用户,-R 可以递归修改 chown user:group file
3.2.5 重定向
# 将 cmd 的 stdout 重定向到 file 中 cmd > file # 将 cmd 的 stderr 重定向到 file 中 cmd 2> file # 将 cmd 的 stdout 和 stderr 重定向到 file 中, 2>&1 的必须放在 > file 后面 cmd > file 2>&1 # 将 cmd 的 stdout 和 stderr 重定向到 /dev/null 中,并挂载成后台任务 cmd >/dev/null 2>&1 &
4 进程管理
4.1 查看进程
# 以不同模式查看进程 ps ps -ef ps aux # 查看用户名 user 的进程 ps -u user # 指定格式查看进程 ps -eo pid,user,command # 查看父进程 ppid 为 1 的子进程 ps -eo ppid,pid,user,command | awk '$1 ~ /^1$/'
4.2 监控进程
# 进程监视器 top # 进程监视器, 仅仅监控 user 的进程 top -u user top -u $USER # htop 和 top 类似,但是比 top 要好看一点,需要安装 htop # 内存监视器 vmstat # 每 3 秒打印一行内存和 CPU 使用情况 vmstat 3 # 查看内存和 swap 的使用情况 free # 每 3 秒刷新显示 while sleep 3; do clear && free; done
4.3 后台进程
# & 符号表示将进程挂在后台运行 cmd & # 查看所有后台进程 jobs # 查看后台进程,并切换过去 bg # 切换后台进程到前台 fg # 切换指定的 job 到前台 fg jid # 长期运行后台进程,退出 shell 后任然保持运行 nohup cmd # 在后台长期运行程序 nohup cmd & # 将指定 pid 或者 jid 从后台任务列表移除 disown pid|jid # 等待所以后台进程任务结束 wait
5 远程交换
5.1 ssh
# 远程登录 ssh user@host # 指定 ssh 端口为 2222 登录到远程机器上 ssh -p 2222 user@host # 生成 ssh 公钥和私钥 ssh-keygen -t rsa -b 4096 -C "hujinghui@buaa.edu.cn" # 复制 ssh 公钥到远程机器上 ssh-copy-id user@host ssh-copy-id -i ~/.ssh/id_rsa.pub user@host # ssh 到远程机器上,并执行 cmd 命令 ssh user@host cmd
5.2 scp 和 rsync
# 本地到远程复制文件, -r 选项表示递归复制 scp file user@host:path scp user@host:path file scp -r file user@host:path # 增量同步文件 rsync -av dir user@host:path # 增量同步文件,显示同步的进度 rsync -av --progress dir user@host:path # 增量同步文件,忽略 *.log 文件 rsync -av --exclude='*.log' dir user@host:path # 增量同步文件,删除远程中多余的文件 rsync -av --delete dir user@host:path # 增量同步文件,删除远程中多余的文件, *.log 文件会被忽略,不会被删除 rsync -av --exclude='*.log' --delete dir user@host:path
6 软件包管理器
6.1 rpm & yum
# 直接安装 rpm -ivh package-name.bla.rpm # 忽略报错,强制安装 rpmrpm --force -ivh your-package.rpm # 查询 rpm rpm -ql tree # 卸载 rpm 软件包 rpm -e tree # 返回软件包的全名 rpm -qf `which git` # 返回软件包的有关信息 rpm -qif `which git` # 返回软件包的文件列表 rpm -qlf `which git`
# 安装指定的安装包 package yum install package # 全部更新 yum update # 删除程序包 package yum remove package # 下载包缓存信息 yum makecache
6.2 dpkg & apt-get
# 安装软件包 dpkg -i package.bal.deb # 从软件包里面读取软件的信息 pkg -A package.bla.deb # 安装一个目录下面所有的软件包 dpkg -R /path/to/folder # 删除软件包(保留其配置信息) dpkg -r avg71flm
简单来说就是 apt = apt-get、apt-cache 和 apt-config 中最常用命令选项的集合
# 刷新存储库索引 apt update apt-get update # 升级所有可升级的软件包 apt upgrade apt-get upgrade # 安装软件包 apt install package apt-get install package # 移除软件包 apt remove package apt-get remove package # 移除软件包及配置文件 apt purge package apt-get purge package # 自动删除不需要的包 apt autoremove apt-get autoremove # 搜索应用程序 apt search text apt-cache search text # 显示装细节 apt show package apt-cache show package
7 网络管理
7.1 route
# 打印路由表 route -n # 添加默认网关为 192.168.1.1, 即默认路由 route add default gw 192.168.1.1 # 添加一条普通路由项 route add 192.168.1.0/32 gw 192.168.1.1 # 删除默认路由 route del default gw 192.168.1.1
7.2 ifconfig
# 显示所有网卡和接口信息 ifconfig # 显示所有网卡(包括开机没启动的)信息 ifconfig -a # 指定设备显示信息 ifconfig eth0 # 激活网卡 ifconfig eth0 up # 关闭网卡 ifconfig eth0 down # 给网卡配置 IP 地址 ifconfig eth0 192.168.120.56 # 配置 IP 并启动 ifconfig eth0 192.168.120.56 netmask 255.255.255.0 up # 修改 MAC 地址 ifconfig eth0 hw ether 00:aa:bb:cc:dd:ee
7.3 netstat
# 列出所有端口 netstat -a # 查看所有连接信息,不解析域名 netstat -an # 查看所有连接信息,包含进程信息(需要 sudo) netstat -anp # 查看所有监听的端口 netstat -l # 查看所有 TCP 链接 netstat -t # 显示所有正在监听的 TCP 和 UDP 信息 netstat -lntu # 显示所有正在监听的 socket 及进程信息 netstat -lntup # 显示网卡信息 netstat -i # 显示当前系统路由表,同 route -n netstat -rn
7.4 ping/traceroute/whois 网络连通性和 DNS
# 连通性 ping host/ip ping -c 3 host/ip # 路由跳转追踪 traceroute host # 查看暴露的外网 ip curl http://httpbin.org/ip # DNS 查询 host domain whois domain dig domain
7.5 nmap 网络和端口扫描
# 扫描一个主机的所有信息 nmap 192.168.0.110 # 扫描主机是否开机 nmap -sn 192.168.0.0/24 # 扫描特定范围的 IP nmap -F 192.168.0.0/24 nmap -F 192.168.0.* nmap -F 192.168.0.110,111,112 nmap 192.168.0.100-199 # 扫描特定的端口号 nmap -p 80 192.168.0.* nmap -p 9000-9999 192.168.0.110
7.6 ssh 代理
# 在本地 9595 端口开启一个 socks5 的代理服务 ssh -N -D 9595 user@proxyer # 测试连通性: --socks5-hostname 表示使用代理机的 DNS 来解析域名 curl --socks5-hostname 127.0.0.1:9595 http://httpbin.org/ip # 优雅地启动 socks5 代理 # -f 挂后台, -q 静默, -n 屏蔽 stdin, -T 阻止分配 tty, -C 压缩 # -N 不执行 ssh 命令,只作端口转发, -D 指定本地监听端口号 ssh -fqnCTN -D 9595 user@proxyer # 反向代理:将外网主机(202.115.8.1)端口(8443)转发到内网主机 192.168.1.2:443 ssh -qnCTN -R 0.0.0.0:8443:192.168.1.2:443 user@202.115.8.1 # 正向代理:将本地主机的 8443 端口,通过 192.168.1.3 转发到 192.168.1.2:443 ssh -qnCTN -L 0.0.0.0:8443:192.168.1.2:443 user@192.168.1.3
8 文本处理
8.1 普通处理
简单的文本处理使用 tr/cut/paste 等,复杂的文本处理使用 sed/awk
# 截取每行头 16 个字符 cut -c 1-16 # 截取指定文件中每行头 16 个字符 cut -c 1-16 file # 截取每行从第三个字符开始到行末的内容 cut -c3- # 截取用冒号分隔的第五列内容 cut -d':' -f5 # 截取用分号分隔的第二和第十列内容 cut -d';' -f2,10 # 截取空格分隔的三到七列 cut -d' ' -f3-7 # 显示 hel echo "hello" | cut -c1-3 # 显示 sir echo "hello sir" | cut -d' ' -f2 # cut 搭配 tr 压缩字符 ps | tr -s " " | cut -d " " -f 2,3,4 # 打印 PATH 变量 echo $PATH | tr : '\n'
8.2 sed
sed 是 Linux 下著名的行编辑器
# 替换文件中首次出现的字符串并输出结果 sed 's/find/replace/' file # 替换文件第 10 行内容 sed '10s/find/replace/' file # 替换文件中 10-20 行内容 sed '10,20s/find/replace/' file # 替换文件中所有出现的字符串 sed -r 's/regex/replace/g' file # 替换文件中所有出现的字符并且覆盖文件 sed -i 's/find/replace/g' file # 在文件的匹配文本前插入行 sed -i '/find/i\newline' file # 在文件的匹配文本后插入行 sed -i '/find/a\newline' file # 先搜索行特征再执行替换 sed '/line/s/find/replace/' file # 执行多次替换 sed -e 's/f/r/' -e 's/f/r' file # 使用 # 替换 / 来避免 pattern 中有斜杆 sed 's#find#replace#' file # 删除第 1 行内容 sed -i '1d' file # 删除文件每行头部空格 sed -i -r 's/^\s+//g' file # 删除文件空行并打印 sed '/^$/d' file # 删除文件每行末尾多余空格 sed -i 's/\s\+$//' file # 打印文件第二行 sed -n '2p' file # 打印文件第二到第五行 sed -n '2,5p' file # 使用词界 (word boundary), 这里 \b 是词界的锚点符号 sed 's/\bfoo\b/bar/g' file
8.3 awk
awk 一般用于文本预处理,并且支持编程
# -F 选项指定分隔符, 默认以空格分隔 awk -F ':' '{print $1}' file # 使用正则表达式匹配过滤结果 awk '/reg/ {print $5}' file awk '$1 ~ /reg/ {print $5}' file # 打印用户名以 b 开头的用户名 awk -F ':' ' $1 ~ /^b/ {print $1}' /etc/passwd # 打印文件中以空格分隔的第五列 awk '{print $5}' file # 打印文件中以逗号分隔的第五列 awk -F ',' '{print $5}' file # 打印文件中包含 str 的所有行的第二列 awk '/str/ {print $2}' file # 打印逗号分隔的文件中的每行最后一列 awk -F ',' '{print $NF}' file # 打印文件中的每行倒数第三列 awk '{print $(NF-2)}' # 计算所有第一列的和 awk '{s+=$1} END {print s}' file # 从第一行开始,每隔三行打印一行 awk 'NR%3==1' file # 跳过第一行 awk 'NR>1 {print $0}' file
8.4 jq
jq 可以处理 JSON 文本
# Identity: . echo '{"a":1, "b": "bla"}' | jq '.' # Object Identifier-Index: .foo, .foo.bar, echo '{"a":1, "b": "bla"}' | jq '.b' # Generic Object Index: .["foo.bar"] echo '{"a":1, "b": "bla", "c": { "k": "kill"}}' | jq '.["b"]' # Optional Object Identifier-Index: .foo? echo '{"a":1, "b": "bla"}' | jq '.b?' # Array Index: .[2] echo '[1, 2, 3]' | jq '.[1]' # Array Slice: .[0:1] echo '[1, 2, 3]' | jq '.[0:2]' # Array/Object Value Iterator: .[] echo '[1, 2, 3]' | jq '.[]' echo '{"a":1, "b": "bla"}' | jq '.[]' # Comma: , echo '{"a":1, "b": "bla", "c": 3}' | jq '.a,.b' # Pipe: | echo '{"a":1, "b": "bla", "c": [1, 2, 3]}' | jq '.c|.[]' # Array construction: [] # Object Construction: {}
去除字符串的双引号,jq 在输出 json 时遇到字符串会添加上双引号,可以使用 -r
选
项来去除双引号
~ $ echo '["a", "b", "c"]' | jq '.[]' "a" "b" "c" ~ $ echo '["a", "b", "c"]' | jq -r '.[]' a b c
8.5 文本排序
# 排序文件 sort file # 反向排序(降序) sort -r file # 使用数字而不是字符串进行比较 sort -n file # 按 passwd 文件的第三列进行排序, -t 表示分隔符 sort -t: -k 3n /etc/passwd # 去重排序 sort -u file
9 杂项
# 查看文件系统的结构和定义 man hier # 查看 ASCII 表 man ascii # 在线查看速查表 curl -L cheat.sh curl -L cheat.sh/find # 查看系统是 32 位还是 64 位 getconf LONG_BIT # 快速备份文件 cp file.txt{,.bak} # 从网络上的压缩文件中解出一个文件来,并避免保存中间文件 wget -qO - "http://www.tarball.com/tarball.tar.gz" | tar zxvf - # 下载 zip 文件并解压,注意: unzip 6.00 后不能从 stdin 中读取,需要存成本地文件 curl -sL -o a.zip "http://localhost/a.zip" && unzip a.zip && rm -f a.zip # 使用光盘制作 iso 文件 cp /dev/cdrom /path/to/file.iso dd if=/dev/cdrom of=/path/to/file.iso # 使用目录制作 iso 文件 mkisofs -r -o /path/to/file.iso /home/Public # Linux 下挂载一个 iso 文件 mount -o loop /path/to/file.iso /mnt/cdrom # 按日期范围查找文件 find . -type f -newermt "2010-01-01" ! -newermt "2010-06-01" # Vim 中保存一个没有权限的文件 :w !sudo tee > /dev/null % # 获取终端的一些基本信息:宽度,长度等 stty -a # 将 list 的输出转化成二维矩阵显示方式 ls | column # 时间戳 -> 字符串, 1564848000 date -d '2019-08-04 00:00:00' +%s # 字符串 -> 时间戳, 2019-08-04 00:00:20 date -d @1564848200 +'%Y-%m-%d %H:%H:%S' # 设置命令超时,超时的时长为 10 秒,如果发送命令后 5 秒任然运行则直接 kill timeout -s INT -k 5 10 sh -c "sleep 8 && echo hello"