linux – bash中的奇怪行为(可能还有其他shell?)
发布时间:2020-12-14 01:57:50 所属栏目:Linux 来源:网络整理
导读:当我做: /bin/bash -c 'cat /proc/$$/cmdline' 我得到的输出是: cat/proc/25050/cmdline 而我预期的输出是: /bin/bash -c 'cat /proc/$$/cmdline' 另一方面,当我这样做时: /bin/bash -c 'echo $$; cat /proc/$$/cmdline' 我得到了预期的输出,即: 28259/
当我做:
/bin/bash -c 'cat /proc/$$/cmdline' 我得到的输出是: cat/proc/25050/cmdline 而我预期的输出是: /bin/bash -c 'cat /proc/$$/cmdline' 另一方面,当我这样做时: /bin/bash -c 'echo $$; cat /proc/$$/cmdline' 我得到了预期的输出,即: 28259 /bin/bash-cecho $$; cat /proc/$$/cmdline 似乎$$是猫的pid而不是bash / sh的pid. 解决方法
为了理解这种行为,我们必须弄清楚bash如何在命令行上执行传递给它的命令.关键是如果命令足够简单,就没有fork(或克隆或类似的东西).
$strace -f -e clone,execve /bin/bash -c 'cat /proc/$$/cmdline' execve("/bin/bash",["/bin/bash","-c","cat /proc/$$/cmdline"],[/* 80 vars */]) = 0 execve("/bin/cat",["cat","/proc/2942/cmdline"],[/* 80 vars */]) = 0 cat/proc/2942/cmdline+++ exited with 0 +++ $ OTOH如果命令更复杂,bash forks: $strace -f -e clone,execve /bin/bash -c 'echo $$; cat /proc/$$/cmdline' execve("/bin/bash","echo $$; cat /proc/$$/cmdline"],[/* 80 vars */]) = 0 2933 clone(child_stack=0,flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,child_tidptr=0x7ff64e6779d0) = 2934 Process 2934 attached [pid 2934] execve("/bin/cat","/proc/2933/cmdline"],[/* 80 vars */]) = 0 /bin/bash-cecho $$; cat /proc/$$/cmdline[pid 2934] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD,si_code=CLD_EXITED,si_pid=2934,si_uid=1000,si_status=0,si_utime=0,si_stime=0} --- +++ exited with 0 +++ $
实际上两者都是. bash直接驱逐cat,所以一个成为另一个. 要了解no-fork行为究竟需要什么,我们需要查看源代码.这是评论: /* * IF * we were invoked as `bash -c' (startup_state == 2) AND * parse_and_execute has not been called recursively AND * we're not running a trap AND * we have parsed the full command (string == ' ') AND * we're not going to run the exit trap AND * we have a simple command without redirections AND * the command is not being timed AND * the command's return status is not being inverted * THEN * tell the execution code that we don't need to fork */ Source (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |