微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Linux中添加运算符到Bash?

我想添加一个运算符(例如^>)来处理prepend而不是追加(>>)。 我需要修改Bash源文件还是有更简单的方法插件等)?

如何在单个文本文件中将tiff图像编译为xyz坐标?

后台启动脚本时,我得到两个进程正在运行

等待命令是否等待variables赋值?

从现在开始,在5秒后运行命令`at'

尾巴不在bash脚本中提供输出

^是字符的一个可怜的选择,因为它在历史替换已经被使用了。

要将新的重定向类型添加到shell语法,请从parse.y开始。 将其声明为一个新的%token以便它可以被使用,将其添加到STRING_INT_ALIST other_token_alist[]以便它可以出现在输出中(例如错误消息),更新解析器中的redirection规则,并更新词法分析器以发出令牌遇到适当的字符。

command.h包含重定向类型的enum r_instruction ,这将需要扩展。 make_redirection中的make_cmd.c有一个巨大的switch语句,处理重定向指令,实际的重定向由redir.c的函数执行。 分散在源代码的其余部分中的是打印,复制和销毁管线的各种功能,这些管线也可能需要更新。

就这样! Bash并不是那么复杂。

这没有讨论如何实现预定义的重定向,这将是困难的,因为UNIX文件API只提供附加和覆盖。 前置到一个文件的唯一方法是完全重写它,这与其他答案一样,比任何现有的shell重定向都要复杂得多。

首先,你需要修改bash源代码并且相当重要。 因为,最重要的是,你很难实现。

请注意,bash重定向操作符通常会执行一个非常简单的写操作,并且只在单个文件(或者管道的情况下)上工作。 排除非常具体的解决方案,通常无法写入文件的开头,因为每次写入后需要将所有剩余内容向前移动。 你可以尝试这样做,但这将会很困难,非常无效(因为每个写操作都需要重写整个文件),而且非常不安全(因为出现任何错误,最终都会随机混合使用新旧版本)。

也就是说,如果像其他人那样使用临时文件功能或者其他解决方案,你的确可能会更好。

为了完整性,我自己实现:

prepend() { local tmp=$(tempfile) if cat - "${1}" > "${tmp}"; then mv "${tmp}" "${1}" else rm -f "${tmp}" # some error reporting fi }

请注意,与@jpa建议的不同,您应该将连接的数据写入临时文件,因为该操作可能会失败 ,如果这样做,则不希望丢失原始文件。 之后,您只需用新文件替换旧文件,或者删除临时文件并按照您的喜好处理故障。

简介与其他解决方案相同:

echo test | prepend file.txt

和一些修改后的版本来保留权限和符合链接安全(如果有必要的话)就像>>一样:

prepend() { local tmp=$(tempfile) if cat - "${1}" > "${tmp}"; then cat "${tmp}" > "${1}" rm -f "${tmp}" else rm -f "${tmp}" # some error reporting fi }

只要注意这个版本实际上是不太安全的,因为如果在第二个cat别的东西会写入到磁盘并填充它,那么最终会得到不完整的文件

说实话,如果有必要,我不会亲自使用它,而是处理符号链接和重置外部权限。

添加一个操作符可能相当困难,但也许一个函数可能就足够了?

function prepend { tmp=`tempfile`; cp $1 $tmp; cat - $tmp > $1; rm $tmp; }

使用示例:

echo foobar | prepend file.txt

将文本“foobar”前置到file.txt中。

我认为bash的插件体系结构(通过“启用”内置命令加载共享对象)仅限于提供附加的内置命令。 重定向操作符是运行简单命令的语法的一部分,所以我认为您需要修改解析器来识别和处理新的^>运算符。

大多数Linux文件系统不支持预先配置。 事实上,我不知道任何一个一个稳定的用户空间界面。 所以,正如其他人所说的那样,只能依赖覆盖 ,不管是初始部分,还是整个文件,都取决于你的需要。

您可以轻松(部分)覆盖Bash中的初始文件内容,而不会截断文件

exec {fd}<>"$filename" printf 'New initial contents' >$fd exec {fd}>&-

上面, $fd是由Bash自动分配的文件描述符, $filename是目标文件名称。 Bash在第一行打开一个新的读写文件描述符到目标文件; 这不会截断文件。 第二行覆盖文件的最初部分。 文件中的位置前进,因此可以使用多个命令来覆盖文件中的连续部分。 第三行关闭描述符; 由于每个进程只有有限的可用数量,因此您希望在不再需要它们之后关闭它们,否则长时间运行的脚本可能会用完。

请注意, >比您预期的要少:

从命令行中删除>和下面的单词,记住重定向

当命令行被处理并且命令可以被启动时,调用fork(2) (或者clone(2) )来创建一个新的进程。

根据命令修改新的进程。包括修改后的环境变量( SOMEVAR=foo yourcommand ),还改变了filedescriptors。 此时,来自cmdline的> yourfile将以只写模式将stdout filedescriptor(即#1)处的文件open(2) ,将文件截断为零字节 。 A >> yourfile会产生这样的效果文件在只写模式和附加模式下在标准输出运行

(只有现在启动程序,像execv(yourprogram,yourargs)

一个简单的例子,重定向可以被实现

open(yourfile,O_WRONLY|O_Trunc);

要么

open(yourfile,O_WRONLY|O_APPEND);

分别。

然后启动的程序将设置正确的环境,并可以愉快地写入fd1。 从这里, 壳不涉及 。 真正的工作不是由shell完成的,而是由操作系统完成的。 由于Unix没有预先模式(并且不可能正确地集成这个特性),所以你可以尝试的所有事情都会以非常糟糕的方式结束。

试着重新考虑你的要求,总是有一个更简单的方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐