shell 通过新终端启动独立进程

cvxl0en2  于 2023-10-23  发布在  Shell
关注(0)|答案(1)|浏览(237)

我一直在尝试创建一个新的键盘快捷键,应该做一些事情,然后打开黑曜石。
我目前使用Alacritty作为我的默认终端模拟器,这是我在上面运行的脚本:

#! /bin/bash

echo Doing some heavy stuff
sleep 5

echo Doing some other heavy stuff
sleep 3

echo Opening Obsidian
/home/enzo/tools/obsidian &

当我直接在终端中执行它时,它工作得很好:它打印应该打印的东西,然后打开一个独立的Obsidian示例,这个示例在终端关闭时不会关闭。
问题是,我想使用键盘快捷键执行这些任务,我真的需要知道在脚本执行过程中发生了什么,这就是为什么我在其中放置了一些echo语句。
因此,我定义了一个运行alacritty -e my_script.sh的快捷方式,它打开一个新的Alacritty示例并正确执行我的脚本,但随后关闭Obsidian。我希望新的终端示例在关闭后不关闭Obsidian。
我还尝试了nohup&disown的许多组合。他们似乎都没有工作。
shopt(shell选项)显示huponexit被设置为off,这意味着SIGHUP不应该被发送给子进程(至少,据我所知),我甚至不应该尝试nohup。实际上,huponexit被设置是使我的脚本在终端中直接执行时按预期执行的原因。

**编辑:**为了让事情更清楚一点,我做了这个例子来演示我认为是成功的情况:

1.按一些快捷键,如CMD + N;
1.看到一个新的终端即时打开和打印一些重要的东西;
1.看到黑曜石正在发射和工作;
1.看到终端被关闭而不影响黑曜石。
这是怎么回事?我错过了什么吗?

2mbi3lxu

2mbi3lxu1#

显而易见的解决方案应该是:

#!/bin/bash
echo ...
sleep 5

echo Opening Obsidian
nohup /home/enzo/tools/obsidian &

唉,这行不通。我认为问题在于,由于&的工作方式,这里有一个raze。
命令末尾的&实际上将整行代码转换为子shell,因此shell首先执行fork(),然后在新进程中执行该命令,而旧进程继续运行。
但是使用上面的脚本,在nohup程序有机会开始运行并设置正确的信号掩码之前,主shell进程立即完成并在整个进程组中导致SIGHUP。因此,新进程被中止,什么也不做。
解决方案取决于你想去多花哨。

21040;#1,不好的。

只是在结尾处添加一个暂停,以便给予nohup一个运行的机会:

#!/bin/bash
echo ...
sleep 5

echo Opening Obsidian
nohup /home/enzo/tools/obsidian &
sleep 1

你自然听说过使用延迟同步并行任务是不好的,(多少延迟?)你确定nohup不会超过1秒运行?)所以你可能想做得更好...

20002;的“丑”。

等待正确的进程出现。有很多种方法可以做到这一点。类似这样的东西应该可以工作,这取决于obsidian如何识别自己,我不知道:

#!/bin/bash
echo ...
sleep 5

echo Opening Obsidian
nohup /home/enzo/tools/obsidian &
PID=$!
while [ -d "/proc/$PID" -a "$(< /proc/$PID/cmdline)" != "/home/enzo/tools/obsidian" ]
do
    :
done

请注意,您的obsidian命令可能无法正常运行,因此您必须检查PID目录是否存在。

36825;#36825;#36826;#36825;#36826;#36826;#36827;#36827。

我不知道bash是否有任何合适的同步原语,但一个普通的临时文件就可以了:

#!/bin/bash
echo ...
sleep 5

echo Opening Obsidian
T=$(mktemp)
nohup bash -c "rm \"$T\" ; exec /home/enzo/tools/obsidian" &

while [ -f "$T" ]
do
    :
done

请记住,mktemp创建一个具有随机名称的空临时文件并返回其名称。rmobsidian之间的顺序并不重要,因为当其中任何一个运行时,nohup已经完成了它的魔力。exec的存在只是为了避免子subshell无所事事地等待obsidian完成。

21440;的解决方案#4,?

当我在写前一个的时候,我突然想到,如果你愿意做sub-subshell并写nohup bash -c...,有一个非常明显的解决方案:

#!/bin/bash
echo ...
sleep 5

echo Opening Obsidian
nohup bash -c "/home/enzo/tools/obsidian &"

请注意,&位于引号内,因此主shell将等待nohup完成。使命完成!

相关问题