我必须编写一个脚本,以递归方式打印指定文件中所有.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
正如评论中提到的find
,printf
你是这个家庭作业上的朋友。一行代码的使用方法如下:
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
您可以使用bash
的globstar
选项:
如果设置,路径名扩展上下文中使用的模式 ** 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟 /,则仅匹配目录和子目录。
设置如下:
shopt -s globstar
之后,您可以将任何.conf
文件/etc
与进行匹配/etc/{,**/}*.conf
,因此现在一个简单的stat
调用就足以解决任务,例如,对于用空格分隔的大小和文件名:
stat -c '%s %N' /etc/{,**/}*.conf
要重定向其输出,请使用>file
stdout 和2>file
stderr,例如:
stat -c '%s %N' /etc/{,**/}*.conf >~/stdout 2>~/stderr
由于 glob 不匹配任何您没有适当权限的目录,因此您通常不会收到任何权限错误,但这些文件会被跳过。要列出它们,您可以使用find
并搜索匹配的文件不是匹配o+r
权限,即其他人无法读取:
sudo find /etc -type f -name '*.conf' ! -perm -o+r