xargs 带有打开编辑器的命令使 shell 处于奇怪的状态
我尝试为提交几个不同的 git 项目创建一个别名。我尝试了类似的方法
cat projectPaths | \
xargs -I project git --git-dir=project/.git --work-tree=project commit -a
,其中projectPaths是一个文件,其中包含我想要提交的所有项目的路径。这似乎在大多数情况下都有效,为每个项目依次启动 vi,以便我可以为其编写提交消息。不过,我确实收到一条消息:
“Vim:警告:输入不是来自终端”
,之后我的终端很奇怪:它不显示我输入的文本,并且似乎不输出任何换行符。当我输入“重置”时,事情几乎恢复正常,但显然我做错了什么。
有没有什么方法可以在不弄乱我的外壳的情况下获得相同的行为?
谢谢!
I tried to make an alias for committing several different git projects. I tried something like
cat projectPaths | \
xargs -I project git --git-dir=project/.git --work-tree=project commit -a
where projectPaths is a file containing the paths to all the projects I want to commit. This seems to work for the most part, firing up vi in sequence for each project so that I can write a commit msg for it. I do, however, get a msg:
"Vim: Warning: Input is not from a terminal"
and afterward my terminal is weird: it doesn't show the text I type and doesn't seem to output any newlines. When I enter "reset" things pretty much back to normal, but clearly I'm doing something wrong.
Is there some way to get the same behavior without messing up my shell?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用这里更简单的示例
有几种解决问题的方法:
或
或
first 示例使用 xargs
-a
(--arg-file) 标志告诉 xargs 从文件而不是标准输入中获取输入。在本例中,我们提供的文件是 bash 进程替换,而不是常规文件文件。
进程替换获取
<( )
中包含的命令的输出,将其放入文件描述符中,然后替换该文件描述符,在这种情况下,替换的命令将类似于 xargs -a /dev /fd/63 vim.第二个命令使用命令替换,命令为在子 shell 中执行,并且它们的标准输出数据被替换。
third 命令使用 xargs
--open-tty
(-o
) 标志,手册页对此进行了如下描述:如果您确实以旧方式使用它并希望让终端再次运行,您可以使用
reset
命令。Using the simpler example of
here are a few ways to fix the problem:
or
or
The first example uses the xargs
-a
(--arg-file
) flag which tells xargs to take its input from a file rather than standard input. The file we give it in this case is a bash process substitution rather than a regular file.Process substitution takes the output of the command contained in
<( )
places it in a filedescriptor and then substitutes the filedescriptor, in this case the substituted command would be something likexargs -a /dev/fd/63 vim
.The second command uses command substitution, the commands are executed in a subshell, and their stdout data is substituted.
The third command uses the xargs
--open-tty
(-o
) flag, which the man page describes thusly:If you do use it the old way and want to get your terminal to behave again you can use the
reset
command.问题是,由于您在管道中运行 xargs(以及 git 和 vim),因此它的标准输入是从
cat projectPaths
的输出而不是终端获取的;这让 vim 很困惑。幸运的是,解决方案很简单:将-o
标志添加到 xargs,它将使用来自 /dev/tty 的输入(而不是它自己的标准输入)启动 git(以及 vim)。The problem is that since you're running xargs (and hence git and hence vim) in a pipeline, its stdin is taken from the output of
cat projectPaths
rather than the terminal; this is confusing vim. Fortunately, the solution is simple: add the-o
flag to xargs, and it'll start git (and hence vim) with input from /dev/tty, instead of its own stdin.GNU
xargs
的手册页显示了 emacs 的类似命令:(在此命令中,第二个“emacs”是 wisbucky 在对此答案的评论中引用的“虚拟字符串”)
并说: :
另一件可以尝试的事情是使用
-a
而不是cat
:或两者的某种组合。
The man page for GNU
xargs
shows a similar command for emacs:(in this command, the second "emacs" is the "dummy string" that wisbucky refers to in a comment to this answer)
and says this:
Another thing to try is using
-a
instead ofcat
:or some combination of the two.
如果您安装了 GNU Parallel http://www.gnu.org/software/parallel/你应该能够做到这一点:
一般来说,这也有效:
如果你想一次编辑多个文件(并且你已将 $EDITOR 设置为你最喜欢的编辑器)。
-o
用于xargs
(如其他地方所述)仅适用于某些版本的xargs
(特别是它不适用于 GNU xargs)。观看介绍视频,了解有关 GNU Parallel 的更多信息 http://www.youtube.com/watch?v =OpaiGYxkSuQ
If you have GNU Parallel http://www.gnu.org/software/parallel/ installed you should be able to do this:
In general this works too:
in case you want to edit more than one file at a time (and you have set $EDITOR to your favorite editor).
-o
forxargs
(as mentioned elsewhere) only works for some versions ofxargs
(notably it does not work for GNU xargs).Watch the intro video to learn more about GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ
有趣的!我在 Mac 上也看到了完全相同的行为,执行一些简单的操作:
ls *.h | xargs vim
显然,这是 vim 的问题:
http://talideon.com/ weblog/2007/03/xargs-vim.cfm
Interesting! I see the exact same behaviour on Mac as well, doing something as simple as:
ls *.h | xargs vim
Apparently, it is a problem with vim:
http://talideon.com/weblog/2007/03/xargs-vim.cfm