我正在尝试创建一个bash脚本,它将终端历史记录保存到名为hist.txt的文件中。使用history > hist.txt
似乎在bash脚本中不起作用,但是在命令行中执行时效果很好。
任何指导,不胜感激。
谢谢朱迪
~/.bash_history
文件。
我正在尝试创建一个bash脚本,它将终端历史记录保存到名为hist.txt的文件中。使用history > hist.txt
似乎在bash脚本中不起作用,但是在命令行中执行时效果很好。
任何指导,不胜感激。
谢谢朱迪
~/.bash_history
文件。
Answers:
使用source
或运行脚本.
:
source ./script_name.sh
要么
. ./script_name.sh
后者在不同外壳之间的兼容性更高。
这个问题强调了一个重要的观点,那就是shell脚本在它们自己的上下文中运行。要了解这意味着什么,请考虑以下shell脚本:
#!/bin/bash
cd /
ls
如果运行此命令,将得到类似以下的输出:
bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
但是您会注意到,运行脚本后,您仍在运行脚本之前所在的目录中:cd /
脚本内部实际上并未影响您的会话-它仅影响了脚本在其中运行的上下文,被创建用于脚本运行,并在返回时销毁。
该source
命令将“从当前shell上下文中的filename参数读取并执行命令”,因此其中的任何命令cd
都会影响您当前的会话。如果要通过将上面的脚本传递给source
您会发现之后您最终位于根目录中。
在这种情况下,问题在于该history
命令为您提供了当前shell上下文的历史记录。在不使用脚本的情况下运行脚本的shell上下文source
没有历史记录,因此不会向输出文件写入任何内容。如果使用source
它,它将在正确的上下文中执行,并且将按预期工作。
注意:这source
是内置的shell,本身不是程序-在Bash中source
是的代名词.
,但在某些shell中只能.
用-我source
在此答案中使用过,因为它比容易阅读.
,但为了最大程度地兼容,.
应该使用。
首先,请注意您的历史记录已在文件中。如果您正在运行bash,则其名称通常为~/.bash_history
。更具体地说,就是将变量设置HISTFILE
为的内容。如果要将其复制到另一个文件,只需运行cat "$HISTFILE" > hist.txt
现在,关于history
命令在bash shell脚本中不起作用的原因,是因为脚本在当前shell会话的非交互式子shell中运行。子级shell不会继承父级的所有环境(因此,不是所有设置的变量),仅继承已导出的变量。为了说明这一点,下面的脚本将回显该变量的值$var
:
#!/bin/bash
echo "$var"
现在,设置$var
为某种并运行脚本:
$ var="foo"
$ foo.sh
VAR:
接下来,首先导出变量:
$ var="foo"
$ export var
$ foo.sh
VAR: foo
如您所见,导出变量后,子外壳程序即可使用它。
如前所述,历史记录存储在变量所指向的文件中$HISTFILENAME
。由于默认情况下不会导出该文件,因此在运行脚本时不会将其设置:
$ cat foo.sh
#!/bin/bash
echo "HISTFILE: $HISTFILE"
$ ./foo.sh
HISTFILE:
$ echo $HISTFILE
/home/terdon/.bash_history
如您在上面的示例中看到的那样,该变量HISTFILE
是在我的常规Shell会话中设置的,但是在运行脚本时为空。
因此,要获取历史记录,您有几种选择:
默认HISTFILE
值为$HOME/.bash_history
。如果尚未更改,则可以在脚本中运行以下命令:
cat "$HOME/.bash_history" > history
您可以将$HISTFILE
变量传递给脚本,cat
这样:
#!/bin/bash
cat "$1" > history
将以上内容另存为foo.sh
,然后像这样运行:
./foo.sh "$HISTORY"
确保已导出变量。将此行添加到您的~/.bash_profile
(如果存在)或~/.profile
(如果~/.bash_profile
不存在)文件中:
export HISTFILE
然后,注销并再次登录,您应该能够history > hist.txt
从脚本中按预期运行。这是因为export VAR
意味着“使$ VAR可用于子shell”。实际上,这意味着HISTFILE
将由您用于运行脚本的非交互式外壳程序继承。
现在,虽然HISTFILE
将设置,但是运行脚本的shell尚未读取它。因此,要使其正常工作,您需要先阅读它history -r
。整个脚本如下所示:
$!/bin/bash
history -r
history > hist.txt
另外,可以在运行脚本之前手动将其导出:
$ export HISTFILE
但是您仍然需要history -r
在脚本中。
您可以source
按照@ p0llard的答案的建议进行操作。