我有一个可以在 Linux 和 Mac OS X 中运行的 bash 脚本。该脚本的某一行在 Linux 中可以正常工作,但在 OS X 中则不行。
nohup <utility> <arg> > output.txt 2> error.txt </dev/null &
当 bash 脚本在 Linux 中运行时,它就像一个魅力。但是,在 OS X 中运行 bash 脚本时,出现错误
nohup: can't detach from console: Inappropriate ioctl for device
我已经进行了大量搜索,但没有找到合适的答案来解释为什么会出现这种情况。
执行脚本早在
<utility>
之前退出,这就是为什么(据我所知)我需要使用 nohup
。但是,我已经做了一些测试,并且从 bash 脚本中的行中删除 nohup
似乎可以解决问题,因为两个系统上的实用程序都会启动,并且即使在脚本退出后也会继续运行。
试试这个:
nohup <utility> <arg> > output.txt 2> error.txt >/dev/null &
你可以试试这个
nohup <utility> <arg> > output.txt 2> error.txt >/dev/null & disown
你根本不需要
nohup
。
nohup
仅具有以下功能:
HUP
信号转发给其子级(您也可以在 bash 中使用 disown -h
执行此操作)。/dev/null
重定向标准输入 如果它之前指向终端(这不是因为你正在运行 </dev/null
)。nohup.out
如果它之前指向终端(这不是因为你正在运行 >output.txt
)。nohup.out
如果它之前指向终端(这不是因为你正在运行 2>error.txt
)。就是这样。这就是它的全部作用。除非您处于交互式 shell 中,否则您不需要需要会拒绝转发 HUP 信号的东西(因为具有默认设置的非交互式 shell 首先根本不会转发 HUP 信号)。
当您尝试使用
nohup
将进程置于后台并且 <utility>
正在尝试访问与终端相关的功能时,通常会在 macOS 上出现错误消息“nohup:无法与控制台分离:设备的 ioctl 不适当”。在 macOS 上不存在或表现不同。
要解决此问题,您可以尝试以下方法:
使用
disown
:
您可以在后台运行命令,然后使用 nohup
内置 shell 命令,而不是使用 disown
。这种方法应该适用于 Linux 和 macOS:
<utility> <arg> > output.txt 2> error.txt </dev/null &
disown
这样,您就可以完全避免使用
nohup
。
使用
setsid
:
在 macOS 上,您可以使用 setsid
命令为后台进程创建新会话:
setsid <utility> <arg> > output.txt 2> error.txt </dev/null &
这也应该适用于 Linux。
使用
stdbuf
:
如果问题与缓冲有关,您可以使用 stdbuf
命令来调整实用程序的缓冲行为。例如:
stdbuf -oL -eL <utility> <arg> > output.txt 2> error.txt </dev/null &
这有助于确保输出和错误流不受缓冲。
尝试每种方法,看看哪一种最适合您在 Linux 和 macOS 上的特定用例。
disown
方法通常是在 shell 脚本中运行后台进程的最简单且最具跨平台的解决方案。