我想知道我使用的确切命令参数(我不记得了),所以我想看看我在那个tty上运行的命令.由于shell仍在运行,因此它没有向bash_history写入任何内容 – 该实例的历史记录仍在内存中.
所以,我的问题是,是否有办法远程检索我想要的东西,也许:
(a)向正在运行的shell发送信号,使其转储其bash历史记录
(b)检查正在运行的shell的环境以获取其历史信息
(c)检查tty会话中最近的x#行,以便我可以看到我键入的内容
或其他一些手段……
解决方法
>打开远程主机的ssh会话.使用几个窗口启动屏幕或tmux会话.您可以通过键入“tty”来确定每个窗口的伪设备.假设我们有“/ dev / pts / [123]”对应于我们在屏幕会话中运行的三个shell
>确定有问题的bash进程的pid(要为其重定向输入和输出的pid).此过程当前与诸如/ dev / tty1的终端设备相关联
>从屏幕窗口1,运行“gdb -p [pid]”并在gdb中运行以下命令:
一个. p dup2(open(“/ dev / pts / 2”,0),0)#this更改目标进程的标准输入
湾p dup2(open(“/ dev / pts / 3”,1),1)#this更改目标进程的标准输出
C. p dup2(open(“/ dev / pts / 3”,1,),2)#这会改变目标进程的标准错误
d.分离
即放弃
换句话说,第3步的作用是使Window 2成为标准输入,而Window 3作为输出.
4.从窗口1(/ dev / pts / 1),“ls -l / proc / [pid] / fd”来验证我们想要操作的bash进程的文件描述符更改
5.你在窗口2中键入的内容现在被送到两个地方:与此窗口关联的原始bash shell和目标进程.因此,从窗口2(/ dev / pts / 2),键入“hhiissttoorryy [return] [return]”.你必须输入两次的原因是因为输入被分割为当前的bash shell和目标bash shell.这是因为操作知道有两个源接入/ dev / pts / 2的键盘输入,它可以公平地分配你输入的字符.第一个字符转到一个目的地,下一个转到第二个目的地,等等.如果你有三个进程的stdin是/ dev / pts / 3,那么你必须输入每个字符三次.内核以循环方式将输入字符提供给收件人.
6.通过临时将原始Window 2 bash shell的stdin设置为某些未使用的设备(例如/ dev / tty5或其他设备),可以解决上述问题.这使得/ dev / pts / 2键盘只能作为一个进程(而不是两个)的标准输入.现在您可以正常输入命令(它们不会回显到您所在的屏幕,它们将回显到/ dev / pts / 3.)
7.既然你输入’history’并且它被输入到目标进程,其stdout是窗口3,切换到窗口3,这样你就可以看到命令输出.现在您拥有目标bash shell的命令历史记录.
8.回到窗口1,再次在[pid]上使用gdb将目标shell的标准输入,输出,错误重置为原始值(/ dev / tty1).您还可以将Window 2 stdin设置回原来的状态.
>如果您愿意,可以通过使用’exec 3>& – ‘删除额外的文件描述符来清除额外的文件描述符,例如删除fd 3
请注意,在正在运行的进程上运行gdb时,它会以与SIGSTOP相同的方式挂起进程的执行.当你“分离”它时,它会像在SIGCONT中那样恢复.这允许您操作文件描述符而不会产生不良后果.
我没有尝试过,但你可以通过打开一个shell,确定它的tty或pty,临时设置shell的指定标准进出一个不可用的设备,分配tty /,使上面的内容变得更容易和更友好. pty作为目标shell的标准输入/输出.这样,您可以使用单个屏幕对目标shell进行所有输入和输出.
摘要:使用上述过程,只要您有一个可以访问的shell,就可以将其用作系统上任何其他进程/ shell的标准输入/输出.这很有用,例如,如果您想与控制台上运行的shell进行交互,但您没有对主机的物理访问权限(或者是一个无人值守的解决方案).当然,这可以推广到您希望特定shell控制您选择的任何进程的输入/输出的任何数量的情况.