3

考虑这样的 shell 脚本:

loop()
{
    while true; do
        sleep 10
        return 1
    done &

    return 0
}

loop
exit 0

while 子句在后台运行,但loop()返回函数并退出脚本。

return 1子句看起来像一个语法错误,但控制台实际上并没有输出任何错误消息。

return 1该条款将导致什么行为?

编辑:

脚本中的每个命令都在子进程中运行(大致),但我的问题是关注return 1子句。这个命令应该在函数上下文中运行,但是在它运行时,函数上下文被破坏了。所以这个return 1子句的行为是奇怪和不清楚的。任何想法?

4

2 回答 2

2

考虑以下

openvas:~$ vi test.sh
loop()
{
    while true; do
        sleep 10
        echo "1" 
        ps -fu openvas
        return 1
    done &

    echo "2"
    ps -fu openvas
    return 0
}

loop

echo "3"
ps -fu openvas
exit 0

结果

openvas:~$ sh test.sh 
2
UID        PID  PPID  C STIME TTY          TIME CMD
openvas     13653 13603  0 16:22 pts/2    00:00:00 sh test.sh
openvas     13654 13653  0 16:22 pts/2    00:00:00 sh test.sh
openvas     13655 13653  0 16:22 pts/2    00:00:00 ps -fu openvas
openvas     13656 13654  0 16:22 pts/2    00:00:00 sleep 10
3
UID        PID  PPID  C STIME TTY          TIME CMD
openvas     13653 13603  0 16:22 pts/2    00:00:00 sh test.sh
openvas     13654 13653  0 16:22 pts/2    00:00:00 sh test.sh
openvas     13656 13654  0 16:22 pts/2    00:00:00 sleep 10
openvas     13657 13653  0 16:22 pts/2    00:00:00 ps -fu openvas
1
UID        PID  PPID  C STIME TTY          TIME CMD
openvas     13654     1  0 16:22 pts/2    00:00:00 sh test.sh
openvas     13658 13654  0 16:23 pts/2    00:00:00 ps -fu openvas

在第一个 ps 输出(echo 2)中,很明显,当调用此脚本时,bash 分配了一个 PID 13653。这反过来又为 while 循环分配了 13654。然后从父 13654 使用 PID 13656 调用 sleep 命令。从原始脚本本身调用 ps 命令。

在第二个 ps 输出(echo 3)中,它遵循相同的模式。

在第三个 ps 输出(echo 1)中,您可以看到 PID 13654 有一个父进程 1 而不是 13653。This shows that init adopts this orphan. 由于父进程已经完成运行并在子进程检查父进程的 PID 时退出。这导致子进程在进程 ID 为 1 的 init 下重新成为父级。

在您的情况下,一旦脚本以 return 0 退出,循环就不会被破坏(PID 13654),它会继续运行,直到遇到 return 1 会破坏它。

于 2013-11-05T15:35:08.180 回答
0

while 循环在一个孤立的子进程中执行一次,然后子进程结束。由于父进程提前 10 秒退出,因此 init “采用”该进程并获取它。从某种意义上说,你正在制造僵尸。

看看你能从中得到什么

loop()
{
    while true; do
        sleep 10
        return 1
    done &

    return 0
}

loop
ps
exit 0

注意运行 sleep 命令的进程 - 来自子进程。

于 2013-11-05T12:25:43.103 回答