我使用startx来启动X,这将计算我的.xinitrc。在我的.xinitrc中,我使用/usr/bin/mywm.启动我的窗口管理器现在,如果我杀死我的WM(为了f.e.测试其他一些WM), X也将终止,因为.xinitrc脚本到达了EOF。 所以我在.xinitrc的末尾添加了这个:
while true; do sleep 10000; done
这样,如果我终止WM, X就不会终止。现在我的问题是:我如何做一个无限睡眠而不是循环睡眠?是否有类似于冻结脚本的命令?
我使用startx来启动X,这将计算我的.xinitrc。在我的.xinitrc中,我使用/usr/bin/mywm.启动我的窗口管理器现在,如果我杀死我的WM(为了f.e.测试其他一些WM), X也将终止,因为.xinitrc脚本到达了EOF。 所以我在.xinitrc的末尾添加了这个:
while true; do sleep 10000; done
这样,如果我终止WM, X就不会终止。现在我的问题是:我如何做一个无限睡眠而不是循环睡眠?是否有类似于冻结脚本的命令?
当前回答
这种方法不会消耗任何资源来保持进程的活动。
while :; do :; done & kill -STOP $! && wait
分解
而:;做的事:;done &在后台创建一个虚拟进程 杀-停止$!停止后台进程 等待后台进程,这将永远阻塞,因为后台进程之前已经停止
笔记
只能从脚本文件中工作。
其他回答
与其杀死窗口管理器,不如尝试使用——replace或-replace(如果可用的话)运行新的窗口管理器。
尾部不堵塞
一如既往:任何事情都有一个简短、容易理解、容易理解但完全错误的答案。这里tail -f /dev/null属于这一类;)
如果你用strace tail -f /dev/null来观察它,你会发现这个解决方案远远没有阻塞!它可能比问题中的睡眠解决方案更糟糕,因为它使用(在Linux下)像inotify系统这样的宝贵资源。其他写入/dev/null的进程也会形成尾循环。(在我的Ubuntu64 16.10上,这在一个已经很忙的系统上增加了每秒10个系统调用。)
这个问题是关于阻塞命令的
不幸的是,没有这样的事情。
阅读:我不知道任何方法来归档这与壳直接。
一切(甚至无限睡眠)都可能被某种信号打断。所以如果你真的想确保它不会异常返回,它必须在循环中运行,就像你睡觉时做的那样。请注意,(在Linux上)/bin/sleep显然被限制在24天(看看strace sleep infinity),因此你能做的最好的可能是:
while :; do sleep 2073600; done
(注意,我认为睡眠循环的内在值高于24天,但这意味着:它不是阻塞,它是非常缓慢的循环。那么为什么不把这个循环移到外面呢?)
. .但是你可以用一个未命名的fifo来接近它
你可以创建一些真正阻塞的东西,只要没有信号发送到进程。下面使用bash 4,2 pid和1 fifo:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
如果你喜欢,你可以用strace检查它是否真的阻塞:
strace -ff bash -c '..see above..'
这是怎么建造的
如果没有输入数据,则读取块(参见其他答案)。然而,tty (aka。Stdin)通常不是一个好的源,因为当用户注销时它就关闭了。它还可能从tty中窃取一些输入。不好。
为了创建read块,我们需要等待像fifo这样永远不会返回任何东西的东西。在bash 4中,有一个命令可以为我们提供这样的fifo: coproc。如果我们还等待阻塞读取(这是我们的coproc),我们就完成了。可悲的是,这需要保持开放的两个pid和一个先进先出。
具有命名fifo的变体
如果你不想使用命名fifo,你可以这样做:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
在读取时不使用循环有点草率,但你可以经常重用这个fifo,并使用touch "$HOME/.pause "使读取终止。Fifo”(如果有多个读等待,所有的都被立即终止)。
或者使用Linux pause()系统调用
对于无限阻塞,有一个名为pause()的Linux内核调用,它做我们想要的事情:永远等待(直到信号到达)。然而,目前还没有用户空间程序。
C
创建这样一个程序很容易。下面是创建一个名为pause的非常小的Linux程序的代码片段,它可以无限期地暂停(需要diet, gcc等):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
如果你不想自己编译,但你已经安装了python,你可以在Linux下使用:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(注意:使用exec python -c…替换当前的外壳,这释放了一个PID。该解决方案还可以通过一些IO重定向进行改进,释放未使用的fd。这取决于你。)
这是如何工作的(我认为):ctypes.CDLL(None)加载标准C库,并在一些额外的循环中运行pause()函数。效率比C版本低,但可以工作。
我给你的建议是:
停留在循环睡眠。它很容易理解,非常便携,而且大多数时候都是阻塞的。
这种方法不会消耗任何资源来保持进程的活动。
while :; do :; done & kill -STOP $! && wait
分解
而:;做的事:;done &在后台创建一个虚拟进程 杀-停止$!停止后台进程 等待后台进程,这将永远阻塞,因为后台进程之前已经停止
笔记
只能从脚本文件中工作。
while :; do read; done
没有等待孩子睡觉的过程。
也许这看起来很丑,但为什么不直接运行cat,让它永远等待输入呢?