Shell脚本(.sh文件)如何执行完毕之后不自动关闭?

Shell脚本异常傲娇,出错后、执行完根本不给你机会让你查看报错信息、输出信息,直接闪退。

废话不多说,调教方法如下,直接在Shell脚本末尾加上如下代码

1、实现方式一

1.1 使用read命令达到类似bat中的pause命令效果

直接在原来的脚本末尾,加上下面一段代码,实现类似bat中的pause命令效果

#  使用read命令达到类似bat中的pause命令效果
echo 按任意键继续
read -n 1
echo 继续运行

例:

某.sh文件内容如下图,执行完或出错后直接闪退。

末尾加上代码:

1.2 运行效果

运行完毕,弹出提示 按任意键继续

这样,运行出错后、执行完,可以有足够的时间来查看报错信息、输出信息。按任意键关闭窗口或者点击关闭窗口。

2、实现方式二

2.1 增加一个sleep 10000来防止窗口自动关闭

然后 我在这个文件的结尾,增加一个sleep 10000,如下所示

2.2 运行效果

这样运行该publish.sh的时候,就不会主动关闭窗口了。

3、实现方式三

3.1 使用tail -f /dev/null命令:

#!/bin/bash
# 你的脚本命令
 
# 在脚本的最后添加这行
tail -f /dev/null

4、实现方式四

4.1 使用read -n 1命令:

#!/bin/bash
# 你的脚本命令
 
# 在脚本的最后添加这行
echo "Press any key to continue..."
read -n 1
<think>好的,我现在需要处理用户关于Linux脚本中父进程退出但子进程退出的问题。首先,用户可能是在编写脚本时遇到了子进程在父进程结束后仍然运行的情况,或者他们想了解如何实现这样的行为。我需要确保回答准确,并且覆盖关键点。 首先,我得回顾一下Linux中进程的关系。当父进程退出时,子进程通常会变成孤儿进程,被init进程(systemd或其他)接管。所以,默认情况下,子进程会因为父进程退出而终止。但是用户提到的是“父进程退出子进程退出”,这可能涉及到如何让子进程在后台运行,或者处理信号等问题。 可能的情况是用户在脚本中直接启动了后台进程,但父进程退出后,子进程仍然运行。例如,在脚本中使用&符号让命令在后台执行,这时候即使脚本结束,子进程可能还在运行。需要解释这种情况。 另外,用户可能想知道如何正确地在父进程退出后让子进程继续运行,而会意外终止。可能需要提到nohup、disown、或者setsid等命令,以及信号处理,比如忽略SIGHUP。 我需要分步骤解释: 1. 默认情况下,父进程退出,子进程成为孤儿进程,继续运行。 2. 如果父进程在退出前没有正确管理子进程,比如没有处理信号,可能导致子进程终止,例如当shell脚本退出时,发送SIGHUP给子进程。这时候需要用nohup或者disown来防止这种情况。 3. 演示几个例子,比如使用&在后台运行,结合nohup,或者使用子shell和disown命令。 4. 可能还需要提到守护进程的创建方法,比如fork两次,或者使用daemon工具。 要确保例子正确,比如一个脚本中启动后台进程,然后退出,查看子进程是否存活。例如: #!/bin/bash sleep 100 & 当这个脚本运行时,sleep进程会被启动,脚本结束后,sleep进程是否还在?这取决于shell是否发送SIGHUP。如果用户直接在终端运行脚本,终端关闭可能会发送SIGHUP,导致子进程终止。但如果使用nohup或者脚本内部处理了信号,子进程可以继续。 因此,需要解释同的场景,比如在交互式shell中运行脚本与使用nohup运行脚本的区别。 另外,需要提到disown命令,它可以从shell的作业表中移除任务,避免shell发送SIGHUP。例如: #!/bin/bash sleep 100 & disown 这样脚本退出后,sleep进程会被终止。 还要注意,如果父进程在子进程之前终止,子进程会被init接管,但如果有终端关联,可能需要处理终端的信号。例如,当使用SSH运行脚本,如果SSH断开,默认会发送SIGHUP,导致子进程终止,除非使用了nohup或类似的机制。 总结回答结构: 1. 解释孤儿进程的概念。 2. 默认情况下子进程是否会退出。 3. 影响子进程退出的因素(如SIGHUP信号)。 4. 保持子进程运行的方法(nohup、disown、setsid、双fork等)。 5. 示例代码和用法。 6. 注意事项或常见问题。 需要验证每个方法的正确性,比如使用nohup的正确方式,disown的使用时机等。例如,在脚本中使用nohup: nohup sleep 100 & 或者,在子shell中启动进程: (sleep 100 &) 过,这样可能还够,可能需要结合disown。 另外,setsid可以创建一个新的会话,使进程脱离终端: setsid sleep 100 & 这些方法各有优缺点,需要简要说明。 最后,确保回答符合用户的要求,结构清晰,步骤明确,帮助用户解决问题。可能需要指出同的使用场景,比如在脚本中如何选择适当的方法,或者在交互式shell中的处理方式。</think>在 Linux 中,父进程退出时子进程是否跟随退出取决于 **进程关系** 和 **信号处理**。以下是逐步说明: --- ### 一、默认行为:子进程成为孤儿进程 1. **父进程退出时** - 子进程会变成 **孤儿进程**(Orphan Process),由 `init/systemd`(PID=1)接管。 - **子进程自动退出**,除非显式收到终止信号(如 `SIGTERM` 或 `SIGHUP`)。 2. **验证示例** ```bash # 父进程脚本 parent.sh #!/bin/bash sleep 100 & # 启动一个后台子进程 echo "父进程 PID=$$ 退出" ``` 运行后,即使父进程退出,`sleep 100` 仍会继续运行。 --- ### 二、子进程退出的常见原因 如果子进程随父进程退出,通常是因为: 1. **终端关闭时发送 `SIGHUP`** - 若父进程是终端启动的脚本,终端关闭会向所有关联进程发送 `SIGHUP`,导致子进程退出。 2. **父进程显式终止子进程** - 例如父进程调用 `kill` 或未处理 `SIGTERM`。 --- ### 三、保持子进程运行的解决方案 #### 方法 1:使用 `nohup` 忽略 `SIGHUP` ```bash nohup your_command & ``` - 作用:忽略 `SIGHUP` 信号,输出重定向到 `nohup.out`。 - 示例: ```bash #!/bin/bash nohup sleep 1000 & ``` #### 方法 2:使用 `disown` 移除作业关联 ```bash your_command & disown ``` - 作用:将子进程从 Shell 作业表中移除,避免收到 `SIGHUP`。 - 示例: ```bash #!/bin/bash sleep 1000 & disown ``` #### 方法 3:使用 `setsid` 创建新会话 ```bash setsid your_command ``` - 作用:让子进程脱离当前终端会话,独立运行。 - 示例: ```bash #!/bin/bash setsid sleep 1000 ``` #### 方法 4:双 `fork` 脱离父进程(守护进程) 在代码中调用 `fork` 两次(常见于 C 语言),或通过脚本模拟: ```bash # 在脚本中启动子进程 (your_command &) ``` --- ### 四、验证子进程状态 1. **查找子进程** ```bash ps aux | grep "sleep 1000" ``` 2. **查看父进程 PID** ```bash ps -o ppid= -p <child_pid> # 应显示 1(被 init/systemd 接管) ``` --- ### 五、注意事项 1. **输出重定向** 若子进程需要保留输出,需显式重定向: ```bash nohup your_command > output.log 2>&1 & ``` 2. **终端环境差异** 在 SSH 会话中运行脚本时,建议直接使用 `nohup` 或 `setsid` 防止断开导致进程终止。 --- ### 总结 Linux 中子进程默认会随父进程退出而终止。若需确保子进程持久运行,可通过 `nohup`、`disown` 或 `setsid` 解除与终端的关联。核心原理是 **避免接收 `SIGHUP` 信号** 并让进程由 `init/systemd` 托管。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻将上头了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值