LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-09-2012, 03:23 PM   #1
YortheHunter
LQ Newbie
 
Registered: Aug 2012
Location: Somewhere in the great state of NC, USA
Distribution: Anything with Penguins, Devils, or Geckos
Posts: 5

Rep: Reputation: Disabled
Expect syntax issue when calling a bash sed command that uses special character '}'


Quick situational description :
I have an Expect script that is modifying dhcpd.conf by adding lines under a specific ip address. I want to make it more robust by having it check to be sure the lines I am looking to add are not already there by simply erasing everything between the ipaddress line and the '}' that closes that dhcp entry. I have the sed command that I would like Expect to issue once it is logged onto the dhcp server, but I cannot get the syntax correct for it to issue the command and have it complete correctly. Here is the Expect proc that is already executing sed commands to add the new lines :
($ip - passed in ip address)
($file - full pathname of dhcpd.conf)

spawn -noecho ssh $dhcpserver
expect "# " {send "sed -i '/$ip/a\ filename \"yaboot\";' $file\r\n"}
expect "# " {send "sed -i '/$ip/a\ next-server $tftpserver;' $file\r\n"}
expect "# " {send "/bin/systemctl restart dhcpd.service\r\n"}
expect "# " {send "exit\r\n"}
expect

This looks for an ip and then appends the filename and next-server lines underneath it. I would like to be able to check for any number of those lines aleady there and remove them first which I can accomplish with these sed commands :

sed -i '/IPADDRESS/,/^\}/ {/filename/d;}' dhcpd.conf
sed -i '/IPADDRESS/,/^\}/ {/next-server/d;}' dhcpd.conf

I have tested those sed lines and they do exactly what I want them to do, but the problem comes in when I try to issue them in Expect since the '}' is a special character. I have tried the following to no avail :

expect "# " {send "sed -i '/$ip/,/^\}/ {/filename/d;}' $file\r\n"}
expect "# " {send "sed -i '/$ip/,/^\}/ \{/filename/d;\}' $file\r\n"}
expect "# " {send "sed -i '/$ip/,/^\\\}/ {/filename/d;}' $file\r\n"}
expect "# " {send "sed -i '/$ip/,/^\\\}/ \{/filename/d;\}' $file\r\n"}

exec "sed -i '/$ip/,/^\}/ {/filename/d;}' $file\r\n"
exec "sed -i '/$ip/,/^\}/ \{/filename/d;\}' $file\r\n"
exec "sed -i '/$ip/,/^\\\}/ {/filename/d;}' $file\r\n"
exec "sed -i '/$ip/,/^\\\}/ \{/filename/d;\}' $file\r\n"

After the above attempts failed, I have attempted other ways to get expect to execute the sed commands to no avail. After a day and a half of abyssmal failures, I come to you....my goto guys. Hopefully it is just something simple that I am missing/lacking, in which case please beat me over the head with common sense so I can continue on to what I usually do everyday.....Try to take over THE WORLD....or whatever other sysadmin duties pop-up on my queue. Many thanks in advance
 
Old 08-10-2012, 12:34 AM   #2
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 623

Rep: Reputation: 364Reputation: 364Reputation: 364Reputation: 364
Hi.

Welcome to LQ!

Please use the [CODE]..[/CODE] tags around code and data to preserve formatting.

What kind of error do you get? The first your command seems to work just fine for me:
Code:
$ cat exp
set file "in"
expect "#" {send "sed '1,/^\}/ {/filename/d;}' $file\r\n"}
$ echo '#' | expect exp 
sed '1,/^}/ {/filename/d;}' in
No errors. So maybe the problem is in ssh or something else.
 
1 members found this post helpful.
Old 08-10-2012, 12:54 AM   #3
YortheHunter
LQ Newbie
 
Registered: Aug 2012
Location: Somewhere in the great state of NC, USA
Distribution: Anything with Penguins, Devils, or Geckos
Posts: 5

Original Poster
Rep: Reputation: Disabled
Thanks for the fast reply. I'm home right now and decided to take a break from work tonight, so I'll get ya some more info tomorrow. However, some of the send commands would run with no error, but they would not modify the file. I should have been more clear about that on my original post. The intent is to modify dhcpd.conf only in the range from the ip to the closing curly brace and to remove any lines with filename or next-server in them before adding bot a new filename and next-server line. So if your command seemed to work, please be sure of modified the file correctly as well. I have been checking my scripts on a different machine against a copy of the dhcpd.conf file and then checking the file right after. As for the commands that gave errors, ill supply that tomorrow when I get to work. Thanks again for the early response, and sorry for the lack of info.....I tried not to miss anything, but was in a rush to get outta the office to lest my wife and daughter for dinner.

<2012-08-10 8AMish>
I also noticed that you are going from what looks like the beginning of the file. It probably doesn't matter for test purposes, but just thought I would point that out since that isn't really an option for me as it could potentially erase all the other 'filename' and 'next-boot' lines in my dhcpd.conf up to the specified ip (which is unacceptable)
=]

Last edited by YortheHunter; 08-10-2012 at 08:30 AM.
 
Old 08-10-2012, 08:21 AM   #4
YortheHunter
LQ Newbie
 
Registered: Aug 2012
Location: Somewhere in the great state of NC, USA
Distribution: Anything with Penguins, Devils, or Geckos
Posts: 5

Original Poster
Rep: Reputation: Disabled
Ok, so here is the double escape of the '}' :
Code:
#!/usr/bin/expect -f
#
set systemip [lindex $argv 0]
set dhcpfile [lindex $argv 1]
log_user 1
exp_internal 1
set expect_out(buffer) {}

proc check_for_preexisting_install_lines {ip file} {
        spawn bash
        send_user "ip is $ip and file is $file\r\n"
        expect "# " {send "sed -i '/$ip/,/\\\}/ {/filename/d}' $file\r\n"}
        expect "# " {send "sed -i '/$ip/,/\\\}/ {/next-server/d}' $file\r\n"}
}
###################### Execution ###################
check_for_preexisting_install_lines $systemip $dhcpfile
###################### Execution ###################
That returns with :
[root@servo ppxe-work]# ./test-proc-dhcp-check-for-recent-install2.exp x.x.x.x dhcptest.txt
spawn bash
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {11140}
ip is x.x.x.x and file is dhcptest.txt

expect: does "" (spawn_id exp6) match glob pattern "# "? no
[root@servo ppxe-work]#
expect: does "\u001b_root@servo:/temp/under-test/ppxe-work\u001b\[root@servo ppxe-work]# " (spawn_id exp6) match glob pattern "# "? yes
expect: set expect_out(0,string) "# "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\u001b_root@servo:/temp/under-test/ppxe-work\u001b\[root@servo ppxe-work]# "
send: sending "sed -i '/x.x.x.x/,/\}/ {/filename/d}' dhcptest.txt\r\n" to { exp6 }

expect: does "" (spawn_id exp6) match glob pattern "# "? no
sed -i '/x.x.x.x/,/\}/ {/filename/d}' dhcptest.txt

expect: does "sed -i '/x.x.x.x/,/\}/ {/filename/d}' dhcptest.txt\r\n" (spawn_id exp6) match glob pattern "# "? no
[root@servo ppxe-work]#
[root@servo ppxe-work]#
expect: does "sed -i '/x.x.x.x/,/\}/ {/filename/d}' dhcptest.txt\r\n\u001b_root@servo:/temp/under-est/ppxe-work\u001b\[root@servo ppxe-work]# \r\n\u001b_root@servo:/temp/under-test/ppxe-work\u001b\[root@servo ppxe-work]# " (spawn_id exp6) match glob pattern "# "? yes
expect: set expect_out(0,string) "# "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "sed -i '/x.x.x.x/,/\}/ {/filename/d}' dhcptest.txt\r\n\u001b_root@servo:/temp/under-test/ppxe-work\u001b\[root@servo ppxe-work]# "
send: sending "sed -i '/x.x.x.x/,/\}/ {/next-server/d}' dhcptest.txt\r\n" to { exp6 }

******* End Error ********
However, even though it says it ran when you look at the dhcptest.txt at the ip section that was specified it still has both lines in it (will post in next comment)

Last edited by YortheHunter; 08-10-2012 at 08:46 AM.
 
Old 08-10-2012, 09:00 AM   #5
YortheHunter
LQ Newbie
 
Registered: Aug 2012
Location: Somewhere in the great state of NC, USA
Distribution: Anything with Penguins, Devils, or Geckos
Posts: 5

Original Poster
Rep: Reputation: Disabled
Code:
#!/usr/bin/expect -f
#
set systemip [lindex $argv 0]
set dhcpfile [lindex $argv 1]
log_user 1
exp_internal 1
set expect_out(buffer) {}

proc check_for_preexisting_install_lines {ip file} {
        spawn bash
        send_user "ip is $ip and file is $file\r\n"
        expect "# " {send "sed -i '/$ip/,/\\\}/ {/filename/d}' $file\r\n"}
        expect "# " {send "sed -i '/$ip/,/\\\}/ {/next-server/d}' $file\r\n"}
        expect "# " {send "exit\r\n"}
        expect
}
###################### Execution ###################
check_for_preexisting_install_lines $systemip $dhcpfile
###################### Execution ###################
Works.....I must have gone cross eyed from staring at the same part of code for hours on end and had some other lingering typo. Many thanks for the second pair of eyes there firstfire. Koodo's to you. I will wander back to my cave now and beat myself mercilessly for wasting your time. Those responsible for flogging those that need to be flogged will also be flogged.

*sigh*

My sanity thanks you firstfire
 
Old 08-10-2012, 09:02 AM   #6
YortheHunter
LQ Newbie
 
Registered: Aug 2012
Location: Somewhere in the great state of NC, USA
Distribution: Anything with Penguins, Devils, or Geckos
Posts: 5

Original Poster
Rep: Reputation: Disabled
also, I posted another comment just before that last that stated that the results were unexpected as the filename was indeed gone, but the next-server line was still there. That pointed to needing an additional expect, thus my last comment with the funtional code. I must really need some sleep....thanks again guys
 
Old 08-10-2012, 09:31 AM   #7
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 623

Rep: Reputation: 364Reputation: 364Reputation: 364Reputation: 364
Hi.

I'm glad to see you figured this out. Good luck!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
search and replace string with special character perl or sed. Noobux Programming 4 05-21-2012 03:16 PM
[SOLVED] How to escape bash-special character in a bash string? fantasy1215 Programming 12 03-10-2012 09:45 AM
[SOLVED] sed command to replace special character / Lokelo Linux - Newbie 11 11-23-2011 07:59 AM
Automatic special character escaping in Bash scripts? wipe Linux - Software 1 06-05-2009 06:41 PM
Trouble calling 'expect' from bash raypen Linux - Software 1 06-01-2006 08:05 PM


All times are GMT -5. The time now is 11:59 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration