LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Expect inside while loop (https://www.linuxquestions.org/questions/linux-newbie-8/expect-inside-while-loop-4175510454/)

cnitin 07-08-2014 03:57 AM

Expect inside while loop
 
Hi Guys,

Its been long time since i've posted on this forum.

But here it is , trying my hands on shell script once again to automate a task which has been done manually for many weeks now.

The task is to scp files from server A to B , However please note that password-less scp cannot be used.

So i am trying to script expect inside a shell script.
I am trying to put all things inside only one script rather than calling expect script from shell script.

Please find below code,

Code:


#!/bin/bash

> filelist1.txt
> filelist2.txt
> filename.txt

find . -type f -newer 1_1764_842824583.dbf ! -newer 1_1822_842824583.dbf  -exec ls -lrt {} \; > filelist1.txt
cat filelist1.txt | awk '{print$9}' > filelist2.txt

while read inputline
        do
        password="abcdefgh"
        echo $inputline > filename.txt
        file=`echo $inputline | cut -c3-`
        expect -c '
              #spawn /usr/bin/scp "$file" oracle@10.10.10.10:/oarch/adb/
              spawn /usr/bin/scp '$file' oracle@10.10.10.10:/oarch/adb/
              expect {
              #"*password:*" { send $password\r\n; interact }
              #"*password:*" { send -- "abcdefgh"}
              "[Pp]assword:*" { send $password\r\n; interact }

                    }
                  '
done < filelist2.txt


And the above code is not working as desired ,
Either it terminates when i use " or it just loops for all the files and exits.

Kindly help or point me in right direction.

Regards,
Nitin

pan64 07-08-2014 04:10 AM

http://stackoverflow.com/questions/7...multiple-files
here you can find a nice function to send password. also you can try to scp all the files in one:
Code:

filelist=$(cat filelist2.txt)
....
scp '$filelist' ....


cnitin 07-08-2014 04:55 AM

Hi Pan64,

Thanks for your reply , According to your link and code i've changed the code as below.

Code:

> filelist1.txt
> filelist2.txt
> filelist3.txt
> filelist4.txt

find . -type f -newer 1_1764_842824583.dbf ! -newer 1_1768_842824583.dbf  -exec ls -lrt {} \; > filelist1.txt
cat filelist1.txt | awk '{print$9}' > filelist2.txt

while read inputline
        do
        file=`echo $inputline | cut -c3-`
        echo $file >> filelist3.txt
done < filelist2.txt

tr '\n' ' ' < filelist3.txt
filelist=`cat filelist4.txt`

password="lkjh1234"

function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

expect_password 'scp "$filelist" oracle@10.10.10.10:/oarch/adb/'

It is throwing below error,

Code:


1_1765_842824583.dbf 1_1766_842824583.dbf 1_1767_842824583.dbf 1_1768_842824583.dbf can't read "filelist": no such variable
    while executing
"spawn scp "$filelist" oracle@10.10.10.10:/oarch/adb/"

Kindly help.

Regards,
Nitin

pan64 07-08-2014 05:32 AM

in your find command you can try to use -print instead of -exec ls -lrt {} that would make it simpler I think.
instead of:
cat filelist1.txt | awk '{print$9}' > filelist2.txt
use:
awk '{print$9} filelist1.txt > filelist2.txt
but will not need any more (if you use -print)

instead of
while read inputline
....
done < filelist2.txt
use
awk 'script' filelist2.txt > filelist3.txt

in this script you need to remove newline chars too, you need to have only one single line in filelist3.txt
actually I do not know what is that cut good for....

cnitin 07-08-2014 06:10 AM

Hi Pan64,

The output of -print is as below
Code:

./1_1765_842824583.dbf
./1_1766_842824583.dbf
./1_1767_842824583.dbf
./1_1768_842824583.dbf

cut is used to get rid of " ./ ".
I have also changed the newline characters to space using tr as below ,
Code:

tr '\n' ' ' < filelist2.txt
I have now changed the code as below,

Code:


> filelist1.txt
> filelist2.txt
> filelist3.txt
> filelist4.txt

find . -type f -newer 1_1764_842824583.dbf ! -newer 1_1768_842824583.dbf -print > filelist1.txt

cat filelist1.txt

while read inputline
        do
        file=`echo $inputline | cut -c3-`
        echo $file >> filelist2.txt
done < filelist1.txt


tr '\n' ' ' < filelist2.txt
filelist=`cat filelist2.txt`
echo filelist
password="lkjh1234"

function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

expect_password 'scp "$filelist" oracle@10.10.10.10:/oarch/adb/'
#expect_password 'scp 1_1764_842824583.dbf oracle@10.10.10.10:/oarch/adb/'

and now the error is as below

Code:

bash-3.2$ ./mov3.sh
./1_1765_842824583.dbf
./1_1766_842824583.dbf
./1_1767_842824583.dbf
./1_1768_842824583.dbf
1_1765_842824583.dbf 1_1766_842824583.dbf 1_1767_842824583.dbf 1_1768_842824583.dbf filelist
can't read "filelist": no such variable
    while executing
"spawn scp "$filelist" oracle@10.10.10.10:/oarch/adb/"

regards,
Nitin

pan64 07-08-2014 06:14 AM

yes, you mixed " and ':
expect_password 'scp '$filelist' oracle@10.10.10.10:/oarch/adb/'

cnitin 07-08-2014 06:41 AM

Hi Pan64,

I have changed " to ' as below ,
Code:

expect_password 'scp '$filelist' oracle@10.10.10.10:/oarch/adb/'
And now when i execute , i get below error

Code:

1_1765_842824583.dbf 1_1766_842824583.dbf 1_1767_842824583.dbf 1_1768_842824583.dbf can't read "filelist": no such variable
    while executing
"spawn scp $filelist oracle@10.10.10.10:/oarch/adb/"

I am trying all kinds of combinations , but nothing seem to work.
One more important thing which i forgot to mention while creating thread is the server is AIX 6.1


Regards,
Nitin

cnitin 07-08-2014 07:35 AM

Hi Pan64,

After making some more changes now the code looks like

Code:


> filelist1.txt
> filelist2.txt
> filelist3.txt
> filelist4.txt

find . -type f -newer 1_1764_842824583.dbf ! -newer 1_1768_842824583.dbf -print > filelist1.txt

while read inputline
        do
        file=`echo $inputline | cut -c3-`
        echo $file >> filelist2.txt
done < filelist1.txt

filelist=`tr '\n' ' ' < filelist2.txt`
password="lkjh1234"

function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    set filelist2 \"$filelist\"
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

expect_password 'scp $filelist2 oracle@10.10.10.10:/oarch/adb/'

Earlier the problem was variable value substitution in

Code:

expect_password 'scp $filelist2 oracle@10.10.10.10:/oarch/adb/'
As a workaround i now have set its value in expect function as below ,

Code:


function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    set filelist2 \"$filelist\"
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

Now the error code is as below ,

Code:


bash-3.2$ ./mov3.sh
spawn scp 1_1765_842824583.dbf 1_1766_842824583.dbf 1_1767_842824583.dbf 1_1768_842824583.dbf  oracle@10.10.10.10:/oarch/adb/
oracle@10.10.10.10's password:
1_1765_842824583.dbf 1_1766_842824583.dbf 1_1767_842824583.dbf 1_1768_842824583.dbf : No such file or directory

Regards,
Nitin

pan64 07-08-2014 08:26 AM

whould be nice to see the whole script...
expect_password 'scp '$filelist' oracle@10.10.10.10:/oarch/adb/'
should work if the variable $filelist contains the list of the files. Something has been mixed....

cnitin 07-08-2014 08:42 AM

Hi Pan64,

Thanks for your prompt replies.

Below is the code now.

Code:

> filelist1.txt
> filelist2.txt
> filelist3.txt
> filelist4.txt

cd /arch/AMERIDB/

#find . -type f -newer 1_1764_842824583.dbf ! -newer 1_1768_842824583.dbf -print > filelist1.txt
echo 1_1764_842824583.dbf > filelist1.txt
#while read inputline
#        do
#        file=`echo $inputline | cut -c3-`
#      echo $file >> filelist2.txt
#done < filelist1.txt

filelist=`tr '\n' ' ' < filelist1.txt`
password="lkjh1234"
function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    set filelist2 \"$filelist\"
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

expect_password 'scp /arch/ADB/$filelist2 oracle@10.10.10.10:/oarch/adb/'
#expect_password 'scp 1_1764_842824583.dbf oracle@10.10.10.10:/oarch/adb/'

And the output is as below,
to avoid the error which i got in previous comment , i have now given whole path.

Code:

bash-3.2$ ./mov3.sh
spawn scp /arch/ADB/1_1764_842824583.dbf  oracle@10.10.10.10:/oarch/adb/
oracle@10.10.10.10's password:
/arch/ADB/1_1764_842824583.dbf : No such file or directory

Regards,
Nitin

cnitin 07-08-2014 11:55 PM

Quote:

Originally Posted by pan64 (Post 5200488)
whould be nice to see the whole script...
expect_password 'scp '$filelist' oracle@10.10.10.10:/oarch/adb/'
should work if the variable $filelist contains the list of the files. Something has been mixed....

Hi Pan64,

I got below code working , Looks like scp is not accepting multiple files

Code:

> filelist1.txt
> filelist2.txt
> filelist3.txt
> filelist4.txt

cd /arch/AMERIDB/

find . -type f -newer 1_1775_842824583.dbf ! -newer 1_1778_842824583.dbf -print > filelist1.txt
#cat filelist1.txt
echo "1_1775_842824583.dbf" > filelist1.txt
#while read inputline
#        do
#        file=`echo $inputline | cut -c3-`
#        echo "\"$file\"" >> filelist2.txt
#done < filelist1.txt

#filelist=`tr '\n' ' ' < filelist2.txt`
filelist=`cat filelist1.txt`
password="lkjh1234"

echo $filelist

function expect_password {
    expect -c "\
    set timeout 90
    set env(TERM)
    set filelist2 \"$filelist\"
    spawn $1
    expect \"*password:\"
    send \"$password\r\"
    expect eof
  "
}

#expect_password 'filelist2'
expect_password 'scp $filelist2 oracle@10.10.10.10:/oarch/adb/'
#expect_password 'scp 1_1764_842824583.dbf oracle@10.10.10.10:/oarch/adb/'

Regards,
Nitin Chauhan

pan64 07-09-2014 12:22 AM

No, I'm really sorry, but I think scp supports copying several files "in one".
http://expert-mode.blogspot.hu/2011/...ple-files.html

You need to insert set -xv at the beginning of your script and see the result. (this will not influence the script just will print a lot of information about execution).

The problem I saw is: /arch/ADB/$filelist2 is not an acceptable syntax. (this can work only if filelist2 contains one file)

cnitin 07-09-2014 12:52 AM

Quote:

Originally Posted by pan64 (Post 5200905)
No, I'm really sorry, but I think scp supports copying several files "in one".
http://expert-mode.blogspot.hu/2011/...ple-files.html

You need to insert set -xv at the beginning of your script and see the result. (this will not influence the script just will print a lot of information about execution).

The problem I saw is: /arch/ADB/$filelist2 is not an acceptable syntax. (this can work only if filelist2 contains one file)

Hi Pan64,

Thanks for your help.

Working code is as below.

I have put the whole expect function inside a while loop.

Code:


> filelist1.txt

cd /arch/AMERIDB/

find . -type f -newer 1_1775_842824583.dbf ! -newer 1_1778_842824583.dbf -print > filelist1.txt
while read inputline
        do
        file=`echo $inputline | cut -c3-`
        password="lkjh1234"

        function expect_password {
        expect -c "\
        set timeout 90
        set env(TERM)
        set filelist \"$file\"
        spawn $1
        expect \"*password:\"
        send \"$password\r\"
        expect eof
        "
        }

        expect_password 'scp $filelist oracle@10.10.10.10:/oarch/adb/'

done < filelist1.txt

Regards,
Nitin


All times are GMT -5. The time now is 07:31 PM.