开机自启动某个任务

基础版本

​ 工作之余用写的。就是把 一个脚本A 做成 一个服务A,然后每次开机自动调用这个服务。
脚本A直接写在下面这个脚本里面,运行下面这个脚本一步一步来就好了,这里是开机自启动jypyter-lab的一个命令。
​ 如果有什么问题,去检查一下 我写入的log 文件夹中的文件。 有时候 要一些模块类似 pip install typing_extensions。

Auto_start_jupyter.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/bash                                                                                                                                                           

# 读取用户输入的密码
read -sp "请输入你的root密码: " root_password
echo

# 切换到 root 用户并执行命令
echo "$root_password" | sudo -S -p '' bash -c '


# 在 /home/jlsf/ 下创建一个 log 文件夹,不会覆盖已存在的文件夹
echo "在 /home/jlsf/ 下创建一个 log 文件夹,不会覆盖已存在的文件夹"
mkdir -p /home/jlsf/log
if [ $? -ne 0 ]; then
echo "Failed to create log folder." >&2
exit 1
else
echo "Log folder created or already exists."
fi


# 检查是否存在 /home/jlsf/Auto_start_jupyter.sh 脚本,如果不存在则创建
echo "检查是否存在 /home/jlsf/Auto_start_jupyter.sh 脚本,如果不存在则创建"
if [ ! -f /home/jlsf/Auto_start_jupyter.sh ]; then
cat << 'SCRIPT' > /home/jlsf/Auto_start_jupyter.sh
#!/bin/bash
/usr/bin/nohup /home/jlsf/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --allow-root >> /home/jlsf/log/myscript.log 2>&1 &
# /home/jlsf/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --allow-root >> /home/jlsf/log/myscript.log 2>&1
SCRIPT
if [ $? -ne 0 ]; then
echo "Failed to create Auto_start_jupyter.sh script." >&2
exit 1
else
echo "Auto_start_jupyter.sh script created."
fi
else
echo "Auto_start_jupyter.sh script already exists."
fi


# 尝试添加 Auto_start_jupyter.sh 脚本权限
echo "尝试添加 Auto_start_jupyter.sh 脚本权限。"
chown jlsf:jlsf /home/jlsf/Auto_start_jupyter.sh
chown jlsf:jlsf /home/jlsf/log
chmod 776 /home/jlsf/Auto_start_jupyter.sh
if [ $? -ne 0 ]; then
echo "Failed to set permissions on Auto_start_jupyter.sh script." >&2
exit 1
else
echo "Permissions set on Auto_start_jupyter.sh script."
fi


# 创建 systemd 服务单元文件
echo "创建 systemd 服务单元文件"
if [ ! -f /etc/systemd/system/Auto_start_jupyter.service ]; then
cat << 'SERVICE' > /etc/systemd/system/Auto_start_jupyter.service
[Unit]
Description=Jupyter Lab Service
After=network.target

[Service]
Type=forking
ExecStart=/home/jlsf/Auto_start_jupyter.sh
StandardOutput=append:/var/log/my_program.log
StandardError=append:/var/log/my_program.log
Restart=always
User=jlsf
WorkingDirectory=/home/jlsf

[Install]
WantedBy=multi-user.target
SERVICE
if [ $? -ne 0 ]; then
echo "Failed to create Auto_start_jupyter.service." >&2
exit 1
else
echo "Auto_start_jupyter.service created."
fi
else
echo "Auto_start_jupyter.service already exists."
fi


# 重新加载 systemd 配置
echo "重新加载 systemd 配置"
systemctl daemon-reload
if [ $? -ne 0 ]; then
echo "Failed to reload systemd daemon." >&2
exit 1
else
echo "Systemd daemon reloaded."
fi


# # 重置服务的启动限制计数
# echo "重置服务的启动限制计数"
# systemctl reset-failed
# if [ $? -ne 0 ]; then
# echo "Failed to reset-failed systemd service." >&2
# exit 1
# else
# echo "Systemd service reset-failed success."
# fi


# 启用并启动服务
echo "启用并启动服务"
systemctl enable Auto_start_jupyter.service
if [ $? -ne 0 ]; then
echo "Failed to enable Auto_start_jupyter.service." >&2
exit 1
else
echo "Auto_start_jupyter.service enabled."
fi
echo "现在开始开启服务"
systemctl start Auto_start_jupyter.service
# if [ $? -ne 0 ]; then
# echo "Failed to start Auto_start_jupyter.service." >&2
# exit 1
# else
# echo "Auto_start_jupyter.service started."
# fi

# 检查服务状态
echo "检查服务状态"
systemctl status Auto_start_jupyter.service


'

改进

Auto_start_jupyter.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/bin/bash

# 读取用户输入的密码
read -sp "请输入你的root密码: " root_password
echo

# 切换到 root 用户并执行一系列配置命令
echo "$root_password" | sudo -S -p '' bash -s <<'EOF'

echo "-----------------------------------------------------"
echo "开始配置 Jupyter Lab 的 systemd 自启动服务..."
echo "-----------------------------------------------------"

# 步骤 1: 创建或更新 systemd 服务单元文件
echo "--> 正在创建优化的 systemd 服务文件: /etc/systemd/system/Auto_start_jupyter.service"

cat << 'SERVICE' > /etc/systemd/system/Auto_start_jupyter.service
[Unit]
Description=Jupyter Lab Service
After=network.target

[Service]
Type=simple
ExecStart=/home/dell/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --allow-root
User=dell
WorkingDirectory=/home/dell
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
SERVICE

echo "成功创建或更新了 Auto_start_jupyter.service 文件。"

# 步骤 2: 重新加载 systemd 配置
systemctl daemon-reload
echo "Systemd 配置已重新加载。"

# 步骤 3: 设置开机自启
systemctl enable Auto_start_jupyter.service
echo "Auto_start_jupyter.service 已被设置为开机自启。"

# 步骤 4: 启动服务
systemctl restart Auto_start_jupyter.service
echo "Auto_start_jupyter.service 已成功启动。"

echo ""
echo "-----------------------------------------------------"
echo "配置完成!正在检查服务的当前状态..."
echo "-----------------------------------------------------"
sleep 2
systemctl status Auto_start_jupyter.service --no-pager -l
echo "-----------------------------------------------------"
echo "如果服务状态显示为 active (running),则表示一切正常。"
echo "如果失败,请用: sudo journalctl -u Auto_start_jupyter.service -n 50 --no-pager"
echo "-----------------------------------------------------"

EOF

改成要把一个脚本做成服务

写脚本 start_jupyter.sh

这里要求 这个脚本内部不能有 nuhup 或者 是 & ,不然可能导致不会被运行。

1
~/.local/bin/jupyter lab --no-browser --ip=0.0.0.0 --allow-root

Auto_start_jupyter.sh ,把 上面的脚本做成一个开机自启动的服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/bin/bash

# 读取用户输入的密码
read -sp "请输入你的root密码: " root_password
echo

# 切换到 root 用户并执行一系列配置命令
echo "$root_password" | sudo -S -p '' bash -s <<'EOF'

echo "-----------------------------------------------------"
echo "开始配置 Python 脚本的 systemd 自启动服务..."
echo "-----------------------------------------------------"

# 步骤 1: 创建或更新 systemd 服务单元文件
echo "--> 正在创建 systemd 服务文件: /etc/systemd/system/Auto_start_task.service"

cat << 'SERVICE' > /etc/systemd/system/Auto_start_task.service
[Unit]
Description=Auto Start Python Task
After=network.target

[Service]
Type=simple
User=cys
WorkingDirectory=/home/cys
ExecStart=/bin/bash start_jupyter.sh
Restart=always
RestartSec=5
StandardOutput=append:/home/cys/auto_task.log
StandardError=append:/home/cys/auto_task_error.log

[Install]
WantedBy=multi-user.target
SERVICE

echo "成功创建或更新了 Auto_start_task.service 文件。"

# 步骤 2: 重新加载 systemd 配置
systemctl daemon-reload
echo "Systemd 配置已重新加载。"

# 步骤 3: 设置开机自启
systemctl enable Auto_start_task.service
echo "Auto_start_task.service 已被设置为开机自启。"

# 步骤 4: 启动服务
systemctl restart Auto_start_task.service
echo "Auto_start_task.service 已成功启动。"

echo ""
echo "-----------------------------------------------------"
echo "配置完成!正在检查服务的当前状态..."
echo "-----------------------------------------------------"
sleep 2
systemctl status Auto_start_task.service --no-pager -l
echo "-----------------------------------------------------"
echo "如果服务状态显示为 active (running),则表示一切正常。"
echo "日志路径:/home/cys/auto_task.log 和 /home/cys/auto_task_error.log"
echo "-----------------------------------------------------"

EOF

运行 这个脚本即可。

补充一些常见问题:

问题一:遇到缺少jupyter_core的报错,导致jupyter没有自启动。

1
2
3
4
Traceback (most recent call last):
File "/home/jlsf/.local/bin/jupyter", line 5, in <module>
from jupyter_core.command import main
ModuleNotFoundError: No module named 'jupyter_core'
1
2
3
4
5
packages/jupyterlab/serverextension.py", line 4, in <module>
from jupyter_server.utils import url_path_join
File "/home/jlsf/.local/lib/python3.8/site-packages/jupyter_server/utils.py", line 25, in <module>
from packaging.version import Version
ModuleNotFoundError: No module named 'packaging'

这两报错,一般是因为 Python 环境中缺少 packaging 模块。这是 Jupyter Lab 的关键依赖项。

运行以下命令检查你的 Python 和 pip 环境是否一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查 Python 路径
which python
python --version

# 检查 pip 路径和版本
which pip
pip --version

# 检查 packaging 是否已安装
pip list | grep packaging

# 检查 Python 是否能找到 packaging
python -c "import sys; print(sys.path)"
python -c "import packaging; print(packaging.__file__)"

如果这样

1
2
3
4
5
6
7
8
9
(base) jlsf@admin:~$ python3.8 --version
Python 3.8.10
(base) jlsf@admin:~$ python3.8 -m pip --version
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
(base) jlsf@admin:~$ which pip
/home/jlsf/data/miniconda/bin/pip
(base) jlsf@admin:~$ which python3.8
/usr/bin/python3.8
(base) jlsf@admin:~$

说明环境存在 Python 和 pip 不匹配 的问题;pip是conda 里面的。

解决:

统一使用系统 Python

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 暂时离开 conda 环境
conda deactivate

# 2. 确认 pip 现在指向系统 Python
which pip
python3.8 -m pip --version

# 3. 使用 python3.8 -m pip 安装所有包
python3.8 -m pip install --user --upgrade pip
python3.8 -m pip install --user packaging jupyter_core jupyter_server jupyterlab

# 4. 启动 Jupyter Lab
python3.8 -m jupyter lab

检查

1
2
3
4
5
6
7
8
9
# 检查 Python 和 pip 是否匹配
which python
which pip
python -c "import sys; print(sys.executable)"

# 检查包是否可导入
python -c "import packaging; import jupyter_core; print('OK')"

sudo reboot # 看看 jupyter 有没有自启动。