Why "cat a.txt | xargs vi" destroy the bash?

bash, linux, pipe

Solution

Your `bash` shell is not destroyed. It is just that your terminal is in some bad state -because you sent strange bytes to it- (a terminal has some state -and the terminal emulator and the kernel manage that state, which persists after the process having wrongly changed it. See e.g. the stty(1) command, the tty(4) man page about `/dev/tty`, and the isatty(3) function). Type (perhaps blindly) the `reset` command (or `stty sane`) to reset the terminal.

Most terminals respond to ANSI escape codes (for ugly details, read about termcap(5) which is related to configuring these escape codes). A command sending arbitrary -or random- bytes may happen to send some escape sequences which might damage the behavior of your terminal.

However, your use of `vi` is probably wrong. For programmable edition, consider using sed(1) or ed(1); or perhaps `emacs --batch` ....

If you just want to edit the file `ba.txt` named by the line inside `a.txt` you could just run:

 vi $(cat a.txt)

or better yet, using the standard `EDITOR` variable (see environ(7))

 $EDITOR $(cat a.txt)

Read also the Advanced Bash Scripting Guide. You might use backquotes, see this answer, but I don't recommend using them.

For historical reasons, terminals emulate tty-s (follow that link, it explains a lot), which were incredibly complex and arcane physical devices. You are probably too young to have seen them (outside of a museum). I worked on some, as a teenager, in the 1970s. It was incredibly fun and noisy - a sort of electromechanical communicating typewriter.

Jesus, I'm getting old, no one know today what a typewriter really is....

Problem

The content of `a.txt` : `ba.txt` When I type `cat a.txt | xargs vi`, vi open the `ba.txt` and everything seems to be OK... But when I exit the vi, I find my bash is abnormal..I can't see the instructions I type in. I typed `ls`. I can't see it, but when I press the enter, the result is displayed(in a strange way..)...(After typed `ls`,I typed `ll`. There are some Chinese characters,please ignore it ).. And the bash is like this: Could anybody explain this?

Original source