是否可以根据文件名生成文件内容?
我需要很多类似的.conf
文件,其内容仅取决于文件名。
我可以创建一些“动态”文件并生成一堆指向该文件的符号链接吗?
也许 fifo 是一个解决方案,但我无法在生成脚本中获取文件名:
zsh$ mkfifo ./dynamic.conf
zsh$ ln -s ./dynamic.conf ./case1.conf
zsh$ echo $0 > ./dynamic.conf &
zsh$ cat ./case1.conf
我有zsh
(我需要case1.conf
)。
答案1
完全不同的方法因为我只知道最后一个答案你会翻白眼。
在本教程中,您将依赖inotify
这意味着它确实是特定于 Linux 的。您将彻底解决问题——各个配置文件仍然存在,但您将自动重新生成它们每次改变主控。
你有你的“主”配置文件,比如说master.conf
,它包含你的所有部分、子部分等。你设置你的脚本,以便inotify
当该脚本更改时,它将重写所有这些文件。 (为了避免竞争条件,您可能需要采取一些额外的技巧,例如将文件存储在子目录中,以及交换目录以执行“提交”。)
从https://stackoverflow.com/q/5316178/3849157我们得到一个基本的 perl 脚本:
my $inotify = Linux::Inotify2->new;
$inotify->watch("/etc/master.conf", IN_MODIFY);
while () {
my @events = $inotify->read;
unless (@events > 0){
print "read error: $!";
last ;
}
foreach my $event (@events) {
next unless $event->IN_MODIFY;
# 1. TODO: RE-READ IN THE CONFIG FILE
# (example)
$config_hash = &parse_master_file;
# 2. TODO: RE-GENERATE YOUR CONFIG FILES
# (example)
for $section qw( section1 section2 misc ) {
open(S,"> /etc/${section}.conf")
print S &dump_config($config_hash,$section)
close(S)
}
}
}
执行parse_master_file
和dump_config
取决于您。另外,主循环中可能应该调用 sleep,否则你的 CPU 会着火。
答案2
您有一个读取所有这些文件的应用程序/程序.conf
,并且您希望将它们全部合并到一个文件中,该文件动态地为程序选择的文件名吐出适当的信息。基于管道的解决方案的问题在于,提供管道的程序无法检测到消费者已打开或想要读取的文件。所以你需要另一种方法。
来自另一个领域的一个鲜为人知的解决方案,解决了另一个领域的令人沮丧的问题:在构建 rpm 时,我们需要缩短 rpmbuild 过程,以修复最终打包步骤中的一些小问题。该spec
文件有几个与我们正在构建的 RPM 相关的“部分”...准备、构建、文件。当我们的程序构建但文件部分存在一些错误时,我们希望 rpmbuild 跳过重新编译。但它不会这样做......按设计。
有些人发现你可以用来LD_PRELOAD
加载一个专门设计的so
/dll 文件来捕获open
调用。如果open
调用的是规范文件,它将为除该files
部分之外的所有内容提供空条目,以便在rpmbuild
读取文件时,它实际上正在读取该 DLL 告诉它的内容。
我使用了它好几个星期,但在某个时刻,我擦除了虚拟机,将该程序从存在中删除,从此再也找不到它了。 :( 一个名为的程序mock
现在执行此操作,但我不知道它是否以相同的方式执行或使用其他方法。
但这就是这个想法。您需要创建一个 DLL,它可以通过 LD_PRELOAD 加载并覆盖open
对该程序的调用,但将您不感兴趣的文件的调用传递给(真实的)。对于您感兴趣的文件,它会提供数据由您的主文件找到并合并。
听起来很复杂?是的,有一点。好的一面是,您将拥有创建一些非常令人讨厌的 rootkit 和特洛伊木马的工具。
ltrace -e open <program>
要验证这是否可行,请使用以下命令运行程序:
ltrace -e open /usr/bin/tail /etc/fstab
您将会看到这个输出(类似)...
(0, 0, 0, 0x7f1c32ade000, 88) = 0x3055621160
open("/etc/fstab", 0, 00) = 4
只要您的程序使用 glibc 打开这些文件(而不是直接系统调用),您就会在上面的输出中看到它,并且您可以正常工作了。
下一步:某个人详细描述如何覆盖ioctl
调用。这会让你走上正轨。这里有一个非常好的教程。
答案3
所提出的解决方案对于生产使用来说太疯狂了。
事实上,您似乎对 inotify 方法很好(文件在主配置修改后显式重新生成),因此您可以只使用一个简单的脚本来重新生成所有垃圾。在那里,inotify 被避免而没有损失功能。好处是您需要调试的东西更少,并且不必在后台照顾该过程。
对于lulz,应该指出的是,可以实现所讨论的功能,但我看不出有任何理由这样做。事情是这样的:一个特殊的文件系统(例如基于熔丝的)等等 - 打开、读取等。处理这些文件的任何人发出的例程最终都会调用您的代码,因此您可以反馈您想要的任何内容。但话又说回来,你到底为什么要这么做。