I have to make a script which prints the sizes of all .conf
files from /etc
recursively in a specified file, and that prints the errors caused by the lack of permission in another file. I don't know how to make it. Any suggestion would be very helpful.

- 117,780
3 Answers
You can use -fprintf
to write output from find
to a file.
$ find /etc -type f,l -name '*.conf' \
-fprintf ~/filelist '%s %p\n' 2> ~/error.log
find options:
-type f,l
Search for regular files and symbolic link.-name
Match the base of the file name with shell match pattern.-fprintf
Like -printf but writes output to a file instead.
fprintf format:
%s
File's size in bytes.%p
File's name (with starting-point included).\n
Newline.
Bash:
[n]>file
Redirect file descriptor [n] to "file".~
Expands to the value of the shell parameter HOME.\
Breaks a up long lines into multiple lines.
-
1Personally I think answer is better without
-L
because it is doubling up on size of/etc/*.conf
files and becomes misleading IMO. I've shown the differences between your answer and my own below. – WinEunuuchs2Unix Nov 17 '19 at 14:54 -
OP seems interested in permissions too. Might want to add
%m
or%M
– glenn jackman Nov 17 '19 at 15:43
As mentioned in comment find
and printf
are your friends on this homework assignment. For a one-liner use:
find /etc -name "*.conf" -printf "%s %p\n" 1>namesize.txt 2>errors.txt
To test the components with output to your screen try out the examples below.
$ 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
This is the short one that shows permission denied. Regular output is redirected to /dev/null
(nowhere) so you get to see only the error messges.
$ 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
This shows the the list of filenamnes and sizes which is too long to print entirely. The four error messages for "Permission denied" are filtered out with 2>/dev/null
redirecting all errors to "nowhere".
Output is piped (using |
) to the column -t
command which pads spaces behind the file sizes in order for the filenames to align in the output.
Compare links to other answer
The other answer shows links like this:
$ 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
The size of the link inherits the size of the file it points to.
My answer shows links like this:
$ 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
The size of the link is the real size of the link (27 bytes).
So it's a question of how your professor/TA/teacher wishes to links reported in the answer. The homework/Lab assignment should have been more specific on how to handle such intricacies of Linux.
To look at the link use:
$ 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

- 102,282
You can use bash
’s globstar
option:
If set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.
Set it with:
shopt -s globstar
After that you can match any .conf
file under /etc
with /etc/{,**/}*.conf
, so now a simple stat
call is enough to solve the task, e. g. for size and filename separated by space:
stat -c '%s %N' /etc/{,**/}*.conf
To redirect the output of that, use >file
for stdout and 2>file
for stderr, e. g.:
stat -c '%s %N' /etc/{,**/}*.conf >~/stdout 2>~/stderr
As the glob doesn’t match any directory for which you don’t have the proper permissions you normally don’t get any permission errors though, but those files are just skipped instead. To list them you can use find
and search for matching files not matching the o+r
permission, i. e. not readable by others:
sudo find /etc -type f -name '*.conf' ! -perm -o+r
Further reading

- 39,982
-
I was thinking a student wouldn't have
sudo
powers but I haven't been in a School's Linux Computer Lab so could not say. – WinEunuuchs2Unix Nov 17 '19 at 14:03 -
-
You can't use "sudo" as per question: "and that prints the errors caused by the lack of permission in another file. " – Rinzwind Nov 17 '19 at 16:44
-
@Rinzwind the question is very unclear in this regard, my
stat
approach does what OP asks for without throwing any permission errors – see last paragraph – dessert Nov 17 '19 at 17:23 -
@Rinzwind I doubt there is actually a way to show permission errors for files in directories you’re not allowed to read – note that the errors
find
reports do not refer to the conf files, but to directoriesfind
can’t access in general, which is not what OP asked for either. Take/etc/sudoers.d
for example, it shows up although irrelevant. – dessert Nov 17 '19 at 18:00
find
. find's-printf
directive can print the file name, size and permissions. – glenn jackman Nov 16 '19 at 19:49find
andprintf
command which is common in Ask Ubuntu. Nor can this be considered Too Broad nor Unclear IMHO. – WinEunuuchs2Unix Nov 17 '19 at 14:41