xargs:带有提示的执行命令

xargs: exec command with prompt

我正在尝试使用 xargs

执行以下操作

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

的输出
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
....

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

重点是,xargs即将执行的命令需要用户做一些额外的输入(如你所见,它需要一个Yes/No), 但是xargs 自动 添加一个未知符号#,然后退出,导致我的目标未实现。

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

您需要 运行 pacman 第二次使用 --noconfirm 选项:

pacman -Q | grep xf86-video | awk '{print }' | xargs pacman -R --noconfirm

这将禁用 'are you sure' 消息,并且无需输入即可执行操作。

你可以使用

xargs -a <(pacman -Q | awk '/xf86-video/{print }') pacman -R

解释:

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

原因是,默认情况下xargsstdin 获取输入,但交互式应用程序也期望从 stdin[=61 输入=].为了防止应用程序获取用于 xargs 的输入,xargs 为它运行的应用程序从 /dev/null 重定向 stdin。这导致应用程序只收到 EOF。 (运行 只需 pacman -R SOMEPACKAGE 和按 Ctrl+D 具有相同的效果)。

要使 xargs 与交互式命令一起工作,您必须使用 --arg-file=FILE 参数(简称 -a FILE)。这告诉 xargsFILE 获取参数。这也使 stdin 保持不变。

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

pacman -Q | awk '/xf86-video/{print }' > /tmp/packagelist
xargs -a /tmp/packagelist pacman -R
rm /tmp/packagelist

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

xargs -a <(pacman -Q | awk '/xf86-video/{print }') pacman -R

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

您可以使用单个连字符消除 xargs 的使用

Additionally, if stdin is not from a terminal and a single hyphen (-) is passed as an argument, targets will be read from stdin.
https://archlinux.org/pacman/pacman.8.html

pacman -Q | awk '/xf86-video/{print }' | pacman -R -

可以使用 xargs,但是...

如果您想使用 xargs,请使用它的 -o--open-tty 选项:

--open-tty
-o
Reopen stdin as /dev/tty in the child process before executing the command, thus allowing that command to be associated to the terminal while xargs reads from a different stream, e.g. from a pipe. This is useful if you want xargs to run an interactive application.

 grep -lz PATTERN * | xargs -0o vi  ①

https://www.gnu.org/software/findutils/manual/html_node/find_html/xargs-options.html

那应该是一个大写的 Z grep 选项 (bug filed).

对于您的具体情况:

pacman -Q | awk '/xf86-video/{print }' | xargs -o pacman -R