Write only changes to file - avoid duplicates


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Write only changes to file - avoid duplicates
# 1  
Old 12-28-2018
Write only changes to file - avoid duplicates

I want to create a file, to save a list of fail2ban blocked ip addresses. So I thought I'd create a loop that will check with fail2ban every minute, and write the ip addresses to a file.

Code:
while true; do echo $(fail2ban-client status asterisk-iptables | grep 'IP list' | sed 's/.*://g' | sed -e 's/^[ \t]*//') | tee -a ~/ips; sleep 60; done

I used tee -a to append, not re-write the file every minute. Of course the problem with this approach is that ~/ips is filled with duplicates every minute.

Is there a way to tell tee not to write an ip address in the file, if it already exists? Of course there's a good chance my whole approach is completely wrong, so I'm open to suggestions.

Thanks
# 2  
Old 12-28-2018
Quote:
Originally Posted by aristosv
Is there a way to tell tee not to write an ip address in the file, if it already exists?
No. The reason is that tee doesn't work on "lines" or "words" or anything like that: it works on data streams (redirections) and what is in these streams is of no concern to tee.

Quote:
Originally Posted by aristosv
Of course there's a good chance my whole approach is completely wrong, so I'm open to suggestions.
I don't know with how much data we are dealing here, so i just hope my suggestions will not be outright unfeasible. Instead of writing the list directly to the file you could write a program which checks one line after the other if it is already there and write it only if it is not. This program would get the output of your command as input. You could write to a named pipe instead of a file. To be honest i found at least two questionable points in your program:

Code:
while true; do echo $(fail2ban-client status asterisk-iptables | grep 'IP list' | sed 's/.*://g' | sed -e 's/^[ \t]*//') | tee -a ~/ips; sleep 60; done

First: the calls to sed and grep could be combined:

Code:
while true; do echo $(fail2ban-client status asterisk-iptables | sed -n '/IP list/ {;s/.*://g'; s/^[ \t]*//;p;}') | tee -a ~/ips; sleep 60; done

Second, what exactly do you need the tee at all for? It makes two datastreams out of one, so that you can process it two times insteead of one (actually this is where the name comes from - the "t-piece" which plumbers use to make two hoses out of one). But you only have one data stream (which goes into the file), so you do not need another, no?

Code:
while true; do echo $(fail2ban-client status asterisk-iptables | sed -n '/IP list/ {;s/.*://g'; s/^[ \t]*//;p;}') >> ~/ips; sleep 60; done

On a further thought i do not understand what the "echo" and the subshell is for either:

Code:
while :; do fail2ban-client status asterisk-iptables | sed -n '/IP list/ {;s/.*://g'; s/^[ \t]*//;p;}' >> ~/ips; sleep 60; done

So, make ~/.ips a named pipe, and let a separate script read it and put the result into a final file, something like this (its input will come from ~/.ips):

Code:
#! /bin/ksh

typeset finalfile="/some/where/final"

exec 3>>"$finalfile"

while read line ; do
     if grep -qv "$line" "$finalfile" ; then
          print -u3 - "$line"
     fi
done

exec 3>&-

exit 0

Again, if this is feasible depends on how big the file is and how many entries per minute arrive. If the numbers are small enough this will work.

I hope this helps.

bakunin
These 2 Users Gave Thanks to bakunin For This Post:
# 3  
Old 12-29-2018
Wouldn't a periodical sort -u of the final result file solve those problems in one go at minimal cost? I'd guess searching the entire file for each new IP could become resource hungry.
# 4  
Old 12-29-2018
Quote:
Originally Posted by RudiC
Wouldn't a periodical sort -u of the final result file solve those problems in one go at minimal cost? I'd guess searching the entire file for each new IP could become resource hungry.
That depends. In principle: yes, that would suffice - IF the period between runs of sort -u is sufficiently small to fit thread-O/Ps needs. What exactly "what he needs" is and what therefore "sufficiently small" constitutes is everybodies guess. IF (and again, who knows if this is a moot point or not) there must not be any duplicates in the final file THEN my approach (or something along similar lines) will be necessary. Also, if appending the output file happens without strict regularity the run of the sort -u might collide with the new entries overwriting them - concurrent access can have that effect. It would need some sort of inter-process communication in this case.

But all that is conjecture. Thread-O/P will have to state his problem more clearly to select the right approach.

I hope this helps.

bakunin
# 5  
Old 12-29-2018
Actually instead of exporting the banned IP addresses every 60 seconds and writing them to a file, I ended up reading fail2ban log files to find which IP's were banned.

Code:
cat /var/log/fail2ban.log* | grep -o 'Ban.*' | sed 's/\<Ban\> //g' | sort -u

The actual issue that I am trying to solve, is that the current version of FreePBX can only run fail2ban v0.8.14, which does not maintain it's list of banned IP addresses after a reboot. So I wanted to somehow save the list of banned IP's, and after reboot, manually ban them again. Something like this:

Code:
for ip in $(cat /var/log/fail2ban.log* | grep -o 'Ban.*' | sed 's/\<Ban\> //g' | sort -u); do fail2ban-client set asterisk-iptables banip $ip; done

Which again is not really working 100%, so now I'm thinking of using iptables commands to ban the IP's, not fail2ban commands.

But I appreciate your suggestions and the discussion. It helps with the learning.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Avoid overwriting backup file when multiple entries need to replace in one file input from another

Hello, I have been working on script in which search and replace the multiple pattern. 1. update_params.sh read the multiple pattern from input file ParamMapping.txt(old_entry|New_entry) and passing this values one by one to change_text.sh 2. change_text.sh read... (0 Replies)
Discussion started by: ketanraut
0 Replies

2. Shell Programming and Scripting

How to avoid ssh :Write failed: Broken pipe?

Hello, I am trying to run some code on Matlab over ssh . The code takes around 5-6 hours to complete. so after giving the command to run it , I locked my machine and then went off to sleep at night, only to discover in the morning that I get this message : ...Code running, partial results... (1 Reply)
Discussion started by: ajayram
1 Replies

3. Shell Programming and Scripting

Request to check:remove duplicates and write sytematically

Hi all I have a file with following input It contains 5 columns gene name drug drug ID disease approved Now the same gene is repeated many times with different data in column2,3 ,4,5 I want to arrange dat in such a way that there shuld be one entry in the column(no... (2 Replies)
Discussion started by: manigrover
2 Replies

4. Shell Programming and Scripting

Request to check remove duplicates but write before it

Hi alll I have a file with following kind input I want in output duplicates should not be there but there should be numbering mentioned before that like (4 Replies)
Discussion started by: manigrover
4 Replies

5. Programming

[c]Why first file is creating after the second. How to avoid

Hi, My Code is as below: nbECRITS = fwrite(strstr(data->buffer, ";") + 1, sizeof(char), (data->buffsize) - LEN_NOM_FIC, fic_sortie); fclose(fic_sortie); sprintf(PATH_BALISE, "%s.balise", PATH); fic_balise_data = fopen(PATH_BALISE, "a+"); if (fic_balise_data == NULL) {... (1 Reply)
Discussion started by: ezee
1 Replies

6. Shell Programming and Scripting

avoid open file to check field.

Hi Everyone, # cat a.txt 94,aqqc,62345907, 5,aeec,77, # cat 1.pl #!/usr/bin/perl use strict; use warnings; use Date::Manip; open(my $FA, "/root/a.txt") or die "$!"; while(<$FA>) { chomp; my @tmp=split(/\,/, $_); if (index($tmp, "qq") ne -1) { ... (4 Replies)
Discussion started by: jimmy_y
4 Replies

7. Shell Programming and Scripting

Avoid file creation in a script...achive same result

Guys following lines help me in getting numbers from PID column ,to be thrown into first column of a CSV file. COLUMNS=2047 /usr/bin/ps -eo pid,ppid,uid,user,args | grep -v "PID" > /tmp/masterPID.txt cat /tmp/masterPID.txt|while read line do PID=`echo $line|awk '{print $1}'` echo "$PID"... (4 Replies)
Discussion started by: ak835
4 Replies

8. HP-UX

Parameter to avoid file being deleted by SAM

Good afternoon. I am a newbie. We just had a potentially big problem (negated to having good backups). Basically, there is an option in SAM, to delete all the data from the system that a user ever created. Lo and behold, silly me, I choose that option, and all sorts of needed files... (5 Replies)
Discussion started by: instant000
5 Replies

9. Shell Programming and Scripting

How to avoid a temp file

Hi all. I want to check the free space on a given FS and process the output. Right now, I'm using a temp file to avoid using df twice. This is what I'm doing #!/usr/bin/ksh ... df -k $FS_NAME > $TMP_FILE 2>&1 if ]; then RESULT="CRITICAL - $(cat $TMP_FILE)" else cat $TMP_FILE | ...... (3 Replies)
Discussion started by: fox1212
3 Replies

10. UNIX for Dummies Questions & Answers

Avoid Duplicates in a file

Hi Gurus, I had a question regarding avoiding duplicates.i have a file abc.txt abc.txt ------- READER_1_1_1> HIER_28056 XML Reader: Error occurred while parsing:; line number ; column number READER_1_3_1> Sun Mar 23 23:52:48 2008 READER_1_3_1> HIER_28056 XML Reader: Error occurred while... (7 Replies)
Discussion started by: pssandeep
7 Replies
Login or Register to Ask a Question