我正在尝试生成一个新终端,执行一些命令并将其输出通过管道传输到原始进程的标准输入。我想做的一件事是下面的 bash 一句话:
$ xterm -e sh -c "echo -e 'foo\nbar' > /proc/$$/fd/1" | grep foo
我在其中生成一个新的 xterm 窗口,打印foo\nbar
并尝试将其重定向到我正在执行此命令的 shell 的标准输入。为了看看它是否有效,我将它通过管道传输到grep
.
上面的代码将foo
和打印bar
到标准输出,而不是仅仅打印foo
,但我不确定为什么。我怎样才能解决这个问题?
编辑:这个的真实案例实现是一个使用 fzf 的文件选择器:
#!/usr/bin/env bash
function open() {
# takes a bunch of file names (either passed as arguments or from stdin) and
# opens them
true
}
# This is what I have now
alacritty \
-e sh -c 'fzf -m --prompt="Open> " --border=horizontal --print0 \
| (nohup xargs -0 bash -c '\''open "$@"'\'' _ &>/dev/null &)'
# This is what I'm trying to do
# alacritty \
# -e sh -c "fzf -m --prompt='Open> ' --border=horizontal > /proc/$$/fd/1" \
# | open
答案1
我有点晚了,但作为使用命名管道(FIFO)的替代方案,fzf 还提供了执行外部命令以响应键绑定的功能。这就是我使用 fzf 作为文件选择器的方式(使用xdg-开放,这应该适用于大多数 Linux 发行版):
fzf --bind "enter:execute(setsid xdg-open {} 2>/dev/null &)+abort"
您可以启动一个终端来执行上述操作的某些变体(例如,从全局键盘快捷键)。在我的点文件中,我有一个脚本打开文件和一个用于启动 GUI 程序使用 gtk 启动。我已经使用它几个月了,没有太大问题,但 gtk-launch 总是忽略由于某种原因重新启动后的第一个调用。
不管怎样,我发现这比摆弄 fifo 或文件描述符更简单。
答案2
#!/bin/sh
exec alacritty -e /bin/sh -c \
"exec fzf \"\$@\" < /proc/$$/fd/0 > /proc/$$/fd/1" \
-- "$@" 2>/dev/null