
我的需求是 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 |
2 xiao201261 2023-10-17 16:24:53 +08:00 你是打算跑 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 14v45mJPBYJW8dT7 2023-10-17 17:08:51 +08:00 为什么不写在 shell 脚本去启动呢 |
13 KagurazakaNyaa 2023-10-17 17:11:40 +08:00 写个 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 huangzhiyia 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 |