我有一个通过 SSH 连接到远程主机的脚本,创建临时文件并执行以下命令:
调用系统(mysql --database=information_schema --host=localhost < /tmp/drush_1JAjtt)
每次它创建不同的文件(模式:)drush_xxxxxx
。
我已经尝试在远程手动运行几次:
tail -f /tmp/drush_*
但我的连接速度太慢,大多数时候我都会遇到错误:
tail:无法打开`/tmp/drush_*'进行读取:没有这样的文件或目录
有什么技巧可以在创建此类文件后立即访问该文件以显示其内容吗?
答案1
我遇到这个问题时检查特定应用程序的行为我不信任。应用程序将创建并随后删除其临时文件。 克诺布溶液很好,但是使用cat
可能会导致竞争条件(即文件在cat
工作时可能被删除,因此仅检索部分数据)。
通过创建到文件本身的硬链接可以降低竞争条件的可能性。grep
ing 和创建硬链接可以通过 结合起来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 create
flag ,我们只对将立即创建的临时文件感兴趣,并且输出格式为我们提供了创建的临时文件的完整路径。忽略通过 的前两行输出NR>2
。对于每个报告的文件,都会在表单中创建一个硬链接/tmp/hardlink_to_<original filename>
答案2
您可以设置一个使用inotify
( inotify-tools
on Debian
) 的脚本,并让它扫描特定目录中文件的任何更改。然后过滤出文件名并将cat
其保存到日志文件中。
答案3
drush 可能通过以下两种方式之一使用该临时文件:
- 它正在创建文件;使用它;然后把它留在身边。
- 它正在创建文件;使用它;然后清理它。
我的猜测是,在情况(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
更改/tmp
和drush
为您合适的值。