V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dcsuibian
V2EX  ›  Windows

Windows 下对应 nohup &的命令是什么?

  •  
  •   dcsuibian · 2022-04-12 13:37:42 +08:00 · 5438 次点击
    这是一个创建于 735 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在做的一个项目,Spring Boot 程序,基本上就是java -jar XXX.jar --spring.profiles.active=production ...这么运行。

    本地开发机是 mac ,安装了 pwsh 。

    程序部署在多台 windows ltsc 2018+虚机上。目前各种依赖环境已经装好,安装了 OpenSSH 并配置了免密登录。Windows Powershell 5 。

    之前部署到 Linux 上的时候基本就是把 jar 包 scp 上去,然后 ssh 上去用 nohup &运行,这样即使退出 session 程序也会继续运行。

    Windows 这边搜了好久,后台运行程序到可以,不过退出 session 后程序也就结束了,找过很多都没有成功的。想请教一下如何实现退出 ssh 会话后仍继续运行的功能?(目前知道 winsw 应该可以,想问问有没有什么更简单的方法)

    第 1 条附言  ·  2022-04-13 09:54:26 +08:00

    感谢各位,最近比较忙没及时回复。看了大家的回复,看来是偷不了这个懒了,准备包装成服务了。

    31 条回复    2022-04-15 10:51:42 +08:00
    daliu
        1
    daliu  
       2022-04-12 13:41:54 +08:00   ❤️ 2
    用 nssm 做成任务可能是最简单的办法了
    lovestudykid
        2
    lovestudykid  
       2022-04-12 14:11:47 +08:00
    用 vbs 可以实现
    kokutou
        3
    kokutou  
       2022-04-12 14:12:29 +08:00 via Android   ❤️ 1
    做成服务。。
    TimePPT
        4
    TimePPT  
       2022-04-12 14:25:01 +08:00
    @daliu nssm +1
    huang119412
        5
    huang119412  
       2022-04-12 14:25:05 +08:00   ❤️ 1
    javaw ,这个命令在 win 下应该可以
    Juszoe
        6
    Juszoe  
       2022-04-12 14:57:17 +08:00   ❤️ 2
    上面的是 windows 下比较常用的做法,如果你非要类似 nohup&这种操作,可以试试 Powershell 的 Start-Process 命令开启一个独立的进程
    Start-Process -WindowStyle Hidden
    ysc3839
        7
    ysc3839  
       2022-04-12 18:19:25 +08:00   ❤️ 1
    没有完全对应的操作。不过如果你想避免 SSH 断开后进程被结束的话,得看 SSH Server 是怎么实现的。
    Windows 下一般有两种方法实现结束所有子进程:
    一种是简单且通用的,直接遍历进程列表,列出子进程的树,再一一结束。这种情况只需要启动两次新进程,即可从树中脱离出去。
    另一种是把子进程加入 Job Object ,然后可以结束其中的所有进程。这种情况要看创建 Job Object 的时候是否允许脱离,允许的话在创建进程时加一个 flag 可以脱离。不允许的话理论上是没办法脱离,但实际可以利用 WMI 服务提供的启动新进程的功能来脱离,因为新进程是由 WMI 服务进行启动的,自然不受限制。
    Tumblr
        8
    Tumblr  
       2022-04-12 18:46:21 +08:00   ❤️ 2
    在 Windows 下,非登录用户可运行的方式有两种,一是用服务运行,二是计划任务。

    其实在 Windows 下的话,如果你只是 disconnect session ,还是可以正常运行的,只是在 log out 的时候你的进程才会关掉。但是很多公司会有策略,一个账号 idle 一段时间之后会强制 log out 。
    ikas
        9
    ikas  
       2022-04-12 19:28:30 +08:00   ❤️ 1
    最好的方式还是写成服务

    一般开源多用 apache commons-daemo,比如 tomcat,elasticsearch 等
    https://commons.apache.org/proper/commons-daemon/binaries.html
    复制他们的配置修改下就行了

    并且它还提供交互接口,管理 ui
    mxT52CRuqR6o5
        10
    mxT52CRuqR6o5  
       2022-04-12 19:40:52 +08:00 via Android
    start
    SenLief
        11
    SenLief  
       2022-04-12 19:43:18 +08:00
    nssm 可以做成一个服务
    oneisall8955
        12
    oneisall8955  
       2022-04-12 21:19:03 +08:00 via Android
    oneisall8955
        13
    oneisall8955  
       2022-04-12 21:20:00 +08:00 via Android   ❤️ 1
    @oneisall8955 不好意思没看完帖子,忽略~
    adoal
        14
    adoal  
       2022-04-12 21:34:48 +08:00   ❤️ 1
    其实你在 Linux 下的做法也不地道。Linux 下,在生产环境跑的守护进程,当代的主流做法是写一个 systemd unit 来做启动控制,而不是用交互登录的帐号手工启动。Windows 下也是同理,要做成服务。
    aisk
        15
    aisk  
       2022-04-12 21:50:22 +08:00
    你在 Linux 上的这个用法,就不担心进程因为 OOM 等其他原因挂了,没人自动帮你重启吗?
    UnknownR
        16
    UnknownR  
       2022-04-12 22:55:04 +08:00   ❤️ 3
    `nohup &` 是创建用户账号下的后台进程,在 windows 下的话可以通过 powershell 调用像 start-process 或者 c#的进程类来实现,实际是一样的。

    最佳的使用方式是像前几楼所说的,linux 下创建 systemd 的守护进程,以系统用户运行。windows 下可以是创建计划任务或者 service 以系统用户运行,比如自带的 sc /create 或者 nssm 这种第三方工具,也可以在 powershell 里用[System.Process.StartInfo]::new() 和 [System.Process]::Start(ProcessStartInfo) 来创建系统级进程。
    lolizeppelin
        17
    lolizeppelin  
       2022-04-12 23:17:45 +08:00   ❤️ 1
    fork 后的进程会继承父进程的信号处理
    shell 里启动的进程就继承了当前终端进程对应的信号处理,也就是 shell 接受到退出信号时,子进程也会按照父进程原有方式处理。

    nohup 实际的作用是,fork 后清空信号处理,避免子进程收到退出信号

    Linux 下标准做法是 fork 两次 setsid,重新注册自己的信号处理,
    nohup 就是在 shell 终端里实现 fork 一次,重设信号的流程而已

    附注:linux 的没有 nohup 函数. setsid 命令可以简单理解为调用 setsid 函数,有兴趣你可以看看 shell 命令里 setsid 与 nohup 的区别
    lolizeppelin
        18
    lolizeppelin  
       2022-04-12 23:21:56 +08:00
    windows 的机制比 linux 复杂,没有像 linux 这样 fork 后退出进程,子进程挂到 pid 1 下这种方便的常驻进程方式
    所有只能使用 windows 标准机制。
    Jiajin
        19
    Jiajin  
       2022-04-12 23:40:03 +08:00
    Start-Job ,但是你这个需求应该是 javaw
    ysc3839
        20
    ysc3839  
       2022-04-13 00:26:38 +08:00   ❤️ 1
    @lolizeppelin Windows 反而没有 Unix 那么复杂,本来子进程就不会受父进程影响的,父进程启动子进程后,只要父进程不主动进行一些操作,子进程是不会退出的。
    前面有人提到 logout session 会结束 session 中所有进程,这是一个特殊情况。如果进程是由 SSH 服务启动起来的,会随 SSH 服务在 session 0 ,这个 session 是一直存在的。
    所以只要 SSH 服务不主动进行一些动作,子进程是能一直存在的。因此我说得看 SSH 服务具体用了什么方法来结束子进程,选择合适的方法“绕过”即可。
    msg7086
        21
    msg7086  
       2022-04-13 06:18:53 +08:00
    nohup 跑项目的建议招一个兼职的运维。
    liaohongxing
        22
    liaohongxing  
       2022-04-13 13:55:32 +08:00
    java 项目也是 6 ,敢用 nohup 这种不带进程监控的直接运行 。半夜服务挂了,还得电话起来 起进程
    julyclyde
        23
    julyclyde  
       2022-04-13 14:22:25 +08:00
    nohup 和&其实是两件事
    你都没发现它是两件事,提问的时候你知道自己想要的是什么吗?
    julyclyde
        24
    julyclyde  
       2022-04-13 14:22:38 +08:00
    @liaohongxing 政企类项目大都这样的
    Bingchunmoli
        25
    Bingchunmoli  
       2022-04-13 16:34:41 +08:00 via Android
    @liaohongxing 日常了百度出来就是这个,不过 java 稳定性还好
    Bingchunmoli
        26
    Bingchunmoli  
       2022-04-13 16:36:14 +08:00 via Android
    Windows 双击启动就不管,狗头
    anyele
        27
    anyele  
       2022-04-14 11:35:43 +08:00
    做过 windows 应用的路过, 吃过做成服务的亏, 强烈建议不要做成服务, 原因是你后面更新的时候会很麻烦, 停止服务->更新文件->启动服务的过程中, 可能会遇到服务停止不成功, 或者服务启动不成功, 没必要给自己增加工作量

    上面说既然有 powershell, 那就独立起一个进程就行了, 要是有界面就隐藏掉
    anyele
        28
    anyele  
       2022-04-14 11:40:37 +08:00
    上面说做成服务的可能都没在实际项目中操作过, 除非你这个项目启动了就不更新了, 一旦涉及到更新, 你会花很多代码去检测服务的各种状态, 不然没办法更新文件, 完全得不偿失, 还可能你执行了停止服务的命令, 但服务并不是秒停, 要等一会, 甚至还停止不成功的蛋疼情况
    dcsuibian
        29
    dcsuibian  
    OP
       2022-04-15 00:29:26 +08:00
    @msg7086
    @liaohongxing
    @julyclyde
    如果不是生活所迫,谁愿意全干呢。
    之前在自己的 ubuntu 上运行过一段时间,还是挺稳定的。
    用 WinSW 做过服务,但一直不确定是不是一种好方案。甲方催得急,也不是那种正式使用的状态,就是单纯要求要“有”,所以寻思着先偷个懒。一方面是没有试错的时间,另一方面确实也想了解下 Windows 下对应的方式。
    dcsuibian
        30
    dcsuibian  
    OP
       2022-04-15 00:33:03 +08:00
    @anyele 最终还是做成服务了,幸好我的是小型单体应用。写了个脚本,Stop-Service 后 scp jar 包上去再 Start-Service ,勉强想办法完成了批量更新操作。
    julyclyde
        31
    julyclyde  
       2022-04-15 10:51:42 +08:00
    @dcsuibian 按说这些通用的知识应该早已积累下来了呀
    难道这是第一个项目?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3278 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 14:15 · PVG 22:15 · LAX 07:15 · JFK 10:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.