我的bash中正在运行什么? (2014年)

2021-01-29 02:25:30

对于TL; DR人群:我非常需要提取我六个月前在bash shell中编写的完整(且非常冗长)的命令行-该命令行仍在屏幕下运行。继续阅读以了解我最终是如何做到的...

假设您使用bash作为日常外壳。您最近听说过很多有关它的安全性的令人担忧的事情。但这不是困扰您的原因。

困扰您的是,几个月前,您滥用了神圣的UNIX原理。这无济于事。您被要求实现一个守护进程,该守护进程监视文件夹中是否有传入的" stuff"。客户端将文件上传到那里,您应该对它们执行各种操作。

因此,您以疯狂的速度进行了黑客攻击,并制作了冗长的bash管道来完成所有操作。循环输入文件,管道,重定向-命名。而且您没有时间闲逛主管,您粘贴了" The Magic CmdLine(TM)"在屏幕上,您的bash耐心地开始颤抖着……然后您移至列表中的下一个紧急事件-自然,该紧急事件也定于昨天进行...

Magic CmdLine(TM)顺服地工作了。您在头几周内检查了它的行为-就像预期的那样,客户端发送的传入文件上的任何错误都报告在其stderr上,您的调用可方便地将其重定向到某个错误日志文件。一切都好。

突然间,你想起了。直到现在(您这个笨蛋!),您才意识到-恐怖的恐怖-您已完全忘记了Magic CmdLine(TM)。争论,重新定向,一切都花在了精神上。喝了

您只需重新启动一次,即可摆脱老板的应有之f(错误:屏幕显示或不显示屏幕,六个月前您认真研究过的Magic CmdLine(TM)),它将永远丢失……下一次重新启动发生)。

您重新回到魔术屏幕,手指交叉。您按下ESC并向上滚动,希望看到魔术线的调用...但无济于事。它生成的错误报告被写在整个屏幕的回滚缓冲区中-您无法一直滚动到调用行。

哎呀,必须有一条通往那条线的方法。 ps aux | grep ...没有帮助-它显示了您编写的命令当前正在运行的部分。你想要整个shebang。

我有一个运行时间很长的bash实例(在屏幕会话中),它在一个循环内执行一组复杂的命令(每个循环执行管道,重定向等)。长长的命令行写在终端内部-不在任何脚本内。现在,我知道了bash的进程ID,并且我具有root访问权限-如何查看在该bash中执行的确切命令行?

#在外壳A中,此命令序列在屏幕下运行:$ echo $$ 8909 $ while true;做回声1;回声2 / dev / null;睡30;在外壳B中,我想基于8909 PID做一些魔术,并获得#字符串..." while true;做回声1;回声2> / dev / null;睡30;完成"

一个告诉您搜索进程列表-在此示例中,该列表只会使您进入睡眠状态(在您的实际情况下,这是复杂的Magic CmdLine(TM)当前正在运行的部分)。

您下载了bash源代码,untar,并希望可以某种方式恢复保存在bash运行实例中的历史信息,您可以使用grep延长生命:

嗯... histfile.c-我们亲爱的bash将历史记录保存到文件中不是吗?在VIM内部打开,搜索...

生成GDB-并激活上帝模式!也就是说,附加到正在运行的bash上,并自行调用write_history-它方便地将文件名保存为参数!

$ gdb --pid 8909 ...为/ lib / i 386 -linux-gnu / i 686 / cmov / libnss_files加载的符号。这样。 2 __kernel_vsyscall()(gdb)中的0xb76e7424调用write_history(" / tmp / foo")$ 1 = 0(gdb)detach(gdb)q $ tail-1 / tmp / foo为true;做回声1;回声2 / dev / null;睡30;完成

您在StackOverflow中回答自己的问题。其他答案以某种方式被删除,显然为您的厄运感到羞耻。

您通过SSH进入运行Thing的远程计算机。运行Thing的bash进程具有PID 53165。

$ ssh IamInHell [ttsiod @ IamInHell] su-.... [root @ IAmInHell〜] gdb --pid 53165 GNU gdb(GDB)Red Hat Enterprise Linux(7.2-60。el6_4。1)...附加到进程53165 / bin / bash(已删除):没有这样的文件或目录

愚蠢的ShellShock事情迫使每个人都更新其bash ...该计算机中的自动更新删除了旧bash的二进制文件,并安装了一个新bash。

因此,即使该过程仍在进行中,但6个月后……仍无法找到生成该二进制文件的二进制文件(以及GDB搜索该二进制文件以获取write_history的地址)。

但是我也知道我的操作系统-我非常了解。我可以通过proc接口从内存中获取旧二进制文件的内容:

[root @ IamInHell] lsof + L1 | grep bash | grep 53165 bash 53165 root txt REG 253,0 938832 0 791023 / bin / bash(已删除)[root @ IamInHell] cat / proc / 53165 / exe> / tmp / oldBash

[root @ IamInHell] gdb --pid 53165 / tmp / oldBash ...为/ lib 64 / libnss_files加载的符号。这样。 2 0x0000003d37aac8be位于/ lib 64 / libc的waitpid()中。这样。 6 ...(gdb)调用write_history(" / tmp / foo")$ 1 = 0(gdb)detach从程序中分离:/ tmp / oldBash,进程53165(gdb)q [root @ IamInHell] tail -1 / tmp / foo为true时;做...

在我的桌子周围跳舞。我周围的人看着我,感到困惑并想知道我的精神状态。

为了减轻我未来的痛苦,并减轻其他编码人员/管理员的痛苦,我编写了一个脚本来自动完成所有这些工作。

自从我在自己的博客上发布了一些东西以来,就已经决定了很长时间了:-)

本网站上的评论要求使用JavaScript。可能您的浏览器不支持JavaScript,或者由于其他原因而未在运行脚本。如果您有兴趣阅读评论或留下评论,请使用其他浏览器或其他连接重试。