SED Escape in bash script - bash

My tempfile.txt has below contents [Typical Cisco Configuration File]
interface GigabitEthernet1/11
no ip address
shutdown
rmon collection stats 6010 owner monitor
!
interface GigabitEthernet1/12
no ip address
shutdown
rmon collection stats 6011 owner monitor
!
interface GigabitEthernet1/13
no ip address
shutdown
rmon collection stats 6012 owner monitor
!
interface GigabitEthernet1/14
no ip address
shutdown
rmon collection stats 6013 owner monitor
!
I am trying to loop through to do some operation on each block
Example
interface GigabitEthernet1/14 --> start of interface block
no ip address
shutdown
rmon collection stats 6013 owner monitor
! --> end of interface block
I have another file which has below data intefaces.txt
interface GigabitEthernet1/11
interface GigabitEthernet1/12
interface GigabitEthernet1/13
interface GigabitEthernet1/14
Now want to do some changes in each block thats why I am trying to access block in loop via
while read line
do
sed -n '/$line/,/!/p' tempfile.txt # this should get me block
#code for doing some changes in block
done < interfaces.txt
Now since my $line will be one of line of interfaces.txt eg: interface GigabitEthernet1/11
how can I escape / as I am doing in loop & my interfaces will always contain / character

Tell sed which character to use in place of / in the search by prefixing it with a backslash:
sed -n "\#${line}#,/!/p" ...

To work with block of text, use gnu awk (due to multiple characters in RS)
awk -vRS="interface" '/1\/13/ {print RS $0}' file
interface GigabitEthernet1/13
no ip address
shutdown
rmon collection stats 6012 owner monitor
!
Here you get all of info for interface 1/13
You can prevent the escaping of / by getting it in as a variable.
awk -vRS="interface" -vtest="1/13" '$0~test {print RS $0}'
interface GigabitEthernet1/13
no ip address
shutdown
rmon collection stats 6012 owner monitor
!

In bash, you can use the parameter global replace operator, ${varname//old/new}, to replace the slashes with backslashed slashes, like this:
while read line; do
sed -n "/${line//\//\/\/}/",'/!/p' tempfile.txt | # do stuff
done <interfaces.txt
... but Holy Leaning Toothpicks, Batman! I would go with #JonathanLeffler's solution of changing sed's search delimiter.

Related

Create a dynamic header based from the output on the file (BASH)

i have a file that is quite dynamic. Dynamic in a sense that Host and iSCSI_Name may come short or long. It works well for some host with long iqn name like the sample below but it doesn't work for host with shorter name.
Would appreciate if someone had done this or maybe had a previous script that creates a dynamic header that follows the length on the given data or vice versa.
With long iqn name
MAPPING
==================================================================================
Host Status iSCSI_Name State
==================================================================================
irefr-esz-011 online iqn.2000-01.com.vmware:irefr-esz-011-312901 active
==================================================================================
with short iqn and host name output looks like this. Data is not in place.
MAPPING
==================================================================================
Host Status iSCSI_Name State
==================================================================================
esz1 online irefr-esz-011-312901 active
==================================================================================
Currently, i had this on my script.
echo -e "\e[96m MAPPING\e[0m"
echo "=================================================================================="
printf '%-12s %-30s %-21s %-30s %-20s\n' Host Status iSCSI_Name State
echo "=================================================================================="
cat outputfile | column -t
echo "=================================================================================="
echo
output file:
irefr-esz-011 online iqn.2000-01.com.vmware:irefr-esz-011-312901 active
esz1 online irefr-esz-011-312901 active
irefr-esz-011 online iqn.2000-01.com.vmware:irefr-esz-011-312901 active
esz1 online irefr-esz-011-312901 active
irefr-esz-011 online iqn.2000-01.com.vmware:irefr-esz-011-312901 active
esz1 online irefr-esz-011-312901 active
What's about
SEP="===================================================================================="
(echo Host Status iSCSI_Name State; cat outputfile) | column -t | \
sed "1 s/\(.*\)/$SEP\n\1\n$SEP/";echo $SEP
sed picks the first line and decorates it with a leading and a trailing separator.

Quoted variables in shell script

I'm attempting to determine if the Auto Proxy URL on a Mac as been configured.
First, I want to get the port number
port=$(route get example.com | grep interface | sed 's/.*\(...\)/\1/')
Then use the port number to obtain the active network service
service=$(networksetup -listnetworkserviceorder | grep $port | sed 's/,.*$//; s/^.*: //')
And finally, I use the active network service to obtain the auto proxy info
autoproxy=$(networksetup -getautoproxyurl \"$service\")
I'm running into a problem with any network service that includes spaces. For example Wi-Fi works fine, but Apple USB Ethernet Adapter does not.
I thought the solution would be to escape the quotes (\"$service\")
The odd thing is that if I echo $service (where $service is Apple USB Ethernet Adapter) it returns a properly quoted result of "Apple USB Ethernet Adapter" If I then copy and paste this exact result as a replacement for the variable $service, I get the result I was expecting (URL: (null) Enabled: No)
However, running the command as it was originally written returns a parameter error (Error: The parameters were not valid).
This is the result of running the script as is:
autoproxy=$(networksetup -getautoproxyurl "$service")
echo $autoproxy
Error: The parameters were not valid.
However, if I copy and paste the output of $service, then it returns the result I was expecting.
service=$(networksetup -listnetworkserviceorder | grep $port | sed 's/,.*$//; s/^.*: //')
echo \"$service\"
"Apple USB Ethernet Adapter"
autoproxy=$(networksetup -getautoproxyurl "Apple USB Ethernet Adapter")
echo $autoproxy
URL: (null) Enabled: No
You are using "" for service variable in autoproxy expression.

What could prevent frequently switching default source ip of a machine with several interfaces

The goal was to frequently change default outgoing source ip on a machine with multiple interfaces and live ips.
I used ip route replace default as per its documentation and let a script run in loop for some interval. It changes source ip fine for a while but then all internet access to the machine is lost. It has to be remotely rebooted from a web interface to have any thing working
Is there any thing that could possibly prevent this from working stably. I have tried this on more than one servers?
Following is a minimum example
# extract all currently active source ips except loopback
IPs="$(ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 |
awk '{ print $1}')"
read -a ip_arr <<<$IPs
# extract all currently active mac / ethernet addresses
Int="$(ifconfig | grep 'eth'| grep -v 'lo' | awk '{print $1}')"
read -a eth_arr <<<$Int
ip_len=${#ip_arr[#]}
eth_len=${#eth_arr[#]}
i=0;
e=0;
while(true); do
#ip route replace 0.0.0.0 dev eth0:1 src 192.168.1.18
route_cmd="ip route replace 0.0.0.0 dev ${eth_arr[e]} src ${ip_arr[i]}"
echo $route_cmd
eval $route_cmd
sleep 300
(i++)
(e++)
if [ $i -eq $ip_len ]; then
i=0;
e=0;
echo "all ips exhausted - starting from first again"
# break;
fi
done
I wanted to comment, but as I'm not having enough points, it won't let me.
Consider:
Does varying the delay time before its run again change the number of iterations before it fails?
Exporting the ifconfig & routes every time you change it, to see if something is meaningfully different over time. Maybe some basic tests to it (ping, nslookup, etc) Basically, find what is exactly going wrong with it. Also exporting the commands you send to a logfile (text file per change?) to see changes in them to see if some is different after x iterations.
What connectivity is lost? Incoming? Outgoing? Specific applications?
You say you use/do this on other servers without problems?
Are the IP's: Static (/etc/network/interfaces), bootp/DHCP, semi-static (bootp/DHCP server serving, based on MAC address), and if served by bootp/DHCP, what is the lease duration?
On the last remark:
bootp/dhcp will give IP's for x duration. say its 60 minutes. After half that time it will "check" with the bootp/dhcp server if it can keep the IP, and extend the lease to 60 minutes again, this can mean a small reconfig on the ifconfig (maybe even at the same time of your script?).
hth

Unix script to resolve hostnames from IP addresses

I've got a text file with a bunch of IPv4 addresses, and I'd like to know the hostname of each one in order to know if they are tor addresses. Is there a simple script that can help me to do that ?
You can loop using dig:
#!/bin/bash
while read line
do
dig -x "$line" +short
done
Then given IPs 1 per line, you can run something like ./reverse.sh < addrs.txt.
Caveats: DNS is not a 1-to-1 mapping, and reverse DNS is somewhat less reliable than forward DNS.

Bash script to audit Cisco configuration

I'm currently writing a script to generate a report from cisco configuration for audit purposes. Using 'grep' command, I was able to successfully capture the global configurations.
But the challenge is doing it per interface. For example, I want to know which interfaces have these lines 'no ip redirects', 'no ip unreachables', etc. How can I accomplish this in bash?
Thank you in advance!
This can not be done easy with grep, but awk handle this:
cat file
!
interface GigabitEthernet0/13
description Server_32_main
spanning-tree portfast
no ip redirects
!
interface GigabitEthernet0/14
description Server_32_log
switchport access vlan 666
spanning-tree portfast
!
interface GigabitEthernet0/15
description UPS_20
spanning-tree portfast
!
As you see, each group is separated by !, so we use that to separate each record.
To get only interface name do like this:
awk -v RS="!" -F"\n" '/no ip redirects/ {print $2}' file
interface GigabitEthernet0/13
To get interface config do:
awk -v RS="!" '/no ip redirects/' file
interface GigabitEthernet0/13
description Server_32_main
spanning-tree portfast
no ip redirects
To get more patterns in one go:
awk -v RS="!" '/no ip redirects/ || /no ip unreachables/' file

Resources