为什么“猫a.txt | xargs vi“销毁bash?

a.txtba.txt的内容

当我inputcat a.txt | xargs vi cat a.txt | xargs vi ,vi打开ba.txt ,一切似乎都OK …

但是当我退出vi的时候,我发现我的bash是不正常的。我看不到我input的指令。我input了ls 。 我看不到它,但是当我按下回车键,结果就显示出来了(用一种奇怪的方法..)…(键入ls ,我键入ll ,有一些中文字符,请忽略它)..而这个bash就是这样的:

庆典

有人可以解释吗?

你的bash外壳不会被破坏。 只是你的终端处于一种不好的状态 – 因为你发送了奇怪的字节给它(终端有一些状态),终端仿真器和内核管理这个状态,在这个过程错误地改变它之后它仍然存在。 stty(1)命令,关于/dev/tty的tty(4)手册页以及isatty(3)函数)。 键入(也许是盲目的) reset命令(或stty sane )重置终端。

大多数终端响应ANSI转义码 (对于丑陋的细节,阅读有关配置这些转义码的termcap(5) )。 发送任意字符或随机字节的命令可能会发送一些可能会损坏终端行为的转义序列。

但是,你使用vi可能是错误的。 对于可编程版本,考虑使用sed(1)或ed(1) ; 或者也许emacs --batch ….

如果你只想编辑由a.txt的行命名的文件ba.txt ,你可以运行:

  vi $(cat a.txt) 

或者更好,使用标准的EDITOR变量(参见environ(7) )

  $EDITOR $(cat a.txt) 

阅读高级Bash脚本指南 。 你可以使用反引号,看到这个答案 ,但我不建议使用它们。


由于历史的原因,终端模拟tty -s(跟随这个链接,它解释了很多),这是令人难以置信的复杂和神秘的物理设备。 你可能太年轻了,看不到他们(博物馆外)。 20世纪70年代,我从小就做过一些工作。 这是令人难以置信的有趣和嘈杂 – 一种机电通信打字机。

耶稣,我老了,没有人知道今天打字机真的是什么….

如果从管道内调用vi / vim, stdin将连接到前一个管道的输出,而不是终端。 vi / vim是一个交互式命令,需要从终端(tty)接收输入。

底线:因为vim期望输入来自交互式终端 ,所以你不能管道到xargs vim。

如果你紧密地在你的终端,你会注意到vi / vim写这个:

Vim:警告:输入不是来自终端

PS:你可以使用:

 cat file | xargs vim -Nu NONE 

为了避免这种情况,使vi / vim非互动。

我认为Basile的回答很好解释了为什么你的终端被搞砸了。 他也给了一个stty sane的解决方案。

当我想要find, grep -l ...(in your case, the cat too)结果打开文件find, grep -l ...(in your case, the cat too)我做的:

 vim $(find . ...) 

你可以尝试:

 vim $(cat a.txt) 

祝你好运。 🙂