Systemd 服务管理
服务文件路径:/etc/systemd/system/
CLI
1. sudo systemctl daemon-reload
作用:重新加载 systemd 服务配置文件
使用时机:当你修改了 .service 文件后必须执行
# 比如你修改了 /etc/systemd/system/flaskapp.servicesudo nano /etc/systemd/system/flaskapp.servicesudo systemctl daemon-reload # 让 systemd 知道配置变了2. sudo systemctl enable <服务名>
作用:启用服务,让它在系统启动时自动运行
# 启用服务(开机自启)sudo systemctl enable <服务名>
# 禁用服务(不开机自启)sudo systemctl disable <服务名>3. sudo systemctl start <服务名>
作用:立即启动服务
# 启动服务sudo systemctl start <服务名>
# 停止服务sudo systemctl stop <服务名>
# 重启服务sudo systemctl restart <服务名>4. sudo systemctl status <服务名>
作用:查看服务的运行状态和日志
# 查看状态sudo systemctl status <服务名>
# 查看详细日志sudo journalctl -u <服务名> -f第一次设置服务时:
# 1. 创建服务文件sudo vim /etc/systemd/system/flaskapp.service
# 2. 重新加载配置(让 systemd 认识新服务)sudo systemctl daemon-reload
# 3. 启用服务(开机自启)sudo systemctl enable flaskapp
# 4. 启动服务sudo systemctl start flaskapp
# 5. 检查状态sudo systemctl status flaskapp日常管理:
# 查看状态sudo systemctl status flaskapp
# 重启服务(部署新代码后)sudo systemctl restart flaskapp
# 停止服务sudo systemctl stop flaskapp
# 查看日志sudo journalctl -u flaskapp -f服务配置文件
[Unit]Description=Flask Backend ApplicationAfter=network.target #依赖关系,在网络服务启动之后启动服务
[Service]Type=simpleUser=root #执行用户WorkingDirectory=/root/flask_backendEnvironment=PATH=/root/flask_backend/.venv/binExecStart=gunicorn -w 2 -b 0.0.0.0:5000 "flaskr:create_app()" #执行指令Restart=always
[Install]WantedBy=multi-user.targetTimer文件
如果需要定时启动执行任务,可以使用Timer文件 必须和service文件同名,比如backup.service,backup.timer
[Unit]Description=Run backup daily at 2 AMRequires=backup.service # 依赖的服务
[Timer]# 定时方式(可同时使用多种)OnCalendar=daily # 每天OnCalendar=*-*-* 02:00:00 # 每天2点(更精确)OnBootSec=15min # 启动后15分钟OnUnitActiveSec=1h # 上次激活后1小时
# 时间参数AccuracySec=1h # 精度1小时内执行即可RandomizedDelaySec=30min # 随机延迟0-30分钟Persistent=true # 错过时间后补执行Unit=my-backup.service # 关联的 Service
[Install]WantedBy=timers.target # 开机自启进程管理
父进程启动的子进程,会在父进程断开后,子进程也会自动关闭。 所以用ssh启动的想长期开启的服务将会在ssh断开后停止。 可以使用screen,tmux,nohup,systemd,docker来守护进程,这样的话启动的服务将不在ssh的bash进程下了。
常用进程管理命令
ps #展示当前用户的进程ps aux #所有用户的进程ps auxf #进程树ps -fp <pid> #可以显示进程的详细信息| 信号 | 数字代号 | 命令示例 | 行为 | 适用场景 |
|---|---|---|---|---|
| SIGTERM (终止) | 15 (默认) | kill -15 <PID> | 优雅终止,允许进程清理后退出 | 首选方式,正常关闭进程 |
| SIGKILL (强制终止) | 9 | kill -9 <PID> | 强制立即终止,不给清理机会 | 进程卡死、不响应 SIGTERM 时 |
| SIGINT (中断) | 2 | kill -2 <PID> | 模拟 Ctrl+C,通常优雅终止 | 交互式程序中断 |
| SIGSTOP (暂停) | 19 | kill -19 <PID> | 暂停进程(可恢复) | 临时挂起进程 |
kill [信号] <PID>权限管理
文件管理
命令
chmod <权限数> <文件路径>#-R递归更改文件夹下的所有权限chown [-R] <用户名:用户组> <文件路径>#只更改所有组chgrp <组名> <文件路径>基本权限数字
- 4 = 读 (Read) =
r - 2 = 写 (Write) =
w - 1 = 执行 (Execute) =
x
权限组合运算
# 举例:rwx = 4+2+1 = 7 # 读写执行rw- = 4+2+0 = 6 # 读写r-x = 4+0+1 = 5 # 读执行r-- = 4+0+0 = 4 # 只读-wx = 0+2+1 = 3 # 写执行-w- = 0+2+0 = 2 # 只写--x = 0+0+1 = 1 # 只执行--- = 0+0+0 = 0 # 无权限三位数权限表示
chmod 命令中的三位数字分别代表:
用户(owner) 组(group) 其他用户(other) ↓ ↓ ↓ abc例如:
chmod 765 file.txt# 7(4+2+1)=rwx 所有者:读写执行# 6(4+2+0)=rw- 组用户:读写# 5(4+0+1)=r-x 其他用户:读执行ls -l#可以查出文件权限,比如这个就是644-rw-r--r-- 1 root root 3444 Jul 6 2023 <文件名>用户管理
配置文件
/etc/passwd
uid(User id)
gid(Group id)
创建用户时可以指定家目录,或者不创建家目录
可以设置登录shell,zsh,bash,fish等等,为了安全可以使用/usr/sbin/nologin让此用户无法登录。
#用户名:密码占位符:<uid>:<gid>:[备注]:[家目录]:<登录shell>cannian:x:1000:1001::/home/cannian:/bin/bash/etc/shadow
密码加密库。只有 root 能读取,存放加密后的密码 hash 及过期策略。
创建用户
-m 可以选择创建家目录,-s可以选择/usr/sbin/nologin来禁止外部登录。如果指定了shell就可以登录了
useradd [参数] <用户名>修改用户
usermod [参数] <用户名>参数:
- -aG <组名或Gid>,追加到组
- -u ,改uid
- -s [shell路径],更改shell,比如
/usr/sbin/bash或者禁止登录的shell,/usr/sbin/nologin
删除用户
userdel <用户名>参数:-r ,删除家目录
设置密码
passwd [用户名]默认修改自己的密码,指定用户名更改别的用户
用户组管理
配置文件
/etc/group定义了哪些用户属于哪个组
CLI
创建用户组
groupadd <组名/Gid>删除用户组
groupdel <组名/Gid>更改用户组
groupmod常用的组
sudo
把用户加入到这个组就可以使用sudo命令,/etc/sudoers这个配置文件可以详细配置各个sudo组的成员有哪些命令权限
查看信息
id [用户名]w #告诉你谁登录了,还告诉你每个人正在干什么以及系统有多忙,更详细who #列出当前所有已经登录到系统的用户。whoami #当前用户是谁groups [用户名] #列出用户的用户组Crontab
使用Crontab来定时执行任务
CLI
# 编辑当前用户的配置crontab -e
#使用root用户配置sudo crontab -e
# 列出当前用户的 crontabcrontab -l
# 删除当前用户的 crontabcrontab -r配置
进去之后每行一个配置,例如
* * * * * cd /your/work/path && ./script.py >> ./log/script.log 2>&1 ^ ^ ^ ^ ^ ^时间参数 切换到工作路径 || 标准输出追加到文件 把标准错误重定向到标准输出 执行的命令>> 操作符
# 标准输出(stdout)追加到文件command >> file.log# 效果:每次执行追加内容,不会覆盖旧日志
# 对比 `>`:覆盖写入command > file.log # 每次执行覆盖文件2>&1 操作符
# 将标准错误(stderr,文件描述符2)重定向到标准输出(stdout,文件描述符1)command 2>&1# 效果:错误信息和正常输出都到同一个地方
# 所以:command >> file.log 2>&1# 意思是:标准输出追加到文件,标准错误也重定向到标准输出时间格式
基本格式:5个星号
* * * * * 要执行的命令│ │ │ │ ││ │ │ │ └─ 星期几 (0-7) 0和7都是周日│ │ │ └─ 月份 (1-12)│ │ └─ 日期 (1-31)│ └─ 小时 (0-23)└─ 分钟 (0-59)每个字段的取值
*代表所有
- 分钟:0-59
- 小时:0-23
- 日期:1-31
- 月份:1-12
- 星期:0-7(0和7都是周日,1=周一,6=周六)
特殊符号解释
1. 逗号 ,(多个时间点)
# 每天3点和15点执行0 3,15 * * * command.sh
# 每周一、三、五的10点30分30 10 * * 1,3,5 command.sh2. 连字符 -(时间范围)
# 工作日上午9点到下午5点,每小时执行0 9-17 * * 1-5 command.sh
# 每月1-10号的凌晨2点0 2 1-10 * * command.sh3. 斜杠 /(间隔时间)
# 每5分钟执行一次*/5 * * * * command.sh# 等价于:0,5,10,15,20,25,30,35,40,45,50,55
# 每3小时的0分钟执行0 */3 * * * command.sh# 等价于:0 0,3,6,9,12,15,18,21 * * *
# 每2天的中午12点0 12 */2 * * command.sh示例
-
-
-
-
-
- :每分钟执行一次
-
-
-
-
- 0 * * * * :每小时的第0分钟执行一次
- 0 1 * * * :每天的1点整执行一次
- 0 1 2 * * :每月2号的1点整执行一次
- 0 1 2 3 * :每年的3月2号的1点整执行一次
- 0 1 2 3 4 :每年的3月2号和每年3月的每个星期4的1点整执行一次
- */30 9-17 * * 1-5 :周一到周五的9-17点,每30分钟执行一次
- 0 10,14 1,15 * * : 每月1号和15号的上午10点、下午2点 https://crontab.guru/这个网站可以进行crontab验证
系统crontab
# 系统级 crontab 文件位置/etc/crontab# 格式包含用户字段:* * * * * username command
# 系统 cron 目录/etc/cron.d/ # 自定义 cron 文件/etc/cron.daily/ # 每天执行/etc/cron.hourly/ # 每小时执行/etc/cron.weekly/ # 每周执行/etc/cron.monthly/ # 每月执行配置和用户crontab有点区别
* * * * * root /path/to/command0 2 * * * www-data /path/to/backup.sh需要指定用户字段,确定用谁的权限来执行任务
环境变量
env #查看现有的环境变量系统级环境变量
影响范围:对机器上所有用户、所有进程生效。
- /etc/environment
- /etc/profile
用户级环境变量
影响范围:仅对当前登录用户生效,使用source
- ~/.profile
- ~/.bashrc
- ~/.zshrc
示例
# 设置别名alias ll='ls -la'alias gs='git status'
# 设置用户级环境变量export PATH="$PATH:$HOME/bin"export EDITOR=vimexport MY_CUSTOM_VAR="hello"export https_proxy="socks5://proxy_server:port"
# 自定义提示符export PS1='\u@\h:\w\$ '会话级
只有这个shell里生效,结束会话就没了。使用export指令
示例
# HTTP/HTTPS 代理export http_proxy="http://proxy_server:port"export https_proxy="http://proxy_server:port"export HTTP_PROXY="http://proxy_server:port"export HTTPS_PROXY="http://proxy_server:port"实用工具
man (manual手册)
会调用vim打开详细说明
man duman lswc (Word Count)
wc -l #数行数wc -w #数字数wc -c #数字节find
扫描路径下的所有文件,默认不包括链接,有需求的话-L,小心无限循环!和|管道符配合可以检索你需要的。
find <path> [-maxdepth\-type]grep
g(global全局) re(Regular Expression正则) p(pring打印) find,docker composes logs这种都是按行输出的,你使用grep用正则匹配某些行,比如说find可以用来找文件,logs可以直接找error之类的日志。
-i不区分大小写匹配grep -i "docker"#可以和find之类的所有标准输出的命令组合find . | grep -i "docker" #在当前路径下列出所有的带有docker名称的文件或文件夹df (Disk Free)
#和du相对应df -hdu (Disk Usage)
查看路径的硬盘占用。
#-s,summary.-h,humandu -sh <path>wget
命令行下载工具
wget [选项] [URL]| 常用选项 | 说明 |
|---|---|
| -O filename | 指定文件名 |
| -c | 断点续传 |
| -b | 后台下载 |
tar
常用的归档工具
tar [选项] [文件或目录]选项太多了,只记常用的就行
# 1. 创建压缩包tar -czf 文件名.tar.gz 要压缩的目录/
# 2. 解压(万能)tar -xf 压缩包文件名
# 3. 查看内容tar -tf 压缩包文件名zip
同时归档并压缩,跨平台兼容性最好
ip
选项功能也很多,只记常用的
ip a # 查看所有网络接口 (address)ip r # 查看路由表 (route)ip l # 查看链路状态 (link)iptable(防火墙)
不要直接改底层的iptable,建议所有全用ufw管理。
sudo iptables -A INPUT -s 123.456.78.9 -j DROP #拒绝一个ip连接sudo iptables -A INPUT -s 123.456.0.0/16 -j DROP #也可以使用掩码来拒绝一个网段ufw(Uncomplicated firewall)
不复杂的防火墙,iptable的命令太复杂了,有个更简单的。
#封禁网段sudo ufw deny from 192.168.1.100/32#允许某个网段访问所有的端口sudo ufw allow from 123.45.67.89#开放80端口sudo ufw allow 80#列举出所有的防火墙规则sudo ufw status numbered#删除对应number的规则sudo ufw delete 21#列举规则还有默认策略:一般来说入站全部拒绝,出战全部允许sudo ufw status verboseipset
sudo apt install ipset#创建一个黑名单表sudo ipset create blacklist hash:ip#绑定到iptable里,拒绝这里面的ipsudo iptables -I INPUT 1 -m set --match-set blacklist src -j DROP#给这个名单添加ipsudo ipset add blacklist <IP>sudo ipset del blacklist <IP>ss
上面的防火墙只是开放了端口,ss可以查出来什么进程占用了什么端口,这个端口是udp还是tcp等等
sudo ss -tulpn#可以和grep组合用,来找什么进程占用了什么端口sudo ss -tulpn | grep "4321"tail
#输出文件末尾10行tail <文件名>#流式输出文件末尾tail -f <文件名>#输出末尾50行tail -n 50 <文件名>homebrew
包管理器,版本更新的快。
wireguard
windows电脑连接可能会有mtu过大丢包的问题,如果查看日志之类的需要传大包的时候加载不出来那就要设置mtu了,建议设置小点
输出重定向
python main.py 1> file:stdout输出到filepython main.py 2> file:stderr输出到filepython main.py 1> file 2>&1:先把stdout定向到file,再把stderr定向到stdout