创建后如何直接访问临时文件?

创建后如何直接访问临时文件?

我有一个通过 SSH 连接到远程主机的脚本,创建临时文件并执行以下命令:

调用系统(mysql --database=information_schema --host=localhost < /tmp/drush_1JAjtt)

每次它创建不同的文件(模式:)drush_xxxxxx

我已经尝试在远程手动运行几次:

tail -f /tmp/drush_*

但我的连接速度太慢,大多数时候我都会遇到错误:

tail:无法打开`/tmp/drush_*'进行读取:没有这样的文件或目录

有什么技巧可以在创建此类文件后立即访问该文件以显示其内容吗?

答案1

我遇到这个问题时检查特定应用程序的行为我不信任。应用程序将创建并随后删除其临时文件。 克诺布溶液很好,但是使用cat可能会导致竞争条件(即文件在cat工作时可能被删除,因此仅检索部分数据)。

通过创建到文件本身的硬链接可以降低竞争条件的可能性。greping 和创建硬链接可以通过 结合起来awk。因此,我想出了以下内容;

inotifywait -e create -m --format "%w/%f" /tmp/suspicious_dir/ 2>&1 | 
awk 'NR>2{n=split($0,a,"/");system("ln "$0" /tmp/hardlink_to_"a[n]);}'

由于我们使用的是-e createflag ,我们只对将立即创建的临时文件感兴趣,并且输出格式为我们提供了创建的临时文件的完整路径。忽略通过 的前两行输出NR>2。对于每个报告的文件,都会在表单中创建一个硬链接/tmp/hardlink_to_<original filename>

答案2

您可以设置一个使用inotify( inotify-toolson Debian) 的脚本,并让它扫描特定目录中文件的任何更改。然后过滤出文件名并将cat其保存到日志文件中。

答案3

drush 可能通过以下两种方式之一使用该临时文件:

  1. 它正在创建文件;使用它;然后把它留在身边。
  2. 它正在创建文件;使用它;然后清理它。

我的猜测是,在情况(1)中您不会提出问题,因为您可以在事后手动检查文件。那么问题是您想要在临时文件的短暂生命周期内检查该文件。

使用外部进程来监视临时文件可能很有可能起作用——尽管这取决于临时文件持续的时间(5 毫秒?500 毫秒?5 秒?5 分钟?)以及监视系统的响应速度。

另一种方法是使用“mysql”命令来记录您感兴趣的数据。例如,如果“mysql”位于“/usr/bin/mysql”中,那么您可以创建一个文件“/usr/local/” bin/mysql”:

#!/bin/bash
LOG=/tmp/mysql-commands
REALCMD=/usr/bin/mysql

NOW=$(date)
echo "[[$NOW: Running: $REALCMD $@]]" >> "$LOG"
tee -a "$LOG" | "$REALCMD" "$@"
exit $?

答案4

如果文件创建的时间足够短,您可以在运行脚本之前在单独的终端上运行以下命令:

while true; do cat /tmp/drush_* 2>/dev/null && break; done

/tmp/drush_*你的模式在哪里。优点是速度快,并且您无需安装任何外部工具(如果您没有管理员/根权限)。

请注意,在这种特殊情况下,使用inotifywatch(from inotify-tools) 工具不起作用,因为该文件是在放置手表后创建的,并且不会检测到更改。阅读更多:为什么 inotify 不打印已更改文件的列表?

但您仍然可以使用inotifywait使用 Linux 的 inotify 接口有效等待文件更改的工具。

这是一个简单的例子:

inotifywait -m --format "%e %f" /tmp

并示例显示新创建的文件的内容/tmp

inotifywait -m --format "%f" /tmp | grep --line-buffered ^drush | xargs -L1 -I% cat /tmp/% 2> /dev/null

如有必要,请sudo在前面添加。cat更改/tmpdrush为您合适的值。

相关内容