1

I'm building a LAMP server for multiple users to practice web development using mod_userdir, and have written scripts to break out the access and error logs to log directories within the user's home directories.

The access_log.sh script is working fine (log lines get written both to the main server log file, and the user's log file), but error_log.sh is only updating the main log file. This is error_log.sh:

#!/bin/bash

IFS='
'

userlogfile=error.log
syslogfile=/var/log/apache2/cs-web_error.log

homedirs=`ls -d /home/*`

while read logline; do
    echo -e ${logline} >> ${syslogfile}
    #echo -e "writing ${logline} to ${syslogfile}" #TESTING

    for homedir in $homedirs; do
        userlogpath="${homedir}/logs/${userlogfile}"
        if echo $logline | grep ${homedir} > /dev/null; then
            echo -e ${logline} >> ${userlogpath}
            #echo -e "writing ${logline} to ${userlogpath}" #TESTING
        fi
    done
done

The logging config for Apache is:

CustomLog "| ${APACHE_LOG_DIR}/access_log.sh" common
ErrorLog "| ${APACHE_LOG_DIR}/error_log.sh"

If I uncomment the #TESTING statements, I get output like this when piping the error log through the script:

writing [Fri Sep 06 12:15:11 2013] [error] [client 193.61.230.178] PHP Parse error:
syntax error, unexpected 'select' (T_STRING) in /home/ginny/htdocs/test.php on line 12 
to /var/log/apache2/cs-web_error.log
writing [Fri Sep 06 12:15:11 2013] [error] [client 193.61.230.178] PHP Parse error:  
syntax error, unexpected 'select' (T_STRING) in /home/ginny/htdocs/test.php on line 12 
to /home/ginny/logs/error.log

... which shows that the grep statement is working. Also, running manually like this, the file is created and written to:

root@cs-web:~# ls -l /home/ginny/logs/
total 16
-rw-r--r-- 1 root root 2213 Sep  6 12:53 access.log
-rw-r--r-- 1 root root 9984 Sep  6 12:49 error.log

What I'm struggling to understand is why this works for the access log, and not for the error log - the only differences are:

root@cs-web:/var/log/apache2# diff access_log.sh error_log.sh
6,7c6,7
< userlogfile=access.log
< syslogfile=/var/log/apache2/cs-web_access.log
---
> userlogfile=error.log
> syslogfile=/var/log/apache2/cs-web_error.log
12a13
>     #echo -e "writing ${logline} to ${syslogfile}"
15,17c16,17
<         homedir=${homedir#/home/}
<         userlogpath="/home/${homedir}/logs/${userlogfile}"
<         if echo $logline | egrep "/(~|users/)${homedir}/" > /dev/null; then
---
>         userlogpath="${homedir}/logs/${userlogfile}"
>         if echo $logline | grep ${homedir} > /dev/null; then
18a19
>             #echo -e "writing ${logline} to ${userlogpath}"

Suggestions gratefully received.

1 Answer 1

1

Quote your variables properly and use arrays instead. readarray is also better than depending on word splits and possible generation through pathname expansion.

#!/bin/bash

#IFS=$'\n'  ## No longer needed.

userlogfile=error.log
syslogfile=/var/log/apache2/cs-web_error.log

readarray -t homedirs < <(ls -d /home/*)

while read logline; do
    echo -e "${logline}" >> "${syslogfile}"
    #echo -e "writing ${logline} to ${syslogfile}" #TESTING

    for homedir in "${homedirs[@]}"; do
        userlogpath="${homedir}/logs/${userlogfile}"
        if echo "$logline" | grep "${homedir}" > /dev/null; then
            echo -e "${logline}" >> "${userlogpath}"
            #echo -e "writing ${logline} to ${userlogpath}" #TESTING
        fi
    done
done

But if your version is earlier than 4.0, then just use the other method:

IFS=$'\n'
homedirs=($(ls -d /home/*))

I suggest that you also use the same concept with the other script for safety.

UPDATE

In your second script you no longer tried to trim $homedir with /home/ which means it's possible that if "$homedir" doesn't begin with /home/, $userlogpath would be <user>/logs/${userlogfile}", whereas in your first script it would still be /home/<user>/logs/${userlogfile}. Try to use these lines in your error_log.sh as well.

     homedir=${homedir#/home/}
     userlogpath="/home/${homedir}/logs/${userlogfile}"
Sign up to request clarification or add additional context in comments.

1 Comment

Oh me of little faith - sorry about the earlier doubt, konsolebox - I tried your changes, and it's working. Have to say I don't really understand why that solves the problem, but it does. Than you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.