无法使用 rm 内置提示选项 -i 和 xargs 来提示用户并查找

无法使用 rm 内置提示选项 -i 和 xargs 来提示用户并查找

我在用参数R M寻找为了删除遵循 find 定义的特定模式的文件,如下所示:

touch file
find . -name file | xargs rm

上面的代码一切正常,但如果我输入 rm 的 -i 选项,然后执行:

touch file
find . -name file | xargs rm -i

印刷:

rm:删除常规空文件“./file7”?用户@主机:$

不让我输入 y 或 n。因此该文件不会被删除。

这里有什么问题?

我还知道 xargs -p 参数有效,但它更通用。即提示用户执行特定的命令,不方便用户操作。

编辑:在 shell 脚本中使用它时,我发现它执行了我想要的命令,但它也打印了 find 的结果,这是不可取的。

另外,当我将ls file2命令传递给 cmd 变量时,它不会专门打印 file2 的规格。当我输入时也会发生同样的事情 rm -i file2。它提示我删除目录中的每个文件。

这是我的脚本:

#!/bin/bash
touch file{1..9}      # Create 9 files named file1,file2...file9
echo -n 'command: '  # Prompt user
read -e cmd             # read command
find . -exec ${cmd} '{}' +  

我能想到的唯一解决方案是单独提示用户选择他们喜欢的模式。然后将该模式存储到一个变量并将其作为参数传递给寻找命令的-姓名选项。

像这样的东西:

#!/bin/bash
touch file{1..9}     # Create 9 files named file1,file2...file9
echo -n 'command: '  # Prompt user for command
read -e cmd          # read command
echo -n 'pattern: '  # Prompt user for pattern
read -e pattern
find . -name "$pattern" -exec ${cmd} '{}' +  

但即使有了这个解决方案,寻找的输出仍会被打印,并且如果模式字段留空(即,用户只是不想使用模式),那么就会出现问题。

有任何想法吗?

答案1

xargs 从 stdin 读取数据。当您使用rm -irm 时,还会尝试从 stdin 读取答案( try touch test && echo y | r -i test ; ls test),但 stdin 被 xargs 关闭(我假设),因此 rm 的反应就像您在提示符下按了 ctrl-d 一样。

另一个解决方案可能是 find 的 -exec 选项:

touch test
find . -name test -exec rm -i {} \;

答案2

您可以使用POSIX -ok选项find让它询问您是否继续执行命令(除了提示之外,它就像-exec

touch file
find . -name 'file' -ok rm -f {} \;

输出

< rm ... ./file > ? _

答案3

这里的问题是,从(在本例中)stdin运行的命令的(标准输入)从重定向,并且是用于获取用户确认的文件描述符。xargsrm/dev/nullstdinrm

您可以使用该-a选项,以便 rm 从先前由 find 命令生成的中间文件中获取文件列表(该-a选项使xargs不受影响stdin),无论如何,我知道这可能不是您真正想要的,因为它需要中间文件。可以使用以下命令获得与您想要的类似的更直接的方法:

for i in $(find . -name file); do rm -i "$i"; done

答案4

我遇到了类似的问题,当命令出现时我感到很惊讶

find . -type f -name "*.txt" | xargs rm

意外删除了与该模式匹配的只读文件。

后来我才在man page中找到了解释rm

如果文件不可写,标准输入是终端,并且未给出 -f 或 --force 选项,或者给出了 -i 或 --interactive=always 选项,则 rm 会提示用户是否删除该文件。

获得提示的条件之一是标准输入是终端,当您将另一个命令的输出通过管道传输到rm.

重要教训:如果 stdin 不是终端,rm将删除只读文件,而不会发出任何警告!

就我而言,解决方案是将find命令修改为仅返回可写文件:

find . -type f -writable -name "*.txt" | xargs rm

相关内容