Bash 从脚本获取最后执行的命令
我正试图从脚本的命令行获取最后执行的命令,以保存供以后参考: 例如:Bash 从脚本获取最后执行的命令,bash,shell,ksh,Bash,Shell,Ksh,我正试图从脚本的命令行获取最后执行的命令,以保存供以后参考: 例如: # echo "Hello World!!!" > Hello World!!! # my_script.sh > echo "Hello World!!!" 剧本的内容是: #!/usr/bin/ksh fc -nl -1 | sed -n 1p 现在您注意到,这里使用的ksh和fc是一个内置命令,如果理解正确,应该由任何与POSIX兼容的shell实现。[我了解此功能是交互式的,再次调用相同的fc将产生不
# echo "Hello World!!!"
> Hello World!!!
# my_script.sh
> echo "Hello World!!!"
剧本的内容是:
#!/usr/bin/ksh
fc -nl -1 | sed -n 1p
现在您注意到,这里使用的ksh
和fc
是一个内置命令,如果理解正确,应该由任何与POSIX兼容的shell实现。[我了解此功能是交互式的,再次调用相同的fc
将产生不同的结果,但这不是您要讨论的问题]
到目前为止,仅当从shell调用my_script.sh
时,或者从bash
调用并将脚本的第一行更改为,上述操作才有效/bin/bash
那么它也可以工作,如果shell不同,它就不会工作
我想知道是否有什么好方法可以在不受调用脚本的shell约束的情况下实现上述功能。我知道,
fc
是一个内置命令,它在每个shell中都能工作,因此我的方法很可能与我想要实现的完全不同。还有更好的建议吗 fc设计用于交互使用。我在cygwin/bash上测试了您的示例,结果不同。即使到处都有bash,fc命令在我的情况下也不起作用
我认为fc显示了当前shell的最后一条命令(这里我不是说shell解释器,而是说shell是“进程框”),所以问题更多的是为什么它对您有效
我不认为有一种干净的方法可以实现您想要的,因为(可能我错过了一些东西)您需要两个不同的进程(bash和您的magic命令[my_script.sh]),默认情况下操作系统确保它们之间的隔离
您可以依赖于您观察到的内容(不可移植,取决于shell解释器等)
您不能依赖BASH historic,因为它位于内存中(文件仅在退出时更新)
您可以使用别名或函数(编辑:@Charles Duffy是正确的)。在这种情况下,您将无法从另一个终端使用您的“魔术命令”,但对于交互式使用,它可以完成任务
编辑:
或者您可以提供两个命令:一个用于保存,另一个用于查找。在这种情况下,您可以管理自己的历史记录,但必须显式保存每个命令
所以我找了个钩子。我找到了另一根线:
但我观察到它减慢了解释器的速度…fc是为交互使用而设计的。我在cygwin/bash上测试了您的示例,结果有所不同。即使在bash无处不在的情况下,fc命令在我的情况下也不起作用 我认为fc显示了当前shell的最后一条命令(这里我不是说shell解释器,而是说shell是“进程框”),所以问题更多的是为什么它对您有效 我不认为有一种干净的方法可以实现您想要的,因为(可能我错过了一些东西)您需要两个不同的进程(bash和您的magic命令[my_script.sh]),默认情况下操作系统确保它们之间的隔离 您可以依赖于您观察到的内容(不可移植,取决于shell解释器等) 您不能依赖BASH historic,因为它位于内存中(文件仅在退出时更新) 您可以使用别名或函数(编辑:@Charles Duffy是正确的)。在这种情况下,您将无法从另一个终端使用您的“魔术命令”,但对于交互式使用,它可以完成任务 编辑: 或者您可以提供两个命令:一个用于保存,另一个用于查找。在这种情况下,您可以管理自己的历史记录,但必须显式保存每个命令 所以我找了个钩子。我找到了另一根线:
但是我观察到它减慢了解释器的速度…有点复杂,但是我能够使用这个命令在Linux上获得zsh、bash、ksh和tcsh中的最新命令:
history | tail -2 | head -1 | sed -r 's/^[ \t]*[0-9]*[ \t]+([^ \t].*$)/\1/'
注意事项:这使用GNU-sed,因此如果使用BSD、OS X等,您需要安装它;而且,tcsh将在命令本身之前显示命令的时间。常规的
csh
在我尝试时似乎没有运行的history
命令。Linux上zsh、bash、ksh和tcsh中的最新命令:
history | tail -2 | head -1 | sed -r 's/^[ \t]*[0-9]*[ \t]+([^ \t].*$)/\1/'
注意事项:这使用GNU-sed,因此如果使用BSD、OS X等,您需要安装它;而且,tcsh将在命令本身之前显示命令的时间。常规的
csh
在我尝试时似乎没有运行的history
命令。不断地租贝壳
当
-l`,
是用于显示$SHELL历史记录的POSIX标准命令,实现细节可能会有所不同
至少bash和ksh93都将使用
fc -n -l -1 -1
但是,POSIX不保证将shell历史记录转移到shell的新实例,因为这需要存在$HISTFILE
当前,shell可能默认为$HOME/.sh_history
但是,此历史文件或命令历史列表不能在不同的shell之间移植
POSIX Shell对
说:
当交互使用sh实用程序时,它应维护命令列表
以前在HISTFILE环境命名的文件中从终端输入
变量。未指定此文件的类型、大小和内部格式
重点矿山
这意味着您的脚本需要知道是哪个shell编写了历史记录
我试图使用$SHELL-c'fc-nl-1-1'
,但当$SHELL引用bash时,这似乎不起作用。从bash调用ksh-c
…实际上起到了作用
我能让它工作的唯一方法是创建一个函数
last_command() { (fc -n -l -1 -1); }
在ksh和bash中,这将给出预期的结果。