Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 从脚本获取最后执行的命令_Bash_Shell_Ksh - Fatal编程技术网

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中,这将给出预期的结果。