我正在为多个用户构建一个LAMP服务器,使用mod_userdir练习Web开发,并编写脚本来分解访问和错误日志以记录用户主目录中的目录。
access_log.sh脚本工作正常(日志行写入主服务器日志文件和用户的日志文件),但error_log.sh只更新主日志文件。这是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
Apache的日志配置是:
CustomLog "| ${APACHE_LOG_DIR}/access_log.sh" common
ErrorLog "| ${APACHE_LOG_DIR}/error_log.sh"
如果我取消注释#TESTING语句,在通过脚本管道错误日志时,我得到这样的输出:
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
...这表明grep语句正在运行。此外,像这样手动运行,文件被创建并写入:
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
我很难理解为什么这适用于访问日志,而不适用于错误日志 - 唯一的区别是:
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}"
感谢收到的建议。
答案 0 :(得分:1)
正确引用您的变量并改为使用数组。 readarray
也比依赖单词拆分和通过路径名扩展可能生成更好。
#!/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
但如果您的版本早于4.0,那么只需使用其他方法:
IFS=$'\n'
homedirs=($(ls -d /home/*))
我建议你也使用与其他脚本相同的概念来保证安全。
<强>更新强>
在您的第二个脚本中,您不再尝试使用$homedir
修剪/home/
,这意味着如果"$homedir"
不以/home/
开头,{{1}将是$userlogpath
,而在你的第一个脚本中,它仍然是<user>/logs/${userlogfile}"
。尝试在/home/<user>/logs/${userlogfile}
中使用这些行。
error_log.sh