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