本博文旨在记录Linux使用过程中常遇到的一些问题和解决方案。 --- 笔者
1. 查看端口占用
当你需要使用某一端口时发现程序因为端口被占用而无法正常运行,你需要知道端口被什么程序占用,运行查看:
netstat -anpe | grep 端口
2. 查看命令行的运行参数
平时实验需要运行很多脚本程序,而且不同的脚本程序使用的脚本参数也不一样,有的很长有的很短,如果脚本有很多输出的话,脚本程序的设置很快就会被挤出程序以外,这时候你如果忘了正在运行的脚本使用的是什么设置怎么办?下面就教大家查看运行的程序及其参量:
- 使用top指令
top -u<username> -c
默认情况下top
指令只显示程序名称(不包括参数),添加-c
参数可以输出查看程序的参数。参数-u<username>
仅用于基于用户名过滤输出列表,这样我们就可以在有限的屏幕空间上查看指定用户启动的程序。
- 使用 ps指令
ps -f -u<username> | grep <program>
指令ps
用于查看当前运行的进程,默认情况下以简易模式输出当前机器上所有运行中的程序,一般而言运行的程序(包括系统程序和各用户运行的程序)数量比较大,不利于快速查看,我们可以通过设置-u
参数来根据用户过滤出指定用户启动的活动程序,还能通过grep
指令进一步实现按关键字过滤。参数-f
可强制ps
指令打印出程序参数。
- 查看/proc/<pid>/cmdline 信息
cat /proc/<pid>/cmdline
Linux系统中/proc
目录是一个很特殊的目录,它保存着系统运行时信息。
/proc is very special in that it is also a virtual filesystem. It's sometimes referred to as a process information pseudo-file system. It doesn't contain 'real' files but runtime system information (e.g. system memory, devices mounted, hardware configuration, etc). For this reason it can be regarded as a control and information centre for the kernel. In fact, quite a lot of system utilities are simply calls to files in this directory. For example, 'lsmod' is the same as 'cat /proc/modules' while 'lspci' is a synonym for 'cat /proc/pci'. By altering files located in this directory you can even read/change kernel parameters (sysctl) while the system is running. Each of the numbered directories corresponds to an actual process ID.
3. 查看CPU占用前10的进程
使用top
指令查看系统运行进程的时候,默认打印所有用户的活动进程,如果指定用户或组别,那么也只能显示指定用户和组别的活动进程,使用top
指令难以实现本节所要实现的目的。下面我们一步步介绍怎么才能实现查看CPU占用前10的进程:
- 首先获取活动进程信息
## 通过`ps`指令活动活动进程信息
ps -aux
- 获取指定信息
上一步中指令会打印所有用户的活动进程信息,包含内容很丰富,实际上我们查看前10进程的时候并不需要那么多详细的信息,而且信息太详细显示起来也比较麻烦,所以我们要有选择地显示感兴趣的信息:
## 仅显示nice值,用户,进程id,cpu用量,内存用量,cpu时间,进程启动至今总时长 和 进程名称
ps -au -o ni,user,pid,pcpu,pmem,cputime,etime,comm
- 获取指定用户的进程信息
步骤2中的方法获得的信息虽然少了许多,但打印的进程单还是很长,其中有许多是root运行的系统启动的进程。我们在查看进程的时候更多的是关心用户启动的进程,这时候就要对进程按用户进行过滤:
- 按用户过滤
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm
- 进程按照CPU用量排序并取前十
这里还有些额外的处理,首先步骤3输出中包含标题,需要去除标题信息:
- 去除标题,得到实际统计数据
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm | grep -v PID
- 按CPU用量逆向排序
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm | grep -v PID | sort -rn -k +4
- 用HEAD指令取前十
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm | grep -v PID | sort -rn -k +4 | head -10
head
指令默认返回前十行数据,可通过设置要返回的行数返回指定行的数据,如:返回前20行 head -20
最终指令如是:
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm | grep -v PID | sort -rn -k +4 | head -10
4. 查看内存用量前10的进程
方法与“查看CPU占用前10的进程”类似,如下:
ps -U user1,user2 -u user1,user2 -o ni,user,pid,pcpu,pmem,cputime,etime,comm | grep -v PID | sort -rn -k +5 | head -10
5. Linuxbrew使用brew安装的curl
Linuxbrew使用brew命令从网络获取信息时,默认使用/usr/bin/curl
,而不管你是不是从brew安装了curl或者手动安装了curl,即便他们在PATH中的位置在系统默认curl前。这是因为brew代码中设置了PATH过滤:
# test-bot does environment filtering itself
if [[ -z "$HOMEBREW_NO_ENV_FILTERING" && "$1" != "test-bot" ]]
then
PATH="/usr/bin:/bin:/usr/sbin:/sbin"
FILTERED_ENV=()
所以我们在使用brew前设置HOMEBREW_NO_ENV_FILTERING
环境变量即可。例如:
HOMEBREW_FORCE_BREWED_CURL=1 HOMEBREW_NO_ENV_FILTERING=1 brew install curl
HOMEBREW_FORCE_BREWED_CURL=1 brew install hello
6. dpkg 批量删除
dpkg -l | grep libreoffice | awk '{print $2}' | xargs sudo dpkg -P
7. 查看拥有sudo权限的用户
默认情况下系统的sudo相关设置在,/etc/sudoers
文件中定义,我们习惯性以为看sudo用户组的成员就能知道谁有高级权限时片面的理解,具体哪些用户或组有高级权限要看sudoer文件的配置
8. 查看显卡信息
## 查看显卡安装情况
## 列举已安装显卡
lspci | grep -i vga
## 查看显卡详情
## 02:00.0 VGA compatible controller: nVidia Corporation GT215 [GeForce GT 240] (rev a2)
lspci -v -s 02:00.0
## NVIDIA 显卡可使用nvidia-smi查看
nvidia-smi
我们还可以用lshw
指令来查看显示硬件信息,命令使用方法如下:
lshw参数:
-help 查看帮助
-version 打印版本
-X GUI显示,要装lshw-gtk 或者lshw-gui
输出的格式
-html 以HTML格式输出
-xml 以XML 格式输出
-short 显示设备列表,输出包括设备路径(path)、类别(class)以及简单描述
-businfo 输出包括总线信息、SCSI、USB、IDE、PCI地址等信息
选项:
-class CLASS 显示指定类别的设备
-C CLASS 同上
-c CLASS 同上
-disable TEST 不检测信息 像 pci 、isapnp、 cpuid等等
-enable TEST 与上面相反,启用检测
-quiet 直接输出结果,不显示检测过程
-sanitize 无害输出 (会移除像硬件序列号等一些敏感信息)
-numeric 显示硬件id (PCI、USB等)
查看显示设备信息可使用 lshw -numeric -c video
或者 lshw -numeric -c display
,下面是一个输出信息示例
WARNING: you should run this program as super-user.
*-display
description: VGA compatible controller
product: GM200 [GeForce GTX TITAN X] [10DE:17C2]
vendor: NVIDIA Corporation [10DE]
physical id: 0
bus info: pci@0000:03:00.0
version: a1
width: 64 bits
clock: 33MHz
capabilities: vga_controller bus_master cap_list rom
configuration: driver=nvidia latency=0
resources: irq:73 memory:fa000000-faffffff memory:e0000000-efffffff memory:f0000000-f1ffffff ioport:e000(size=128) memory:fb000000-fb07ffff
WARNING: output may be incomplete or inaccurate, you should run this program as super-user.
其中configuration
参数部分表明当前设备使用的驱动类型(示例设备使用Nvidia驱动),可以使用lshw -c video | grep configuration
直接获取。
modinfo nvidia
查看驱动的详细信息,如下:
filename: /lib/modules/4.4.0-137-generic/updates/dkms/nvidia.ko
alias: char-major-195-*
version: 390.87
supported: external
license: NVIDIA
srcversion: 9680830EEE0BAB392576E99
alias: pci:v000010DEd00000E00sv*sd*bc04sc80i00*
alias: pci:v000010DEd*sv*sd*bc03sc02i00*
alias: pci:v000010DEd*sv*sd*bc03sc00i00*
depends: ipmi_msghandler
retpoline: Y
vermagic: 4.4.0-137-generic SMP mod_unload modversions retpoline
parm: NVreg_Mobile:int
parm: NVreg_ResmanDebugLevel:int
parm: NVreg_RmLogonRC:int
parm: NVreg_ModifyDeviceFiles:int
parm: NVreg_DeviceFileUID:int
parm: NVreg_DeviceFileGID:int
parm: NVreg_DeviceFileMode:int
parm: NVreg_UpdateMemoryTypes:int
parm: NVreg_InitializeSystemMemoryAllocations:int
parm: NVreg_UsePageAttributeTable:int
parm: NVreg_MapRegistersEarly:int
parm: NVreg_RegisterForACPIEvents:int
parm: NVreg_CheckPCIConfigSpace:int
parm: NVreg_EnablePCIeGen3:int
parm: NVreg_EnableMSI:int
parm: NVreg_TCEBypassMode:int
parm: NVreg_UseThreadedInterrupts:int
parm: NVreg_EnableStreamMemOPs:int
parm: NVreg_EnableBacklightHandler:int
parm: NVreg_EnableUserNUMAManagement:int
parm: NVreg_EnableIBMNPURelaxedOrderingMode:int
parm: NVreg_MemoryPoolSize:int
parm: NVreg_IgnoreMMIOCheck:int
parm: NVreg_RegistryDwords:charp
parm: NVreg_RegistryDwordsPerDevice:charp
parm: NVreg_RmMsg:charp
parm: NVreg_AssignGpus:charp
Ref:
9. 删除添加的PPA源
## e.g. remove added graphics-drivers/ppa source
add-apt-repository ppa:graphics-drivers/ppa
10. 修改用户UID和GID
# change user foo to new uid=1066
usermod -u 1066 foo
# change group foo to new gid=2066
groupmod -g 2066 foo
11. 强制开机启动RPC bind服务
systemctl add-wants multi-user rpcbind.service
12. 使用中文man帮助
如果感觉看英文帮助比较吃力,改用中文帮助就可以了,中文man资料库在非中文系统上默认是不全的,需要先安装完全中文资料库
apt install manpages-zh
如果你希望系统是英文的,只有man是中文的,可以在调用man的时候指定 -M 设置man查找帮助的位置,系统man资料库安装在 /usr/share/man/LANGUAGE
下,将LANGUAGE换成 zh_CN
即可。
详情还可以参考:/etc/manpath.config
13. 删除ssh冲突密钥
ssh-keygen -R ip or hostname
如果使用的是非默认端口可使用
ssh-keygen -R [ip or hostname]:port
14. 记录用户命令执行轨迹
使用如下代码,通过 PROMPT_COMMAND
行为结合日志功能实现用户命令执行纪律跟踪。变量 PROMPT_COMMAND
指定的行为会在首次打开终端和每次执行命令后执行。
usrlogd() {
# get runtime directory
if [ -z "$__BASH_CMD_CONTEXT" ]; then
__BASH_CMD_CONTEXT="$PWD"
fi
__BASH_CMD_HISNO="$( history 1 | { read __BASH_CMD_HISNO __BASH_CMD_HISCMD; echo $__BASH_CMD_HISNO; } )"
__BASH_CMD_HISCMD="$( history 1 | { read __BASH_CMD_HISNO __BASH_CMD_HISCMD; echo $__BASH_CMD_HISCMD; } )"
# filter out ENTER and only log valuable user command
# fix bug: "history -c" will clear all histories and __BASH_CMD_HISNO,__BASH_CMD_HISCMD will be empty
# fix bug: ENTER in terminal will result __BASH_CMD_HISNO=__BASH_CMD_HISPRENO
# fix bug: the latest command will be logged everytime when you launch a new terminal
# For now the terminal exit command will not be recorded
if [ ! -z "$__BASH_CMD_HISPRENO" ] && [ ! -z "$__BASH_CMD_HISNO" ] && [ "$__BASH_CMD_HISNO" != "$__BASH_CMD_HISPRENO" ]; then
CMD_XXX="$( echo $__BASH_CMD_HISCMD | { read CMD_XXX CMD_IGNORE; echo $CMD_XXX; } )"
CMD_XXY="$( which $CMD_XXX 2>/dev/null )"
if [ ! -z "$CMD_XXY" ]; then CMD_XXX=$CMD_XXY; fi
CMD_YYY="$(echo $__BASH_CMD_HISCMD | { read CMD_IGNORE CMD_YYY; echo $CMD_YYY; } )"
MSG="$(who -m | { read x y z; echo "$x : TTY=$y ; PWD=$__BASH_CMD_CONTEXT ; USER=$x ; COMMAND=$CMD_XXX $CMD_YYY"; })"
logger -i -t usrlogd -p user.info "$MSG"
fi
# record command history ID
__BASH_CMD_HISPRENO="$__BASH_CMD_HISNO"
# update runtime directory
__BASH_CMD_CONTEXT="$PWD"
}
# export usrlogd
PROMPT_COMMAND=usrlogd
将上述代码放入 /etc/profile.d/usrlogd.sh
中,用户每键入一个新的命令,该命令就会被写进日志。
15. 读写IO测试
# 写1MB文件
time dd if=/dev/zero of=temp.dat bs=1024 count=1000
#读1MB文件
time dd if=temp.dat of=/dev/null bs=1024
16. 获取本机指纹
机器指纹可视为机器的身份认证,用户在ssh连接机器的时候往往被要求检查目标机器是不是期望的机器,这一步骤是通过对比指纹来实现的。作为管理员,我们应公布自己机器的指纹信息以便用户核实,避免中间人攻击。
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
17. 不添加PPA安装额外包
一般安装额外包的时候,教程会说将PPA的源地址添加到apt的源列表中,然后 update 更新包信息,再利用包管理工具安装。
实际上用不着这么麻烦,对于那些我们不想经常更新的包或者软件,我们直接下载 deb 文件就能安装。
wget https://url.to.package.deb
sudo dpkg -i filename.deb
安装完后 apt install -f
修复依赖。
18. 查看系统安装的桌面环境
Linux 桌面环境非常灵活,一套系统可以配置多套不同的桌面环境,用户可以根据需要选择不同的桌面。那么如何查看系统上安装了哪些桌面环境呢?
查看 ls /usr/share/xsessions/
即可,也可以通过 ls /usr/bin/*-session
查看。
admin@host:~$ ls /usr/share/xsessions/
gnome.desktop
mate.desktop
ubuntu.desktop
xfce.desktop
xubuntu.desktop
admin@host:~$ ls /usr/bin/*-session
/usr/bin/dbus-run-session
/usr/bin/gnome-session
/usr/bin/mate-session
/usr/bin/sogou-session
/usr/bin/xfce4-session
19. 查看当前使用的桌面环境
admin@host:~$ echo $XDG_CURRENT_DESKTOP
MATE
20. 查看主板类型
命令行查看主板类型:
dmidecode -t 2
更详细信息:
dmidecode -t baseboard
21. 显示NAT IPTABLES 规则
admin@host:~$ sudo iptables -t nat -L
22. sysctl 读写 kernel 变量
admin@host:~$ sysctl -a | grep net.ipv4.ip_forward
net.ipv4.ip_forward = 0
admin@host:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
admin@host:~$ sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
# 或者直接修改 /etc/sysctl.conf 文件
23. RSYNC 使用非默认端口同步数据
# 服务器监听8022端口,从服务器同步文件到本地
user@client:~$ rsync -avz -e "ssh -p 8022" admin@host:/path/to/files/ /local/path/
24. 查看系统所有当前服务状态
user@client:~$ service --sta
25. 无sudo使用docker
安装docker服务的时候会新建用户组 docker:999
,如果没有新建可手动新建该用户组。将需要免sudo使用docker服务的用户添加进docker用户组即可实现无sudo使用docker服务。
user@client:~$ usermod -a -G docker YOUR_USER_NAME
然后检查设置是否生效:id YOUR_USER_NAME
, 如果尚未生效则需要重新登入。
26. pam_tally2
重置账户锁定: pam_tally2 --reset -u xxx
27. scp
路径中包含特殊字符
使用scp
传送文件的时候,如果路径中有特殊字符,可以这样解决:
- 特殊字符使用
\\
进行转义
-路径使用双引号包括起来
两条缺一不可。
28. grep
获取匹配区域上下文
使用grep
命令进行匹配时,通常只输出匹配的内容,有时候我们也需要匹配内容的上下文信息,此时可以使用下面几个参数:
-
-C 5
显示匹配内容的上5行和下5行信息 -
-B 5
仅显示匹配内容的上5行信息 -
-A 5
仅显示匹配内容的下5行信息
29. 获取文件或目录的所有者
有时候在些shell脚本的时候需要判断文件或目录的所有权,这时候可以通过stat
命令快速获得相关信息,如下:
# 获取 user id
stat -c "%u" /path/to/file
# 获取 user name
stat -c "%U" /path/to/file
30. rsync
合并多个文件夹
合并多个文件夹最简单可以采用下面这种方式:
cp -fr folder1/ target/
cp -fr folder2/ target/
cp -fr folder3/ target/
...
但这个操作起来比较麻烦,对重复文件的处理也不友好。用rsync
命令可以实现多个文件夹的合并,灵活性也比较高,示例如下:
rsync -avz folder1/ folder2/ folder3/ ... target/