前言
大一的时候给 IKnowISee多功能AR眼镜 项目写了一个脚本,主要的要求是:1、一个脚本启动多个 python 文件;2、保持这几个 python 进程在前台运行,因为要随时查看控制台输出
当时我使用了 screen
来保留 python 进程的输出,脚本内容如下
#!/bin/bash
echo "项目准备中..."
do_in_screen(){
screen -x -S ${1} -p 0 -X stuff "${2}"
screen -x -S ${1} -p 0 -X stuff $"\n"
}
launch(){
screen -dmS ${1}
do_in_screen ${1} "source activate"
do_in_screen ${1} "conda activate iknowisee"
do_in_screen ${1} "python ${2}"
echo "已启动 ${1}.py"
}
# 设置文件路径
file1="/root/python/Dlib_face_recognition_from_camera-master/main.py"
file2="/root/python/Dlib_face_recognition_from_camera-master/newtest.py"
file3="/root/python/Dlib_face_recognition_from_camera-master/newtest1.py"
file4="/root/python/shuaxin.py"
file5="/root/python/shuaxin-bei.py"
file6="/root/python/openai.py"
echo "关键路径设置成功"
# 运行Python文件
launch "main" "$file1"
launch "newtest" "$file2"
launch "newtest1" "$file3"
launch "shuaxin" "$file4"
launch "shuaxin-bei" "$file5"
echo "完成!"
echo "创建了以下终端"
screen -ls
当时写的时候大量借助了 AI,知其然而不知其所以然,最近又想用 screen
写点小工具,所以认真学习一下这个命令的使用方法
什么是 screen
screen
命令是一个用于管理 Linux 窗口的 bash 程序,使用 screen 命令,你可以启动多个屏幕会话。屏幕会话也可以有多个窗口
screen
命令通过将终端上运行的进程放在不同的会话中来帮助分离它们,screen 命令允许你在会话之间切换并选择要附加的会话
screen
最有用的功能当属其会话恢复功能,只要Screen本身没有终止,在其内部运行的会话都可以恢复
在很多 Linux 发行版中都默认搭载了 screen
,所以在编写脚本时常能直接拿来使用,即使默认没有安装 screen,也可以通过 apt 或者 yum 等软件源来安装
# CentOS
yum install screen
# Debian/Ubuntu
apt install screen
screen 常见用法
创建/退出会话
最简单的用法:创建并进入一个自命名会话
screen -S my_session
在 screen 会话中时,使用 Ctrl-A D 可以在保持会话在后台运行的情况下退出会话
也可以使用下面的命令退出
screen -d
查看会话
我们可以使用 -ls
来查看所有的 screen 会话
screen -ls
输出会类似这样:
# screen -ls
There is a screen on:
599.my_session (09/04/24 22:50:29) (Detached)
1 Socket in /run/screen/S-root.
使用 screen ls [key_word]
可以查看包含指定关键字的会话
# screen -ls session
There is a screen on:
599.my_session (09/04/24 22:50:29) (Detached)
1 Socket in /run/screen/S-root.
进入会话
想要重新进入已经退出的会话,可以使用
screen -r [session]
这里的 [session] 可以是会话的名称,也可以是会话的 id,下面的三种用法都是可以的
screen -r 599
screen -r my_session
screen -r 599.my_session
但是使用 -r
有时候会报错:
# screen -r my_session
There is a screen on:
599.my_session (09/05/24 00:52:53) (Attached)
There is no screen to be resumed matching my_session.
这是因为要进入的会话的状态是 Attached(附加状态,表示该screen正在作为主终端使用)
当有用户进入了某个会话时,那个 session 就会标记为 Attached,使用 screen -d
退出后又会重新回到 Detached(分离状态,表示该screen正在后台使用)
此时可以使用下面的命令来进入处于附加状态的会话
screen -x my_session
该命令对于 Detached session 的效果和 -r
相同,对于 Attached session 则会在不影响原有使用者的情况下进入会话,此时你在 session 中进行的所有操作,会同步展示给原本的使用者,其他人的操作也一样,相当于”多人同时在一个屏幕中工作“
删除会话
可以在会话中使用 exit 来退出会话,这种退出方式会同时删除 session
screen -r my_session # 进入会话
exit # 退出
也可以使用下面的命令
screen -S my_session -X quit
-S 指定了要操作的 session 名称
-X 的作用是发送命令至会话, 这里发送了quit命令, 也就是关闭会话的命令
窗口操作
screen 可以在一个会话中创建多个窗口,并在窗口之间切换
稍微不好的一点:窗口操作只能用组合键来完成,对脚本不太友好
Ctrl-a c
:创建一个新的窗口,并切换到该窗口Ctrl-a p/n
:切换到 上一个/下一个 窗口Ctrl-a [0-9]
:切换到指定编号的窗口Ctrl-a q
:关闭当前窗口Ctrl-a "
:列出所有窗口,并显示它们的编号
一些对脚本友好的用法
创建具名会话但不进入
screen -dmS my_session
向指定会话发送命令
screen -x -S [session] -p 0 -X stuff "[command]\n"
-x:仅在需要附加到一个已经存在的、并且已经分离的 screen 会话时使用
-S [session]:用于指定会话的名称,如果会话已经存在并且你想要附加到它,这是必要的
-p 0:指定要发送命令的窗口索引,0 表示第一个窗口
-X stuff “[command]\n”:向 screen 会话发送指定的命令,\n模仿键盘回车进行命令执行
销毁一个正在运行的会话
PID=`screen -ls | grep -w [session] | awk '{print $1}' | cut -d '.' -f1`
kill -9 $PID
screen -wip
使用 grep + awk + cut 获取指定名称的 session 的 pid,然后直接 kill 掉进程,最后使用 wip 销毁被 kill 的会话
文章有(1)条网友点评
终于看到我会的了