如何以递归方式打印文件大小并报告权限错误?

如何以递归方式打印文件大小并报告权限错误?

我必须编写一个脚本,以递归方式打印指定文件中所有.conf文件的大小/etc,并打印另一个文件中由于缺少权限而导致的错误。我不知道该怎么做。任何建议都会非常有帮助。

答案1

您可以使用-fprintf将输出写入find文件。

$ find /etc -type f,l -name '*.conf' \
    -fprintf ~/filelist '%s %p\n' 2> ~/error.log

查找选项:

  • -type f,l搜索常规文件和符号链接。
  • -name将文件名的基础与 shell 匹配模式进行匹配。
  • -fprintf喜欢-printf而是将输出写入文件。

fprintf 格式:

  • %s文件的大小(以字节为单位)。
  • %p文件的名称(包含起点)。
  • \n新队。

重击:

  • [n]>file将文件描述符 [n] 重定向至“文件”。
  • ~扩展为 shell 参数 HOME 的值。
  • \将长行拆分为多行。

答案2

正如评论中提到的findprintf你是这个家庭作业上的朋友。一行代码的使用方法如下:

find /etc -name "*.conf" -printf "%s %p\n" 1>namesize.txt 2>errors.txt

要测试在屏幕上输出的组件,请尝试下面的示例。

$ find /etc -name "*.conf" 1>/dev/null
find: ‘/etc/ssmtp’: Permission denied
find: ‘/etc/polkit-1/localauthority’: Permission denied
find: ‘/etc/cups/ssl’: Permission denied
find: ‘/etc/ssl/private’: Permission denied

这是显示权限被拒绝的简短示例。常规输出被重定向到/dev/null(无处),因此您只能看到错误消息。

$ find /etc -name "*.conf" -printf "%s %p\n" 2>/dev/null | column -t
3874   /etc/bluetooth/main.conf
258    /etc/bluetooth/proximity.conf
397    /etc/bluetooth/input.conf
  (... SNIP ...)
1366   /etc/at-spi2/accessibility.conf
13592  /etc/openal/alsoft.conf
1800   /etc/cracklib/cracklib.conf

这将显示文件名和大小的列表,该列表太长,无法全部打印出来。“权限被拒绝”的四个错误消息被过滤掉,并将2>/dev/null所有错误重定向到“无处”。

输出通过管道(使用|)传输到column -t命令,该命令在文件大小后面填充空格,以便文件名在输出中对齐。


比较链接其他答案

另一个答案显示如下链接:

$ find -L /etc -type f -name '*.conf' -fprintf ~/filelist '%s %p\n' 2> ~/error.log
$ grep 45-latin.conf ~/filelist | column -t
4621  /etc/fonts/conf.d/45-latin.conf
4621  /etc/fonts/conf.avail/45-latin.conf

链接的大小继承了它指向的文件的大小。

我的回答显示如下链接:

$ find /etc -name "*.conf" -printf "%s %p\n" 1>namesize.txt 2>errors.txt
$ grep 45-latin.conf namesize.txt | column -t
27    /etc/fonts/conf.d/45-latin.conf
4621  /etc/fonts/conf.avail/45-latin.conf

链接的大小是链接的实际大小(27字节)。

所以,问题在于你的教授/助教/老师希望如何在答案中报告链接。家庭作业/实验室任务应该更具体地说明如何处理 Linux 的这种复杂性。

要查看链接,请使用:

$ ll /etc/fonts/conf.d/45-latin.conf
lrwxrwxrwx 1 root root 27 Aug  2  2018 /etc/fonts/conf.d/45-latin.conf -> ../conf.avail/45-latin.conf

答案3

您可以使用bashglobstar选项:

如果设置,路径名扩展上下文中使用的模式 ** 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟 /,则仅匹配目录和子目录。

设置如下:

shopt -s globstar

之后,您可以将任何.conf文件/etc与进行匹配/etc/{,**/}*.conf,因此现在一个简单的stat调用就足以解决任务,例如,对于用空格分隔的大小和文件名:

stat -c '%s %N' /etc/{,**/}*.conf

要重定向其输出,请使用>filestdout 和2>filestderr,例如:

stat -c '%s %N' /etc/{,**/}*.conf >~/stdout 2>~/stderr

由于 glob 不匹配任何您没有适当权限的目录,因此您通常不会收到任何权限错误,但这些文件会被跳过。要列出它们,您可以使用find并搜索匹配的文件不是匹配o+r权限,即其他人无法读取:

sudo find /etc -type f -name '*.conf' ! -perm -o+r

进一步阅读

相关内容