Apache produces log files (i.e. httpd.log
). After a given time, log files are rolled over (i.e into httpd.log-20210627
). When a log file is rolled over again, the previous rolled over version is compressed (i.e. into httpd.log-20210620.gz
).
As root, I can list all these files.
[root@server user]# ls -latr /var/log/httpd/localhost/httpd.log*
-rw-r--r-- 1 root root 9364779 6. Jun 03:48 /var/log/httpd/localhost/httpd.log-20210606.gz
-rw-r--r-- 1 root root 8407071 13. Jun 03:27 /var/log/httpd/localhost/httpd.log-20210613.gz
-rw-r--r-- 1 root root 7099637 20. Jun 03:35 /var/log/httpd/localhost/httpd.log-20210620.gz
-rw-r--r-- 1 root root 91551338 27. Jun 03:45 /var/log/httpd/localhost/httpd.log-20210627
-rw-r--r-- 1 root root 49229622 30. Jun 17:28 /var/log/httpd/localhost/httpd.log
[root@server user]#
Using bash
, I'd like to print the content of all log files, in temporal order, as an otherwise unprivileged user (that is: using sudo
, not in a root shell), so I can, for example, grep through them.
Printing the content of the current log file is easy, because it has a fixed filename:
sudo cat /var/log/httpd/localhost/httpd.log
Printing the content of the compressed log files is almost as easy, because I can write a pattern that matches all relevant compressed files and use zcat
to print the uncompressed content:
sudo su - -c "zcat /var/log/httpd/localhost/httpd.log-*.gz"
But so far I couldn't figure out how to print the content of the rolled over but not yet compressed log file. This is because I don't know the actual filename and a pattern like /var/log/httpd/localhost/httpd.log*
will match all the compressed files as well.
According to the documentation, I can make use of more complex patterns, when I enable extglob
:
If the
extglob
shell option is enabled using theshopt
builtin, several extended pattern matching operators are recognized. [][…]
+(pattern-list)
Matches one or more occurrences of the given patterns.
According to this answer, I need to use a subshell, If I want to enable extglob
in a single command. And indeed, this works as expected in a root shell. Executing shopt -s extglob
and then cat /var/log/httpd/localhost/httpd.log-+([0-9]) )
prints the content of the log file in question.
Outside of a root shell, however, I get an error:
[user@server ~]$ sudo su - -c "( shopt -s extglob ; cat /var/log/httpd/localhost/httpd.log-+([0-9]) )"
-bash: -c: line 0: syntax error near unexpected token `('
-bash: -c: line 0: `( shopt -s extglob ; cat /var/log/httpd/localhost/httpd.log-+([0-9]) )'
[user@server ~]$
This is the same error that I get when I try to execute cat /var/log/httpd/localhost/httpd.log-+([0-9])
in the root shell without enabling extglob
. I'm not sure why this doesn't work, because enabling extglob
appears to be working in the given circumstances:
[user@server ~]$ sudo su - -c "( shopt -s extglob ; shopt extglob )"
extglob on
[user@server ~]$
So I'd like to know how I can print the content of a file with an unknown filename outside of a root shell, when I need extglob
to write the pattern. But this may be an xy-problem, so my actual question is:
How can I print the content of all of Apache's log files outside of a root shell.