Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 后续调用';rm-rf';不在'工作;对于';环_Bash - Fatal编程技术网

Bash 后续调用';rm-rf';不在'工作;对于';环

Bash 后续调用';rm-rf';不在'工作;对于';环,bash,Bash,我想删除由find找到的几个文件夹。此脚本仅在的中的第一个循环中运行良好。echo显示循环工作正常,但在第二个和后续循环中未执行rm-rf$f folder=`find /seriem/docs/it/ -name '*.printed' -printf '%h\n'` for f in $folder do echo "rm -rf $f" rm -rf $f done 在我的例子中,调试输出是: rm -rf /seriem/docs/it/afp/PC_58 rm -r

我想删除由
find
找到的几个文件夹。此脚本仅在的
中的第一个循环中运行良好。
echo
显示循环工作正常,但在第二个和后续循环中未执行
rm-rf$f

folder=`find /seriem/docs/it/ -name '*.printed' -printf '%h\n'`

for f in $folder
do
    echo "rm -rf $f"
    rm -rf $f
done
在我的例子中,调试输出是:

rm -rf /seriem/docs/it/afp/PC_58
rm -rf /seriem/docs/it/afp/PC_59
rm -rf /seriem/docs/it/afp/PC_60
但仅删除文件夹PC_58

对不起,如果我在这篇文章中做错了什么。。。这是我第一次使用stackoverflow;)

工作解决方案:

for f in $(find /seriem/docs/it.nrw/ -name '*.printed' -printf '%h\n');
do
    echo "rm -r $f"
    rm -r -v "$f" 

    #do some other stuff. This is why I need a loop
done
希望我现在就做了;)
谢谢你的快速帮助

f美元应该用引号括起来

rm -rf "$f" 
而不是

rm -rf $f
这样更安全


编辑:@Kamil Cuk击败了我

你根本不需要循环。使用
-exec

find /seriem/docs/it/ \
     -name '*.printed' \
     -exec sh -c 'rm -rf "$(basename "$1")"' _ {} \;
为了避免每次调用
rm
都会产生一个单独的shell,在该shell中放置一个循环来迭代shell的参数,并使用
-exec+表单以向每个shell传递尽可能多的文件

find ... -exec sh -c 'for f; do rm -rf "$(basename "$f")"; done' _ {} +

任何一种方法都可以确保文件名在传递到
rm

之前正确引用。您可以让
find
以安全的方式处理整个删除过程:

#/usr/bin/env/bash
查找/seriem/docs/it/-regex'/seriem/docs/it/*\.打印\(/.*\)?'-删除
/seriem/docs/it/
查找拆分的参数:
  • find
    :命令
  • /seriem/docs/it/
    :启动搜索的基本目录
  • -regex'/seriem/docs/it/*\.printed\(/.*\)?'
    :应用于整个路径的regex模式:
    • /seriem/docs/it/
      :路径以该文本开头
    • *
      :任何字符的任意数字
    • \.打印的
      :文字
      。打印的
    • \(/.*\)?
      :可选的
      /
      组,后跟任何字符
  • -删除
    :删除找到的/匹配的文件

如果目的是在找到匹配项时删除整个包含目录

find/seriem/docs/it/-name'*.printed'-execdir rm-rf{}\;

这个脚本太危险了。不要使用反勾号,它们已被弃用。总是,总是引用你的变量。永远不要
rm-rf$f
,而是始终
rm-rf“$f”
。你可以做
rm-v
ans看看它在做什么。为什么要将
-f
/force与
rm
一起使用?请使用
$(…在此处生成输出的cmds)提供的“现代”命令替换,而不是反勾号否则,一个非常好的第一个问题。我看不出为什么它不起作用。如果您在MS Windows计算机附近创建了脚本,则
dos2unix myScript
可能会有所帮助。祝你好运。@Kamil Cuk-我怀疑你能证明你的自欺欺人的说法,即backticks`……不受欢迎。根据这是旧式的反报价表,因此它有style.off-hand,我的第一个猜测是,在PC_59和PC_60下面,由于权限或其他原因,您不能
rm
;但对于诊断,我的第一个问题是:脚本的后续运行会发生什么?第二次运行是否仅删除PC_59?第三次运行删除PC_60?或PC_59和PC_60从未删除?这个问题的答案会告诉你下一件事investigate@Armali但是反勾号有一个客观的缺点,即需要对嵌套引号进行转义,其中as
$()
创建了一个新的引用上下文:引用还需要从调用
\n
中删除
\n
;这是不必要的,shell在未加引号的参数扩展上进行分词时会将其剥离。
rm-rf--“$f”
:始终以
--
结束选项,以防止以破折号开头的变量内容像选项一样被处理。不需要shell和
basename
调用<代码>rm
对绝对路径没有问题。简单地
-exec rm-rf{}+
更简单。我会添加
-depth
,以避免试图删除已经删除的目录。
rm-rf--
:始终以
--
结束选项,以防止以破折号开头的变量内容像选项一样被处理。@LéaGris通常是正确的,但是考虑到所涉及的
find
命令,传递给shell的任何参数都不可能以连字符开头(它们都以
/seriem/docs/it
开头)。请记住,并非所有版本的
find
都支持
-regex
-delete