我的需求是 go 在启动的时候把自生加入开机自启,并且不依赖其他软件。
我在 windows 环境,go 可以新建一个文件(AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\start.bat
),在脚本内可以调用 exe 程序 重启就会自动启动
但是在 linux 上,我把编译后的 go 文件进行执行,里面的代码有一句是 os.Create("/etc/init.d/start.sh")
在创建时 会创建失败,我以为是权限的问题 ,但是我是使用的是root
用户,并且使用chmod 777
了。
实际上 执行 os.Create("/tmp/start.sh")
是成功的
查到的方案基本上都是通过用shell
, 但是这样需要手动的添加
有没有办法解决linux
执行 os.Create("/tmp/start.sh")
失败的问题
linux 权限如下:
[root@localhost etc]# pwd
/etc
[root@localhost etc]# ll | grep init
drwxr-xr-x. 2 root root 24 Sep 27 23:42 gdbinit.d
lrwxrwxrwx. 1 root root 11 Sep 27 23:30 init.d -> rc.d/init.d
-rw-r--r--. 1 root root 511 Nov 16 2020 inittab
[root@localhost application]# ll
total 2076
-rwxr-xr-x. 1 root root 2111964 Oct 17 11:05 start
1
exkernel 2023-10-17 16:24:21 +08:00 1
|
2
xiao201261 2023-10-17 16:24:53 +08:00 1
你是打算跑 docker 还是?
init.d(openrc) 或者什么的是很古老写法,在现代的 Linux 现在应该使用 systemd 来守护,来启动进程。 |
3
bg7lgb 2023-10-17 16:27:25 +08:00
直接加在 rc.local
|
4
liarsa 2023-10-17 16:28:13 +08:00
我同意二楼同学的说法
|
5
julyclyde 2023-10-17 16:36:40 +08:00
建议参考一下/t/982696
|
7
leegoo OP @xiao201261 不跑 docker ,如果用 systemd 也需要自己手动编写脚本把(我的意思是没办法在程序中自动加入开机自启)
|
8
julyclyde 2023-10-17 16:45:05 +08:00
@leegoo 正儿八经的需求,找一个并不懂这方面知识的人来做?并没觉得这需求有多么正儿八经
你在 windows 环境设置的那个是用户级自动启动吧,是登录之后才有的 服务器哪儿有机会让你登录啊 设置系统级自动启动需要系统级的权限,不是你想写就能随便往里写的 |
9
xiao201261 2023-10-17 16:51:05 +08:00
@leegoo 如果你还是想直接加 init.d 的话,你可以检查一下 selinux 是否阻止了你的程序往 /etc/init.d 加文件 用 dmesg 看最近几条日志就知道了。
===== 让进程守护是个复杂的操作,什么不需要写脚本呢? 让什么用户运行你的程序? 是不是要等待网络或者数据库启动后再运行?(优先级) 要不要限制什么权限? 原始的 /etc/init.d 里面也是有不少的配置选项呢,脚本量和 systemd 相比差不了多少(何况你系统基本也是 systemd 运行的,保留 /etc/init.d 只是为了兼容) 难道你的启动脚本就一行,用来启动 go 的程序就撒手不管了? 真的,跑服务有很多需要考虑的东西,不要只启动就行了,守护在哪里,日志放哪里..... |
10
leegoo OP @julyclyde 大哥,我觉得你真是有点没事找事。公司有这个需求,我只是来实现而已。你为什么非要觉得我要搞一个最大权限?
意思是公司派了一个需求,又只有你适合去做这个事情,你不做吗? 不是每个公司都有专职的 DBA 和运维 |
12
rimutuyuan 2023-10-17 17:08:51 +08:00
为什么不写在 shell 脚本去启动呢
|
13
XiLingHost 2023-10-17 17:11:40 +08:00 1
写个 systemd 的 unit 不就好了,然后程序里把 unit 链接到/etc/systemd/system/multi-user.target.wants/
|
14
purrgil 2023-10-17 17:15:30 +08:00
windows 下我用任务计划自启。
还能同时做到间隔几分钟自启,防止程序被杀掉。 linux 下对应的当然是 crontab 了。 |
15
purrgil 2023-10-17 17:20:17 +08:00
你把程序放 Startup 里启动,那服务器每次重启是不是要进桌面才会启动?
|
16
julyclyde 2023-10-17 17:21:26 +08:00
|
18
zmaplex 2023-10-17 17:36:15 +08:00 via Android
你都有 root 了,可以写 /etc/systemd/system/ 里面,用 systemd 来管理。
|
20
stephenxiaxy 2023-10-17 17:51:32 +08:00
systemd
|
21
tairan2006 2023-10-17 18:35:13 +08:00
|
23
kkocdko 2023-10-17 19:04:00 +08:00
如果是实体机,请你通过 systemd 的 service 做。由 systemd 完成自启动,自动拉起,日志管理等等。
|
24
kkocdko 2023-10-17 19:05:55 +08:00
emmm ,看到楼上的回复了,楼主你想怎么做就怎么做吧
|
25
X4hB5a 2023-10-17 19:35:00 +08:00
|
26
liberize 2023-10-17 19:38:41 +08:00 via Android
如果是桌面程序,可以在~/.config/autostart 下创建一个.desktop 文件,基本对标 windows
如果是服务端程序,可以在/etc/systemd/system 下面创建一个.service 文件,需要 root |
29
expy 2023-10-17 19:48:49 +08:00
参考服务器被入侵挖矿的,用 cron 。
|
30
kingfalse 2023-10-17 20:03:06 +08:00 via Android
crontab ,每分钟执行一次 sh ,判断没有进程就启动,这不安全的多,兼容性极佳
|
33
ksc010 2023-10-17 20:22:21 +08:00
可以 用 supervisor
|
34
skywalkerfc 2023-10-17 20:50:43 +08:00
cron 定时任务
systemd/init.d 后台常驻进程(更偏系统层,随 Linux 启动而启动) supervisor 后台常驻进程(更偏用户层,一般用来管理自己写的常驻脚本偏多) |
35
yanqiyu 2023-10-17 21:15:58 +08:00
> 我的需求是 go 在启动的时候把自生加入开机自启,并且不依赖其他软件。
"并且不依赖其他软件"? 要是 init 都不想依赖那就麻烦了,建议添加 init=你的程序 替代掉 init ,启动自身之后创建容器启动原来的 init 作为给用户的系统 开个玩笑 你得依赖点什么东西,要是 systemd 就创建 systemd unit: https://www.freedesktop.org/software/systemd/man/systemd.unit.html 要是 sysV init 就是/etc/rc.d/xxx.sh, /etc/init.d/,/etc/rc.d/init.d 写好一个可用的 systemd unit 没那么难。 以及就算创建文件失败至少给点失败的信息,不然大家水晶球也水晶不出来 |
36
SenLief 2023-10-17 23:07:34 +08:00 via iPhone
systemd.service
|
37
voidmnwzp 2023-10-18 00:03:49 +08:00
注册服务然后自启动
|
38
pyu77 2023-10-18 09:57:40 +08:00
shell 脚本写个,然后放到 rc.local 启动就拉起来。
想要中断后自动拉起,可以加到 crontab 定时任务。 |
40
tangtang369 2023-10-18 11:27:38 +08:00
一楼的答案就是正解 如果用 Go 的话都是用这个第三方模块来实现
|
42
julyclyde 2023-10-18 12:22:17 +08:00
|
43
ysc3839 2023-10-18 13:01:29 +08:00 via Android
@julyclyde 不需要吧,至少通过 StartTransientUnit 创建临时 service 不需要特殊权限
|
44
julyclyde 2023-10-18 13:07:29 +08:00
@ysc3839 StartTransientUnit 是指从 dbus 接口创建吗 user 级别的 unit 吧?
那由哪个程序来发这个消息呢?发消息的这个程序是怎么运行起来呢? |
45
ysc3839 2023-10-18 13:22:39 +08:00 via Android
@julyclyde 只是举例子说明可以免额外权限创建用户级的 service ,不是说一定要用这种方案。具体能否 enable 一个用户级的 service ,我没调查过,但我猜测是可以的。
|
46
julyclyde 2023-10-18 13:38:29 +08:00
@ysc3839 但是 TransientUnit 不能“下次开机”的时候自动启动吧?那东西的 unit file 根本就不存盘吧
无法满足 OP 的需求 |
49
julyclyde 2023-10-18 20:06:03 +08:00
@gejigeji 旧版本 systemd 对于大量 session 累积的情况,会无法正常清理。“理论上”进程退出之后,session 应该退出,但实际上没做到
|
51
julyclyde 2023-10-20 21:55:13 +08:00
@gejigeji 应该也会。session 是由/etc/pam.d/crond 生成的。
不过我没实际试过…… 抛开 session 的问题不说,服务进程的“上级”是 crond 就够奇怪了,和上级是个 login shell 差不多奇怪 |
52
alsas 2023-11-01 16:38:00 +08:00
systemd
|