linux shell script 求解惑
https://img1.doubanio.com/view/status/l/public/395c6f67fb6abd8.webphttps://s3.bmp.ovh/imgs/2022/04/01/dd0f6c259e72b65a.jpg
先声明我不是超能力者,最多写点 python bash 这种低等胶水语言。所以我的问题可能非常非常愚蠢,希望诸位超能力者多多海涵。
最近在折腾linux桌面,写状态栏脚本的时候遇到了一点问题。如上图所示,我的状态栏其实是一堆 bash 脚本,设置鼠标动作可以触发命令。右边的脚本是显示电池状态的,左击会在vim里打开这个脚本。但是由于这个脚本打开了一个vim,在我关闭这个vim之前它会一直悬挂在这里不会更新状态,像左边这个htop tree显示的一样。这对于一个按时间周期更新电池状态的脚本来说不算大问题,但对于其他脚本来说可能就不是这么一回事了。
我想知道有没有方法让脚本A运行另一个脚本或者命令B,但不在A下运行,i.e., A的剩余部分也能直接运行下去,A重启或者关闭也不会导致B关闭(我不知道我的表述是否正确)。在这里&显然是不管用的,nohup和disown好像也不对。我浅薄的unix知识已经没法handle这个问题了,希望超能力者们能指点一二。
就是运行一个后台程序?以我浅薄的linux知识来看这不就是 & 可以解决的么……还是我没理解你的需求 楼上+1. 虽然我也是bash菜鸡(一切bash能干的东西我都可以用ruby来干!),但是,在A里直接写 (B &) 这样不行吗? 本质上是让 B 不再是 A 的子进程,nohup 或者 disown 应该都可以,不行的表现是什么? 看完你的描述我觉得nohup &显然是有用的,你是遇到了什么问题..? tmux 左键点击会打开编辑是状态栏行为吗,如果是就是设计如此,不应该绕过 fork exec
用脚本就是 ( 你的脚本 &)
当然最好输入输出重定向一下
nohup和&一起用也是差不多的 今天一大早傻逼老板突然叫我明天做汇报,忙着做ppt没看s1,抱歉抱歉。
我的需求其实是下面这个脚本,主要代码就一行,需求也很简单,检测trayer程序有没有跑,有就关掉,没有跑就打开。
用了nohup &,htop tree还是显示trayer是脚本的子进程。可以注意到dwmblocks那里有一行echo $(sb-tray), 换言之脚本运行还是卡在那里了,我再点击状态栏脚本也不会运行。我明白这时候我kill掉这个脚本之后trayer也会接着跑(这也是我理解的nohup的运行方式),但是我想要trayer独立于脚本之外运行,这样才能实现我想要的 点击打开-再点击关闭 的功能。https://s3.bmp.ovh/imgs/2022/04/01/cdaa55f6b45d455c.jpg
https://imgtu.com/i/q5YEGj
yuandi42 发表于 2022-4-1 22:15
今天一大早傻逼老板突然叫我明天做汇报,忙着做ppt没看s1,抱歉抱歉。
我的需求其实是下面这个脚本,主要代 ...
Supervisor可以试试, bash居然可以写的这么复杂。。。
— from Google Pixel 6 Pro, Android 12 of S1 Next Goose v2.5.2-play 你可以让systemd来管理这个进程,然后脚本里就只是发指令给systemd 这tilling wm配置有点审美的,礼貌求抄dotfile
emanon42 发表于 2022-4-2 08:05
这tilling wm配置有点审美的,礼貌求抄dotfile
dotfiles
还有一部分配置在我自己的fork的dwm和dwmblocks里,现在还在折腾,不是完全体。 可能我之前表述不是很清楚,我再解释一下我的需求吧。我希望脚本A启动命令(或脚本)B的时候,B就不是A的子进程。A不会因为B在持续运行而卡在B这一步。
在我的理解里,nohup &并不能满足我的需求,因为nohup能做到只是当A关闭的时候,让B忽略SIGHUP信号仍旧能够执行而已。
有版友建议我用systemd之类的,但这种实现方式我想我还是等到shell builtin 命令确定不能满足我的需求再试一试吧。一方面我不想为了这么一件很简单的事动用systemd这种大家伙,另外我也希望我写的脚本的依赖尽可能少一点。
P.S. 楼上还有人提到fork exec的,那个不是c里的东西吗,,, yuandi42 发表于 2022-4-2 23:47
可能我之前表述不是很清楚,我再解释一下我的需求吧。我希望脚本A启动命令(或脚本)B的时候,B就不是A的子 ...
如果用A启动B,那B肯定是A的子进程。不然你觉得B的父进程应该是哪个?
shell我不太熟,不过我觉得 & 或者supervisor都能满足你的需求, &本身就是fork和exec
试了一下:
不如直接 python multiprocessing,我觉得用 && 和 | 都解决不了的问题就不该用 shell script 了,可读性太寄吧差
—— 来自 Xiaomi MI 8, Android 10上的 S1Next-鹅版 v2.5.1 maritimus 发表于 2022-4-3 00:39
如果用A启动B,那B肯定是A的子进程。不然你觉得B的父进程应该是哪个?
shell我不太熟,不过我觉得 & 或 ...
谢谢!我试着在terminal跑了一下nohup &, 似乎没有太大问题。那大概是dwmblocks的锅了,已经向上游提了个 issue. 如果shell script实现不了我就换成其他实现方式吧,,, 这种“如果一个进程还没启动过, 就启动, 否则就重启”的需求还是用专门的进程管理要简单些
你可能需要 systemd (user) unit
https://wiki.archlinux.org/title/Systemd/User
直接 `systemctl --user restart <service>` 就行了 估计是虚拟终端问题
setsid试试 想了下 应该是dwmblocks的退出代码里有主动结束子进程的行为
Linux实现方法是fork两次让孙进程挂到pid1上
最标准的做法还是让常驻进程让sysremd管理 第一反应fork
—— 来自 samsung SM-G9750, Android 12上的 S1Next-鹅版 v2.5.2-play
页:
[1]