- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Learning Bash Book 提到子 shell 将仅继承环境变量和文件描述符等,并且它不会继承未导出的变量
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
据我所知,shell 将为 () case 和 ./file 创建两个子 shell,但为什么在 () case 中子 shell 识别了 var 变量,尽管它没有导出,而在 ./file case 中它没有识别是吗?
# Strace for ()
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631
我尝试使用 strace 来弄清楚这是如何发生的,令人惊讶的是我发现 bash 将对克隆系统调用使用相同的参数,因此这意味着 () 和 ./file 中的两个 fork 进程应该具有相同的进程父级的地址空间,那么为什么在 () 情况下变量对子 shell 可见,而对于 ./file 情况不会发生同样的情况,尽管相同的参数基于克隆系统调用?
最佳答案
使用括号创建的子 shell 不对新进程使用 execve()
调用,脚本调用会。此时,来自父 shell 的变量的处理方式有所不同:execve()
传递一组经过深思熟虑的变量(脚本调用情况),而不调用 execve()
(括号内的情况)保留完整的变量集。
您使用 strace
进行的探测应该准确地显示出这种差异;如果你没有看到它,我只能假设你犯了几个可能的错误之一。我将只删除我所做的以显示差异,然后您可以自己决定错误在哪里。
我创建了两条轨迹。第一个是使用
strace -f -o bash-mystery-1.strace bash -c 'v=15; (echo $v)'
第二个是用
strace -f -o bash-mystery-2.strace bash -c 'v=15; ./x.sh'
(x.sh
是一个可执行脚本。)
选项 -f
是跟踪父 shell 的子级(命令行中的 bash
)所必需的。
在均衡所有典型和频繁的差异(如地址和 PID)之后,我使用 diff -y -W 300
比较了这些轨迹:
q() {
sed -e 's/0x[0-9a-f]*/ADDR/g' \
-e 's/12923\|12927/PARENT/g' \
-e 's/12924\|12928/CHILD/g'
}
diff -y -W 300 <(q < bash-mystery-1.strace) <(q < bash-mystery-2.strace) | less -S
12923 和 12927 是我的父 PID,12924 和 12928 是我的子 PID(这是我通过扫描跟踪文件发现的)。你当然会有不同的数字,所以调整这些。您将需要一个非常宽的终端(超过 200 个字符)才能正确查看差异输出。所以让你的窗口变宽;-)
在第 140 行附近,我发现了一个 clone()
调用,它或多或少是一个 fork()
,因此它将当前进程一分为二。在那里,CHILD 开始做事,正如我们在跟踪的以下几行中看到的那样。在第 165 行左右,我看到了 execve()
的调用,但只是在调用脚本的情况下,所以 child 自愿放弃了很多环境,并故意设置了一个.括号中的情况不会改变它的环境(它不会调用 execve()
),所以子进程继续拥有完整的集合。
关于linux - Bash 子 shell 之谜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26079488/
我一直在使用高精度时间在控制台中记录我的程序事件。但很快我就注意到程序有时会显示四舍五入到毫秒的时间,有时则不会!它完全偶尔发生,它是相同的代码,未重新编译,未在运行之间编辑: using Syste
首先:该代码被认为是纯粹的乐趣,请在生产中不要做任何类似的事情。在任何环境下编译并执行这段代码后,对于您,您的公司或您的驯鹿造成的任何伤害,我们概不负责。以下代码不安全,不可移植,并且非常危险。被警告
我正在投影图像,然后检查它: 高度是20px。这是正确的。 然后我检查包含 img 的 data-radium 元素,令我惊讶的是: 尽管没有内容,该元素的高度“增长”了两个像素。此外,data-ra
我是一名优秀的程序员,十分优秀!