函数返回时会产生什么行为,但函数中的命令是否在后台运行?

时间:2013-11-05 11:46:15

标签: linux bash shell

考虑这样的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子句的行为很奇怪而且不清楚。有什么想法吗?

2 个答案:

答案 0 :(得分: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.而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时退出。这导致子进程在init下重新成为父级,进程ID为1。

在你的情况下,一旦脚本退出并返回0,循环就不会被销毁(PID 13654),并且它会一直持续到它遇到返回1而导致它被破坏。

答案 1 :(得分:0)

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

看看你从这里得到了什么

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

    return 0
}

loop
ps
exit 0

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