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,lSearch for regular files and symbolic link.-nameMatch the base of the file name with shell match pattern.-fprintfLike -printf but writes output to a file instead.
fprintf format:
%sFile's size in bytes.%pFile's name (with starting-point included).\nNewline.
Bash:
[n]>fileRedirect 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
-Lbecause it is doubling up on size of/etc/*.conffiles 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
%mor%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
sudopowers 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
statapproach 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
findreports do not refer to the conf files, but to directoriesfindcan’t access in general, which is not what OP asked for either. Take/etc/sudoers.dfor example, it shows up although irrelevant. – dessert Nov 17 '19 at 18:00
find. find's-printfdirective can print the file name, size and permissions. – glenn jackman Nov 16 '19 at 19:49findandprintfcommand which is common in Ask Ubuntu. Nor can this be considered Too Broad nor Unclear IMHO. – WinEunuuchs2Unix Nov 17 '19 at 14:41