Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have created the alias below in my .bash_aliases file

alias auth="grep \"$(date|awk '{print $2,$3}')\" /var/log/auth.log |
            grep -E '(BREAK-IN|Invalid user|Failed|refused|su|Illegal)'"

This is supposed to:

  • check todays date
  • grep auth.log for todays messages
  • grep todays messages for warning messages matching particular strings

However, it only works when there's a 2-digit day because days numbered <10 do not have a preceding zero.

For example, I run date and pipe the result to awk. date outputs Sat Jan 1 04:56:10 GMT 2011 and then awk captures $2 and $3 and feeds them into grep as follows

Jan 1

However, when there's a single digit day, messages in auth.log appear as follows

Jan  1 00:44:57 linux su[21249]: pam_unix(su:session): session closed for user root

So there are two spaces following Jan in the auth.log but only one space following Jan in my grep command

How can I modify the command to allow for the additional space?

share|improve this question
add comment

1 Answer

up vote 7 down vote accepted

Rather than using date | awk ..., you can use a format specifier with the date command for the format you want. According to the date(1) man page, %b is the abbreviated month name, and %e is the day of month, space padded, same as %_d.

The following date command should give you a string in the form you want:

date "+%b %e"

You can also put other characters into the format specifier, so if you use:

date "+^%b %e"

you'll get a grep pattern that matches the date only at the beginning of the line. This would prevent any false matches where there is a date in the message part of the log.

As pointed out by Steven D, you can also do this with a single invocation of grep:

auth()
{
    grep -E "$(date '+^%b %e')"'.*(BREAK-IN|Invalid|user|Failed|refused|su|Illegal)' /var/log/auth.log
}

I've made a few changes based on issues mentioned in comments related to quoting. My rules for quoting are to use single quotes when grouping separate words into a single word and to protect against shell expansion of metacharacters, and to use double quotes only when you want to expansion inside a multi-word string.

The original answer had the date format string in double quotes, which was wrong according to my above rules. I've now changed that. An edit put the grep string into double quotes. I've put it back into single quotes because there is so often an overlap between shell metacharacters and grep regular expression (RE) metacharacters that you almost always want to single-quote REs to grep. The current string may not need single quotes but if this shell function evolves over time, it may break with future changes.

Because the question was asking about a command to put inside an alias, there was an additional level of quoting that was not shown in this answer. It would be simpler to use a shell function instead of an alias so you don't need to deal with this extra level of quoting. Nested quoting can get messy quickly, so anything you can do to avoid it, you should do.

I have tested this as a shell function, using Gilles suggestion for futzing the date and it "works for me".

share|improve this answer
1  
You can also reduce the calls to grep to 1. –  Steven D Jan 15 '11 at 5:40
    
@Steven D: that's right. I'm in the process of testing an edit that does that. I'll add it to the answer. –  camh Jan 15 '11 at 5:43
    
This isn't actually working, I'll play around with it. The first section works but the piece contained in the single-quotes doesn't, even if I replace 'BREAK-IN...Illegal' with 'Jan' –  conorgriffin Jan 15 '11 at 12:41
1  
I've edited the post a bit to fix the quoting. The version I've posted works for me. –  Steven D Jan 15 '11 at 16:25
2  
@camh: Under Linux, you can use date -d '10 days ago' '+^%b %e' to test. –  Gilles Jan 15 '11 at 23:26
show 5 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.