sda*_*aau 9 bash filenames process-substitution
这是我的用例:命令行实用程序melt
可以接受带有.melt
命令行扩展名的文件名,然后打开它;例如,这是一个正确的test_p.melt
文件:
colour:blue
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
... 打开并播放melt test_p.melt
.
现在,问题是.melt
文件不支持注释,我希望他们支持(对于包含不可解析参数的任何行,包括那些带有 a 的参数,您都会收到错误消息#
)。所以这是一个注释test_c.melt
文件:
# master comment here
colour:blue # this is blue!
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
melt
直接打开它给出:
$ melt test_c.melt
Failed to load "# master comment here"
...
Run Code Online (Sandbox Code Playgroud)
...并且没有显示蓝屏。
所以我想 - 好吧,我无论如何都可以添加注释,然后使用 Bash 进程替换来过滤文件sed
,然后简单地将其提供给melt
应用程序。首先,尝试使用 进行测试cat
,测试成功:
$ cat <(sed 's/#.*$//' test_c.melt)
colour:blue
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
... 看起来挺好的; 但是,如果我尝试使用melt
,它会看穿我的诡计:
$ melt <(sed 's/#.*$//' test_c.melt)
Failed to load "/dev/fd/62"
Failed to load "/dev/fd/62"
Run Code Online (Sandbox Code Playgroud)
基本上,melt 得到了为进程替换提供的管道 Bash 的文件名 - 但不幸的melt
是,它argv[i]
直接处理的是什么;如果是文件,则需要.melt
在文件名中看到扩展名;如果没有 - 过程失败。
所以我的问题是:我怎么能使用进程替换——所以管道的文件名有一个特定的扩展名,在这种情况下.melt
?基本上,作为替换的结果,我想要一个管道文件名/dev/fd/62.melt
,我认为它会通过。
注意:当然,我总是可以这样做:
sed 's/#.*$//' test_c.melt > test_c_temp.melt
melt test_c_temp.melt
Run Code Online (Sandbox Code Playgroud)
...但首先,这里有两个命令 - 我想要一个单线管道;另一方面,它打开了我考虑之后删除临时文件的另一个问题,我不喜欢。
这是否可以使用 Bash 进程替换 - 或者以某种方式使用标准 Linux 工具?
一种可能性是指向melt
显示文件修改副本的文件系统。FUSE是一种构建文件系统驱动程序的通用方法,由普通程序实现,不需要任何特权。周围有许多 FUSE 文件系统,其中一个很有可能可以帮助您。这个想法是提供一个挂载点,读取.melt
文件时会读取 \xe2\x80\x9creal\xe2\x80\x9d 文件,但注释会被过滤掉。
ScriptFS看起来很有前途(但我从未使用过它)。像这样的东西应该有效:
\n\nmkdir ~/uncommented-melt\nscriptfs -p "$HOME/bin/uncomment-melt;&*.melt" ~/work ~/uncommented-melt\n
Run Code Online (Sandbox Code Playgroud)\n\n包含您的文件的~/work
树的根在哪里.melt
~/bin/uncomment-melt
#!/bin/sh\nsed \'s/#.*$//\' "$1"\n
Run Code Online (Sandbox Code Playgroud)\n\n然后,如果您有带有注释的文件~/work/test_c.melt
,则可以运行melt ~/uncommented-melt/test_c.melt
.
其他可能有用的 FUSE 文件系统:
\n\n