xargs:带有提示的 exec 命令

hel*_*nki 4 redirect zsh xargs

我正在尝试使用 xargs 执行以下操作

pacman -Q | grep xf86-video | awk '{print $1}' | xargs pacman -R删除我机器上的所有 xf86-video-* 驱动程序。为了使问题更清楚,这里是输出pacman -Q | grep xf86-video | awk '{print $1}'

xf86-video-ark
xf86-video-ati
xf86-video-dummy
xf86-video-fbdev
xf86-video-glint
xf86-video-i128
xf86-video-intel
xf86-video-mach64
xf86-video-neomagic
xf86-video-nouveau
....
Run Code Online (Sandbox Code Playgroud)

当我将结果重定向到 时xargs,输出如下所示:

xargs 结果

关键是,xargs即将执行的命令需要用户做一些额外的输入(如您所见,它需要是/否),但会xargs 自动添加一个未知符号#,然后退出,这导致我的目的无法实现。

为什么xargs会这样做,或者,我可以做什么来使用xargs带有提示的命令?

Ada*_*hon 6

您可以使用

xargs -a <(pacman -Q | awk '/xf86-video/{print $1}') pacman -R
Run Code Online (Sandbox Code Playgroud)

解释:

没有进一步的参数xargs不适用于交互式(命令行)应用程序。

原因是,默认情况下xargs,它从stdin获取输入,但交互式应用程序也期望来自stdin 的输入。为了防止应用程序抢夺被用于输入xargsxargs重定向标准输入来自/dev/null于它运行的应用程序。这导致应用程序只收到一个EOF。(仅运行pacman -R SOMEPACKAGE并按Ctrl+D具有相同的效果)。

要开始xargs使用交互式命令,您必须使用--arg-file=FILE参数 (short -a FILE)。这告诉xargsFILE. 这也使stdin保持不变。

所以你可以把你的包列表放到一个临时文件中

pacman -Q | awk '/xf86-video/{print $1}' > /tmp/packagelist
xargs -a /tmp/packagelist pacman -R
rm /tmp/packagelist
Run Code Online (Sandbox Code Playgroud)

或者您可以使用zsh 的进程替换机制<(list)。执行带有 的行时<(list)<(list)将替换为list可以从中读取的输出的文件名。

xargs -a <(pacman -Q | awk '/xf86-video/{print $1}') pacman -R
Run Code Online (Sandbox Code Playgroud)

你得到的单个#不是来自xargs而是来自zsh它本身。如果 shell 选项PROMPT_CRPROMPT_SP已设置(默认情况下两者都是)zsh尝试保留部分行,即不以换行符结尾的行。为了表示这样的一行已经被保留,zsh 在该行的末尾打印一个反向+粗体字符,默认情况下,普通用户为%,root用户为#