Problem to match a path in a file and put it into a variable

Hello,:stuck_out_tongue:

I made a script which do a backup on remote servers with a rsync command. I have a config.cfg with the IPs and the paths where it will copy the directory. The problem is that it doesn't match the paths, So, here my script and its output with the debug :

#!/bin/bash
# PATHS
HOME_BACKUP="/home/backup"
HOME_SCRIPT="/home/scripts/test/backup_server"
# DATE
DATE_Ymd=$(date +%Y-%m-%d)
# DEBUG
set -x

# SCRIPT
for IP in `egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' config_ip.cfg`
do
        ssh "$IP" 'hostname' > hostname.txt
        HOSTNAME=$(cat hostname.txt)
                cd "$HOME_BACKUP"
                mkdir -p "$HOSTNAME"
                cd "$HOSTNAME"
                mkdir "$DATE_Ymd"

        TARGET=$(grep "$IP" config_ip.cfg |awk -F "PATH: " '{print $2}')
        rsync -azvtP rsync_user@"$IP":"$TARGET" "$HOME_BACKUP"/"$HOSTNAME"/"$DATE_Ymd"
                rm -rf "$DATE_Ymd"
                cd "$HOME_SCRIPT"
                rm "$HOME_SCRIPT"/hostname.txt

done

Config.cfg :

#########################################
# Enter the remote servers IP as follow:#
# IP CLIENT: XXX.XXX.XXX.XXX            #
# Source: backup_script.sh              #
#########################################

IP CLIENT: 192.168.1.93   -   PATH: /var/www
IP CLIENT: 192.168.1.30   -   PATH: /var/www

Output :

rsync_user@SERVER:/home/scripts/test/backup_server$ ./backup_script.sh
++ egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' config_ip.cfg
+ for IP in '`egrep -o '\''([0-9]{1,3}\.){3}[0-9]{1,3}'\'' config_ip.cfg`'
+ ssh 192.168.1.93 hostname
++ cat hostname.txt
+ HOSTNAME=vm1
+ cd /home/backup
+ mkdir -p vm1
+ cd vm1
+ mkdir 2016-12-07
++ awk -F 'PATH: ' '{print $2}'
++ grep 192.168.1.93 config_ip.cfg
grep: config_ip.cfg: No such file or directory
+ TARGET=
+ rsync -azvtP rsync_user@192.168.1.93: /home/backup/vm1/2016-12-07

receiving incremental file list
sent 161 bytes  received 3,109 bytes  934.29 bytes/sec
total size is 4,928  speedup is 1.51

+ rm -rf 2016-12-07
+ cd /home/scripts/test/backup_server
+ rm /home/scripts/test/backup_server/hostname.txt

...

If anyone have an idea ? :slight_smile: I hope have been understandable

Hi,

You do cd twice so your directory is not same as when your first line of

 for IP in `egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' config_ip.cfg`

Hence this grep says no such file or directory :

 $(grep "$IP" config_ip.cfg |awk -F "PATH: " '{print $2}')

Modify the code to cd the directory where you have config_ip.cfg

Minor comment:

TARGET=$(grep "$IP" config_ip.cfg |awk -F "PATH: " '{print $2}')

can be written as

TARGET=$(awk -F "PATH: " -vx=$IP ' $0 ~ x {print $2}' config_ip.cfg)
1 Like

Thank you very much ! I created a variable for the path and I modified, your awk is a very good way :b::b: :

TARGET=$(awk -F "PATH: " -vx=$IP ' $0 ~ x {print $2}' "$HOME_SCRIPT")

---------- Post updated at 06:16 PM ---------- Previous update was at 06:15 PM ----------

can you describe the command ? Without asking too much

Hello Arnaush78,

Could you please go through the following and let me know if this helps you.

TARGET=$(awk -F "PATH: " -vx=$IP ' $0 ~ x {print $2}' config_ip.cfg)
awk -F "PATH: "   #### -F in awk defines the field seprator whuch we want to makein any Input_file, so here we are mentioning it should be string "PATH: "
-vx=$IP           #### -v in awk is used for initializing a vatiable, so here we are creating a variable named named x whose value is equal to value f shell variable named $IP. Because in awk we can't mention variable's
                       value like shell so like this we could assign any shell's variable value to awk's variabe to make use of it in awk program.
' $0 ~ x          #### Mentioning a condition here if $0(current line) equals to value of variable named x(which we defines with -v explained as above), if this condition is TRUE then execute the following statements.
{print $2}'       #### printing the field 2nd of the current line in case above condition is TRUE.
config_ip.cfg     #### Mentioning the Input_file here which awk has to read and process whose name is config_ip.cfg here.

Thanks,
R. Singh

2 Likes

Looking at the script in post#1 I feel inclined to comment on a few points:

  • Don't cd to and fro ( as already pointed out by greet_sed) but use absolut paths.
  • Don't use temp files if not necessary.
  • Don't use "command substitution" excessively - use available shell tools where appropriate, avoiding surplus process creation.
  • Looks like you're removing the freshly created backup with rm -rf "$DATE_Ymd" . Why?

Look into this little proposal; you might want to consider this or that hint in it:

while read V1  X  IP  X X  TARGET  X
  do    [ ! "$V1" = "IP" ] && continue
#       test the IP if necessary
        echo $IP, $TARGET
#       further processing, like
        HOSTNAME=$(ssh "$IP" 'hostname')
        mkdir -p "$HOME_BACKUP"/"$HOSTNAME"/"$DATE_Ymd"

        rsync -azvtP rsync_user@"$IP":"$TARGET" "$HOME_BACKUP"/"$HOSTNAME"/"$DATE_Ymd"

  done < cfg_file
1 Like

Thanks for your all replies !:b::b:

You have DOS <carriage return> line terminators (\r, 0x0D, ^M) in your config file. Use tr -d $'\r' <file to remove them upfront, or do it in the awk when assigning TARGET.

It's difficult to believe that it should work flawlessly from the command line with the same config file.

1 Like

Yes I found.. I copied the script and conf from notepad..I deleted both files and recreate, they work ty too