0

So I'm attempting to grab some syslogs from a file like this one.

$date  INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0]

I will be replacing the time-stamp and IP addresses of the individual logs which are taken from the file and stored inside an array. here is my code:

#!/bin/bash
file=log_store
gen_ip() {
        echo $((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256))
}
timestamp() {
        date +"%b %d %H:%M:%S"
}
ip=$(gen_ip)
date=$(timestamp)
if [ -e $file ];  then
        readarray -t logs < $file
else
        echo "$file is not present"
fi

cmd='cmd=${logs[0]}'
eval $cmd
echo $cmd

this code seems to echo the first array item but it isn't replacing the $date from the file, it simply prints "$date". From my tests the eval seems to work on other arrays I've defined inside the program except for the log array so i'm a little stuck!

  • I don't see any replacement logic within your code – RomanPerekhrest Jan 23 '18 at 11:03
  • @RomanPerekhrest I was hoping that the eval would process the variables. for example, when you create a string that contains a variable, the eval command will replace them with the variable contents. so when foo='$bar' is run through eval $foo then echo $foo it should print whatever $bar was – user3019354 Jan 23 '18 at 11:08
  • *replacing the time-stamp and IP addresses of the individual logs* - and how IP address is replaced? – RomanPerekhrest Jan 23 '18 at 11:22
  • @RomanPekherest i would write $ip in the text file – user3019354 Jan 23 '18 at 11:30

1 Answers1

1

Change this line:

cmd='cmd=${logs[0]}'

to:

cmd="cmd=\"${logs[0]}\""

Your single quotes are preventing the expansion of the ${logs[0]} variable, so $cmd contains that literally. Then eval expands that variable, which results in $date. You need the first expansion so that the value of the variable becomes

cmd='$date  INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0]'

and then eval will expand the $date variable.

You need the double quotes around ${logs[0]} so that it won't try to parse the rest of the line as a shell command, but will still expand variables in it. And they have to be escaped so they can be put inside the cmd string.

You should also quote the variable when you use eval and echo:

eval "$cmd"
echo "$cmd"

to prevent additional word splitting and globbing of the result.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • It's interesting because this seems to work perfectly fine; 'logs=( "this is a $date" ) packet='packet=${logs[0]}' eval $packet echo $packet' it seems not to like single quotes on the array i've found. I also returned an error with removing the quotes. – user3019354 Jan 23 '18 at 11:29
  • Variables are expanded in double quotes, not in single quotes. – Barmar Jan 23 '18 at 11:31
  • So when you write `logs=("this is a $date")` it expands the variable there. – Barmar Jan 23 '18 at 11:31
  • See [difference between single and double quotes in bash](https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash) – Barmar Jan 23 '18 at 11:32
  • aaah ok I see what you mean so i'd need to write cmd="${logs[0]}" which should return the log and then push that through eval? – user3019354 Jan 23 '18 at 11:42
  • @barmer so i'm now getting this error ./program.sh: eval: line 19: syntax error near unexpected token `(' – user3019354 Jan 23 '18 at 11:45
  • What's on line 19? – Barmar Jan 23 '18 at 11:47
  • this is what's there: eval $cmd – user3019354 Jan 23 '18 at 11:49
  • I can't reproduce the error. What does `echo "$cmd"` show before the `eval`? – Barmar Jan 23 '18 at 11:55
  • The best way to debug a shell script is to put `set -x` at the beginning. Then you'll see all the variable expansions as it's executing. This should help you. – Barmar Jan 23 '18 at 11:56
  • so this is my code in it's current state #!/bin/bash file=log_store gen_ip() { echo $((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256)) } timestamp() { date +"%b %d %H:%M:%S" } ip=$(gen_ip) if [ -e $file ]; then readarray logs < $file else echo "$file is not present" fi date=$(timestamp) packet="${logs[0]}" echo $packet eval $packet echo $packet – user3019354 Jan 23 '18 at 11:59
  • and this is the error: $date INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0] ./picnmix.sh: eval: line 18: syntax error near unexpected token `(' ./picnmix.sh: eval: line 18: `$date INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0]' $date INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0] – user3019354 Jan 23 '18 at 11:59
  • It's putting the entire line in `logs[0]` instead of just the first field. – Barmar Jan 23 '18 at 12:01
  • is there not a way to process the whole line and the variables in it? – user3019354 Jan 23 '18 at 12:03
  • See the updated answer. You need single quotes around `${logs[0]}` inside the double quotes. – Barmar Jan 23 '18 at 12:05
  • so i've updated to match the answer date=$(timestamp) packet="packet='${logs[0]}'" eval "$packet" echo "$packet" the output of this is now: $date INT-FW01 : %ASA-6-106100: access-list inside denied udp inside/172.29.2.101(1039) -> outside/192.203.230.10(53) hit-cnt 1 first hit [0xd820e56a, 0x0] i'm so confused and sorry about this haha – user3019354 Jan 23 '18 at 12:11
  • Ugh, I also made a single vs. double quote error. They need to be escaped double quotes around `${log[0]}` – Barmar Jan 23 '18 at 12:15