29

I have a httpd.conf file of shared hosting server and I have a task to migrate every virtual host to a vps. using awk I extract a block of virtual host entry for a particular site. and store that entry in a variable. but when i echo the out put of the variable to append httpd.conf of vps server it gives a error like

bash: command substitution: line 1: syntax error near unexpected token newline' bash: command substitution: line 1:echo '

Could anyone tell what is exact way to append simple text file by echo a variable having multiple lines.

My expect script is as follows:

#!/usr/bin/expect 
set remote_ip [lindex $argv 0] 
set username [lindex $argv 1] 
set remote_command [lindex $argv 2] 
foreach {remote_ip username remote_command} $argv {break} 
spawn ssh -o "StrictHostKeyChecking no" root@$remote_ip `echo $remote_command >> /etc/httpd/conf/httpd.conf`
expect "*assword: " 
send "redhat\r" 
interact 

and the variable "remote_command" contains a pattern of virtual host entries. used printf but still same problem exists. –


my remote_command contains following values

<VirtualHost>
DirectoryIndex index.php
</VirtualHost>

it still giving same error.I used "" quotes but it worked for a single line , and not for multiple lines.

My main script script.sh contains lines

#!/bin/bash
some code .....
some code......
some code ......
echo "<VirtualHost $D_IPADDRESS>" > /opt/remotehttpd_conf
awk "p && /\/VirtualHost/{exit} /$SITENAME/{p=1}p" /opt/httpd.conf >> /opt/remotehttpd_conf
echo "</VirtualHost>" >> /opt/remotehttpd_conf
REMOTE_COMMANDS4=`cat /opt/remotehttpd_conf`
echo $REMOTE_COMMANDS4
./expect_remote_command_httpd.exp  "$D_IPADDRESS" "$USERNAME" "$REMOTE_COMMANDS4"
some code .....
some code .....

when I echo REMOTE_COMMANDS4 it works fine and give me output so i use expect_remote_command_httpd.exp to transfer the output to remote machine

my expect_remote_command_httpd.exp contains

#!/usr/bin/expect 
set remote_ip [lindex $argv 0] 
set username [lindex $argv 1] 
set remote_command [lindex $argv 2] 
foreach {remote_ip username remote_command} $argv {break} 
spawn ssh -o "StrictHostKeyChecking no" root@$remote_ip `echo $remote_command >>   /etc/httpd/conf/httpd.conf`
expect "*assword: " 
send "redhat\r" 
interact 

but its not working. May be what approach i am using is totally wrong. My main concern is to extract all lines of virtual host block related to given sites in shared httpd server and trnsfer it to remote vps's httpd conf file.i will appreciate if you will suggest any other way.

aditya
  • 531
  • 2
  • 5
  • 14

4 Answers4

56
cat >> /path/to/existingFile.text<< EOF
some text line 1
some text line 2
some text line 3
EOF

switch cat >> to cat > to create a file instead of append

cat > /path/to/newFile.text<< EOF
some text line 1
some text line 2
some text line 3
EOF
snassr
  • 1,228
  • 14
  • 10
25

It seems so that you try to write some characters that are treated by like special characters. You must escape them with ''. If you want just add lines line1, line2, line3 seprated with newlines try

echo -e 'line1\nline2\nline3\n'

or (more portable)

printf 'line1\nline2\nline3\n'

If something else, could you please give additional information?

Thank you for additional information. You mst change backticks ` to double quotes""in thespawn ssh` command. That is a command substitution here, but must be a normal (interpolated) string.

Update

Ok, so you want to run $remote_command and write its reuls to the file. Ok. Then you must do it this way:

spawn ssh -o "StrictHostKeyChecking no" root@$remote_ip $remote_command >> /etc/httpd/conf/httpd.conf
Igor Chubin
  • 61,765
  • 13
  • 122
  • 144
  • Imo he/she asks about lines with content. – Ondra Žižka Jul 04 '12 at 05:29
  • 2
    `echo -e` is very non-portable. Use `printf`. – ormaaj Jul 04 '12 at 05:31
  • @OndraŽižka: Added some content :) – Igor Chubin Jul 04 '12 at 05:31
  • 1
    Since `printf` loops through its format string if there are excess arguments, you can also use `printf "%s\n" line1 line2 line3`. But it may be easier to use `cat` with a [*here document*](http://tldp.org/LDP/abs/html/here-docs.html). – Keith Thompson Jul 04 '12 at 05:56
  • @aditya: added suggestion to my answer. – Igor Chubin Jul 04 '12 at 06:49
  • If you are printing multiple lines, consider the format where you use the `<<< delimiter` option, check `man bash` on "Here Documents" – Miquel Jul 04 '12 at 07:02
  • $remote_command is variable and not a command that contains virtualhost block( with multiple lines) I just want to insert these lines on remote computer's httpd conf file. I tried the above way u suggested but gave error like virtualhost command not found DiectoryIndex command not found. I repeat $remote_command is variable and not a command – aditya Jul 04 '12 at 08:26
  • adity: sorry, I thought it is a command. How can `$remore_command` contain newlines? How do you specify newlines in it? That is just an argument for the script. Please show, how you do it. – Igor Chubin Jul 04 '12 at 08:36
  • @aditya: how can you remote command contain these values? How can you pass newlines into this variable? – Igor Chubin Jul 05 '12 at 07:07
3
    `echo "line 1 content" >> myfile.txt`
    `echo "line 2 content" >> myfile.txt`
    `echo "line 3 content" >> myfile.txt`

add >> instead of > after the string you want to echo, this command would append to a new line in the file.

0

You can do it like this, it is easier

spawn ssh -o "StrictHostKeyChecking no" root@$remote_ip "echo ready;cat >> /etc/httpd/conf/httpd.conf"
expect "assword:"
send "redhat\n"
expect "ready"
send "line 1 of file\n"
send "line 2 of file\n"
send "line 3 of file\n"
# send control-D to end
send "\04"
interact

if you don't like "echo ready; cat ...", you can just call a script that reads from stdin and do your work. Or call bash directly and send in a script.

pizza
  • 7,296
  • 1
  • 25
  • 22