具体来说,如果使用 & 调用,bash 脚本中的函数调用是否会在后台运行?
我试图想出一个解决方案更改文件的一堆所有者并认为像下面这样的东西可能会起作用。但是 user_searcher() 函数调用实际上会在后台运行吗?
1 #!/bin/bash
2
3 User1=1000
4 User2=1001
5 User3=1002
6
7 user_searcher()
8 {
9 for fil in `find $HOME -uid $ooser -type f`
10 do
11 chown "NEWUSER$1" $fil
12 done
13 }
14
15 PIDARRAY=()
16 let i=1
17 for ooser in $User1 $User2 $User3 ;
18 do
19 let i++
20 user_searcher ooser i &
21 PIDARRAY+=("$!")
22 done
23
24 wait ${PIDARRAY[@]}
答案1
man bash(参见作业控制)
& 是控制运算符,意味着它执行控制功能。
如果命令由控制运算符 & 终止,则 shell 会在子 shell 的后台执行该命令。
(子 shell 被分配一个 PID 进程 ID 号)
简而言之,任何命令都可以通过用 & 终止命令来告诉在后台运行,这会生成一个子 shell 进程来运行该命令。
宽松地说,如果它可以在 shell 中独立运行,那么它就可以在子 shell 中在后台运行(&
做什么)。如果它是一个完全的它运行的子 shell 的指令或完整指令(函数)的序列,那么它可以在后台运行...也许我会在这里得到纠正,但很容易说如果它可以在前台运行shell 那么它可以在子 shell 的后台运行,其变量具有不同的和可定制的范围(对比coproc
vs &
,并参见lastpipe
,但变量的范围是在子 shell 中运行的命令的结果,而不是因为命令在后台运行)。
什么是命令?
从伍利奇狂欢指南:
BASH 从其输入(通常是终端或文件)读取命令。它读取的每一行输入都被视为一条命令——一条要执行的指令。 (有一些高级情况,例如跨多行的命令,稍后会介绍。)Bash 将每行划分为由空白字符(空格和制表符)分隔的单词。该行的第一个字是要执行的命令的名称。所有剩余的单词都成为该命令的参数(选项、文件名等)。
来自 bash-doc-3.2 中的 aosa-bash-full.pdfbash 源代码:
一个“简单”的 shell 命令...由命令名称(例如 echo 或 cd)以及零个或多个参数和重定向的列表组成。 (第 47 页)
Shell 函数和 shell 脚本都是命名一组命令并执行该组命令的方法,就像执行任何其他命令一样。 Shell 函数使用特殊语法声明,并在同一 shell 上下文中存储和执行; shell 脚本是通过将命令放入文件并执行 shell 的新实例来解释它们来创建的。 Shell 函数与调用它们的 shell 共享大部分执行上下文,但 shell 脚本由于由新的 shell 调用解释,因此仅共享环境中进程之间传递的内容。 (第 48 页)
………………
Bash 引入了作业的概念,作业本质上是由一个或多个进程执行的命令。例如,管道对管道的每个元素使用一个进程。进程组是一种将单独的进程连接到单个作业中的方法。终端有一个与其关联的进程组ID,因此前台进程组是与终端进程组ID相同的进程组。 (第 69 页)
- 任何进程都可以在后台运行
- shell本身就是一个进程
- shell 中的任何指令/命令(仍然松散定义)都可以通过在 & 生成的子 shell 中运行来在后台运行。
最大的考虑因素是后台子shell进程如何与其父进程交互,再次参见 man bash 中的作业控制