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'm on FreeBSD's csh. I want to form a row with domains of one user and then use this row to filter exim maillog to get only mail from/to this user's domains.

I wrote a script to form a row from a list of DirectAdmin-domains:

#!/bin/sh
user="some-user"

    list=$(cat /usr/local/directadmin/data/users/$user/domains.list)
    domaincount=$(echo $list|wc -w)
    echo $list| tr ' ' '|'

Executing this script returns rows with domains like this: 'domain.com' or this: 'domain1.com|domain2.net'

Now I want to use this as an argument to grep, but

cat /var/log/exim/mainlog |egrep `/path/to/rowscript`

returns nothing, while replacing manually /path/to/rowscript with its result returns what I want to see.

Tried to use

grep -E "`/path/to/rowscript`", 
egrep '`/path/to/rowscript`' 
egrep `/bin/sh /path/to/rowscript`
egrep $(/path/to/rowscript)
    getting "Illegal variable name."

etc., but still no luck.

BTW, date in backticks works well:

cat /var/log/exim/mainlog | grep `date +%Y-%m-%d`

What am I doing wrong?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

Your script should not output single quotes. When you write

egrep 'foo|bar'

the single quotes are part of the shell syntax. They protect the characters inside them against expansion. If single quotes appear in the output of your script, they'll be taken as ordinary characters. Simply omit them.

There's a far easier way to write your script: replace newlines by pipe symbols, and remove the last one.

list=$(</usr/local/directadmin/data/users/$user/domains.list tr '\n' '|')
echo "${list%|}"

You don't need to do that if you're looking for a fixed set of strings. Instead, use the -F option to grep to tell it to look for fixed strings, and the -f option to tell it to read a list of patterns from a file.

grep -Ff /usr/local/directadmin/data/users/bob/domains.list

Note that if you have domain.com in that file, the search will also return hits for longer strings such as otherdomain.com. So you may want to use your script to build a pattern that has anchors at the beginning and at the end, so avoid spurious matching. I don't know what kind of punctuation the exim log has; for example, if the names are surrounded by whitespace, you'd want something like

#!/bin/sh
list=$(</usr/local/directadmin/data/users/$1/domains.list tr '\n' '|')
echo " (${list%|}) "

and call it as

</var/log/exim/mainlog grep -E `/path/to/rowscript bob`

Or make the script call grep:

#!/bin/sh
shift
list=$(</usr/local/directadmin/data/users/$1/domains.list tr '\n' '|')
grep -E " (${list%|}) " -- "$@"

called as

</var/log/exim/mainlog /path/to/rowscript bob
share|improve this answer
    
1) I've already tested a script, that I posted first and simplified it. 2) Simply omit them. Okay, I tried to omit them earlier and now too. Then I added ticks to egrep '/script/row' and still have no luck 3) Thanks for grep -Ff! It works pretty good. –  Drey Nov 13 '11 at 20:14
    
@Drey Your revised version still has single quotes: change echo "'"$list"'" to echo "$list". –  Gilles Nov 13 '11 at 20:30
    
I removed these quotes from script already, but still can't use script output as a filter –  Drey Nov 13 '11 at 20:49
    
@Drey What does your input file look like? What does your script's output look like (and what version of your script are you using, you've made several changes and I've lost track)? –  Gilles Nov 13 '11 at 20:52
1  
@Drey Again, drop the single quotes: … | grep -E `/scripts/domainsrow` See Difference between ' and " on command line (bash)? (but note that csh has different rules, so also read the csh manual). –  Gilles Nov 13 '11 at 21:29

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.