使用 ls -ld 和 find 仍然会打印出目录中的文件

使用 ls -ld 和 find 仍然会打印出目录中的文件

我使用 find 列出具有给定 UID 和 GID 的所有文件。我将文件列表存储在临时文件中,因为我需要打印出该文件集的不同属性。这些属性之一是具有安装 GID 的文件。我将临时文件的内容放入一个数组中:

a=$( < $tmpfile)

对于 cups 包,tmpfile 的内容如下:

/usr/share/cups
/usr/share/cups/banners
/usr/share/cups/data
/usr/share/cups/doc-2.2.6
/usr/share/cups/doc-2.2.6/apple-touch-icon.png
/usr/share/cups/doc-2.2.6/cups.css
/usr/share/cups/doc-2.2.6/cups-printable.css
/usr/share/cups/doc-2.2.6/de
/usr/share/cups/doc-2.2.6/de/index.html
/usr/share/cups/doc-2.2.6/es
/usr/share/cups/doc-2.2.6/es/index.html
/usr/share/cups/doc-2.2.6/help
/usr/share/cups/doc-2.2.6/help/accounting.html
/usr/share/cups/doc-2.2.6/help/api-admin.html
/usr/share/cups/doc-2.2.6/help/api-filter.html
/usr/share/cups/doc-2.2.6/help/api-ppd.html
/usr/share/cups/doc-2.2.6/help/api-raster.html
/usr/share/cups/doc-2.2.6/help/cgi.html
/usr/share/cups/doc-2.2.6/help/cupspm.html
/usr/share/cups/doc-2.2.6/help/encryption.html

等等 ....

然后像这样搜索数组:

echo "files with group install"
for file in ${a[@]}; do
  find $file -type f -user $userid -group install -exec ls -l {} \;
  find $file -type d -user $userid -group install -exec ls -ld {} \;
done

此处的第二个查找打印出该目录下的文件,因此具有安装 GID 的任何子目录都会打印两次。尽管存在 ls -ld,但仍然如此。所以杯子的结果看起来像:

drwxrwxr-t 16 cups install 4096 Dec  1 17:28 /usr/share/cups
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/ppdc
drwxrwxr-t 2 cups install 4096 Dec  1 17:21 /usr/share/cups/model
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/banners
drwxrwxr-t 3 cups install 4096 Dec 13 16:53 /usr/share/cups/drv
drwxrwxr-t 2 cups install 4096 Dec 13 16:53 /usr/share/cups/mime
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/data
drwxrwxr-t 2 cups install 4096 Dec  1 17:26 /usr/share/cups/usb
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/banners
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/data
drwxrwxr-t 3 cups install 4096 Dec 13 16:53 /usr/share/cups/drv
drwxrwxr-t 2 cups install 4096 Dec 13 16:53 /usr/share/cups/mime
drwxrwxr-t 2 cups install 4096 Dec  1 17:21 /usr/share/cups/model
drwxrwxr-t 2 cups install 4096 Dec  1 17:28 /usr/share/cups/ppdc
drwxrwxr-t 2 cups install 4096 Dec  1 17:26 /usr/share/cups/usb

我知道 find 是递归的,但它肯定应该遵守 exec 命令并只打印目录的长形式。

for (( i=0; i<${#a[@]}; i++ )); do
#    for file in ${a[@]}; do
 find ${a[i]} -user $userid -group install -type f -exec ls -l {} \;
 find ${a[i]} -user $userid -group install -type d -exec ls -ld {} \;
done

给出相同的结果。

答案1

find $file -type d -user $userid -group install -exec ls -ld {} \;

这将递归到$file,并ls -ld在其中的所有目录上运行。因此,如果您循环的列表也包含子目录,您将再次获得它们。首先从find主目录开始递归,然后每次列出子目录。

比较:

$ mkdir -p dir1/subdir
$ for f in dir1 dir1/subdir ; do find "$f" -type d -exec ls -1d {} \; ; done
dir1
dir1/subdir
dir1/subdir

我不太确定您想在这里做什么,仅列出当前正在处理的文件(在 中),您根本$file不需要,只是应该这样做。不过,如果您仅用于打印给定用户拥有的文件,则可以使用以防止递归。完全没有。findls -ld $filefind-maxdepth 0find

$ for f in dir1 dir1/subdir ; do find "$f" -maxdepth 0 -type d -exec ls -1d {} \; ; done
dir1
dir1/subdir

但后来我想知道是否最好找到所有文件所在的目录/-ies(/usr/share/cups此处)并在其上运行find -user ... -group ... -exec ls -ld {} +


至于a,赋值a=$( < $tmpfile)只是将一个字符串分配给a。在 shell 中与 相同a[0],并且${#a[@]}也只是返回,1因为标量在某种意义上是单元素数组。要使其成为一个实际的数组,您需要分配a=( $(< $tmpfile) ),但这只会使空白的分割更早发生。

您可能想使用while read ...读取输入文件来代替。看Bash常见问题解答 001

相关内容