可以使用 ls 访问目录,但不能通过 Bash 访问

可以使用 ls 访问目录,但不能通过 Bash 访问

我的服务器上有一群不守规矩的邮件帐户用户。他们从不清空垃圾文件夹,文件数量无限增加。

我正在创建一个 Bash 脚本,以使用 cron 定期删除这些文件。

我已经这样做了:

  1. 创建一个 txt 文件,其中包含我想要删除的目录列表;
  2. 创建一个脚本,逐行读取每个目录并删除cur和中的所有内容new

txt文件示例:

~/mail/.Junk/cur
~/mail/.Junk/new
~/mail/.Trash/cur
~/mail/. Trash/new
~/mail/[email protected]/.Junk/cur
~/mail/[email protected]/.Junk/new
~/mail/[email protected]/.Trash/cur
~/mail/[email protected]/.Trash/new
~/mail/[email protected]/.Junk/cur
~/mail/. [email protected]/.Junk/new
~/mail/. [email protected]/.Trash/cur
~/mail/. [email protected]/.Trash/new

我正处于脚本创建的第一阶段,正在测试是否可以访问目录并列出其内容。

所以我有这个脚本:

#!/bin/bash 

while read line 
do 
ls $line
done < ~/directories.txt 

当我运行脚本时出现以下错误:

ls:无法访问 ~/mail/[电子邮件保护]/.Junk/new/:没有此文件或目录

对于所有目录,但是如果我输入

ls ~/mail/[email protected]/.Junk/new/

它工作正常。

为什么?

答案1

引用你的变量!

while read line然后这样做ls $line是行不通的;您必须使用ls "$line"来处理变量中的空格。通常,使用变量时要用引号括起来!

如果你不这样做,那么当你rm $line试图

~/mail/. Trash/new

然后如果你这样做了ls $line,它会尝试列出两个文件夹:

  • ~/mail
  • Trash/new

在最坏的情况下,如果你做了rm -rf $line你会完全~/mail删除!因此,ls "$line"在循环内使用。对 也一样rm

事实上,逐行读取文件并正确处理空格的最可靠方法是这里解释

while IFS= read -r line; do
    ls "$line"
done < "$file"

-r可以防止反斜杠被扩展,并且IFS=在行以空格开始或结束时有所帮助,否则 shell 会修剪它。

不要使用需要扩展的路径!

如果您的文本文件包含稍后才会扩展的路径,则路径将根据谁在何处执行脚本而变化。这里,~将在执行时扩展为用户的主路径,因此如果您以 身份运行脚本root,它将从 开始/root,而不是从创建文本文件时的用户主路径开始。

因此,请将完整路径存储在您的文件中。

相关内容