0

I'm working on a small script that loads some iptables lists and writes each line to a associated chain-file. This all works only if the script runs in an empty directory. As far as I understand correctly, this is due to the array in which I have the value * stored. As soon as a line with * is called, the value is replaced with all files in the current directory.

Do you guys know a simple solution to run the script in a non-empty folder?

here is an example of output when the script runs in ~

LOG tcp -- Bilder Dokumente Downloads Musik Öffentlich Schreibtisch Videos Vorlagen eth1 !125.238.212.131 0.0.0.0/0 tcp dpt:45 LOG flags 0 level 4 prefix `LOGSMTP '
LOG tcp -- Bilder Dokumente Downloads Musik Öffentlich Schreibtisch Videos Vorlagen eth1 !125.238.212.131 0.0.0.0/0 tcp dpt:225 LOG flags 0 level 4 prefix `LOGSMTP '

and here is an example of the output when it runs in an empty folder (it should look like this)

LOG tcp -- * eth1 !125.238.212.131 0.0.0.0/0 tcp dpt:45 LOG flags 0 level 4 prefix `LOGSMTP '
LOG tcp -- * eth1 !125.238.212.131 0.0.0.0/0 tcp dpt:225 LOG flags 0 level 4 prefix `LOGSMTP '

and here is the script

#!/bin/bash

cd /scripts/s.iptables.d/work
data=$(ls /scripts/s.iptables.d/iptables*)

for file in $data
do
        outputpath="/output/s.iptables-"
        while read -r line
        do
                arr=($line)
                case "$line" in
                        Chain* )        chain=${arr[1]}
                                        output=$outputpath$chain
                                        inactiveoutput=$outputpath$chain"-inactive"
                                        ;;
                        [1-9]* )        reg="^[0-9]*\s+0\s+0.*$"
                                        if [[ "$line" =~ "$reg" ]]
                                        then
                                        echo "${arr[@]:3}" >> $inactiveoutput
                                        else
                                        echo "${arr[@]:3}" >> $output
                                        fi
                                        ;;
                esac
        done < <(cat "$file")
done

I am looking forward to any help and thank you in advance

3
  • Escape it with a backslash, you know, \*, and test it Commented Sep 6, 2017 at 10:45
  • So if I escape every *, I would have to replace every \* before it can be written. This would, substantially increase the running time. Do you have a other idea? Commented Sep 6, 2017 at 12:07
  • Have you tried using backticks ( ` ) around the ls command instead of using the $() notation? So would look like data=` ls /scripts/s.iptables.d/iptables* ` Commented Sep 6, 2017 at 13:33

1 Answer 1

1

Don't parse ls -> http://mywiki.wooledge.org/ParsingLs and http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29

Do one of these:

files=( /scripts/s.iptables.d/iptables* )
for file in "${files[@]}"

or simply

for file in /scripts/s.iptables.d/iptables*

Also done < <(cat "$file") is an excessive use of process substitution, just use

done < "$file"
Sign up to request clarification or add additional context in comments.

Comments

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.