Use of expect to run scripts on remote machine

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
-2
down vote

favorite












I have automated most of the information required for the completion of this project but the only thing that is lagging is the running of local shell scripts on the remote machine.



As we are aware that no Linux command is recognized by the script that uses the 'expect' library.



Here in we have two use cases that I have tried:




  1. Running the desired list of commands on the remote server using only one expect script which has both the script execution as well as pushing of output using scp to the local machine, here is a snippet of this code:



    chmod 777 localscript.sh
    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    set timeout $timevalue
    spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    chmod 777 script1.sh
    ./script1.sh $password $2 $timevalue



  2. Running the desired list of commands on the remote server in a separate expect script and using scp to get files in a different script:



    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    cat > script2.sh <<- "ALL2"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL2
    chmod 777 localscript.sh script1.sh script2.sh
    ./script1.sh $password $2 $timevalue
    sleep 5
    ./script2.sh $password $2 $timevalue


==========================



I believe the above codes should both be valid in their own respect, however, the output for the same seem to be quite unexpected:




  1. Both the commands ssh and scp are being executed almost simultaneously after the password is entered hence, it is not giving localscript enough time to do its job, here's the output I see:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password: spawn /usr/bin/scp username@1.2.3.4:"/home/some/file/*" /another/file/
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Please note: This functionality is working fine without the involvement of 'expect'




  1. Here we are executing ssh and scp separately, however, it seems like it is unable to recognize that the file localscript.sh exists:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    bash: localscript.sh: No such file or directory
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Any feedback on the same would be appreciated, I think the first approach might be a feasible solution, except the fact that spawn is too fast and none of the 'sleep' or 'after' commands are helping/working. I think the second approach is also valid however it seems like there is a different way of running a local script on a remote server than the usual way we do on Linux when using 'expect'.










share|improve this question























  • Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
    – user307080
    Aug 23 at 14:36














up vote
-2
down vote

favorite












I have automated most of the information required for the completion of this project but the only thing that is lagging is the running of local shell scripts on the remote machine.



As we are aware that no Linux command is recognized by the script that uses the 'expect' library.



Here in we have two use cases that I have tried:




  1. Running the desired list of commands on the remote server using only one expect script which has both the script execution as well as pushing of output using scp to the local machine, here is a snippet of this code:



    chmod 777 localscript.sh
    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    set timeout $timevalue
    spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    chmod 777 script1.sh
    ./script1.sh $password $2 $timevalue



  2. Running the desired list of commands on the remote server in a separate expect script and using scp to get files in a different script:



    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    cat > script2.sh <<- "ALL2"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL2
    chmod 777 localscript.sh script1.sh script2.sh
    ./script1.sh $password $2 $timevalue
    sleep 5
    ./script2.sh $password $2 $timevalue


==========================



I believe the above codes should both be valid in their own respect, however, the output for the same seem to be quite unexpected:




  1. Both the commands ssh and scp are being executed almost simultaneously after the password is entered hence, it is not giving localscript enough time to do its job, here's the output I see:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password: spawn /usr/bin/scp username@1.2.3.4:"/home/some/file/*" /another/file/
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Please note: This functionality is working fine without the involvement of 'expect'




  1. Here we are executing ssh and scp separately, however, it seems like it is unable to recognize that the file localscript.sh exists:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    bash: localscript.sh: No such file or directory
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Any feedback on the same would be appreciated, I think the first approach might be a feasible solution, except the fact that spawn is too fast and none of the 'sleep' or 'after' commands are helping/working. I think the second approach is also valid however it seems like there is a different way of running a local script on a remote server than the usual way we do on Linux when using 'expect'.










share|improve this question























  • Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
    – user307080
    Aug 23 at 14:36












up vote
-2
down vote

favorite









up vote
-2
down vote

favorite











I have automated most of the information required for the completion of this project but the only thing that is lagging is the running of local shell scripts on the remote machine.



As we are aware that no Linux command is recognized by the script that uses the 'expect' library.



Here in we have two use cases that I have tried:




  1. Running the desired list of commands on the remote server using only one expect script which has both the script execution as well as pushing of output using scp to the local machine, here is a snippet of this code:



    chmod 777 localscript.sh
    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    set timeout $timevalue
    spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    chmod 777 script1.sh
    ./script1.sh $password $2 $timevalue



  2. Running the desired list of commands on the remote server in a separate expect script and using scp to get files in a different script:



    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    cat > script2.sh <<- "ALL2"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL2
    chmod 777 localscript.sh script1.sh script2.sh
    ./script1.sh $password $2 $timevalue
    sleep 5
    ./script2.sh $password $2 $timevalue


==========================



I believe the above codes should both be valid in their own respect, however, the output for the same seem to be quite unexpected:




  1. Both the commands ssh and scp are being executed almost simultaneously after the password is entered hence, it is not giving localscript enough time to do its job, here's the output I see:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password: spawn /usr/bin/scp username@1.2.3.4:"/home/some/file/*" /another/file/
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Please note: This functionality is working fine without the involvement of 'expect'




  1. Here we are executing ssh and scp separately, however, it seems like it is unable to recognize that the file localscript.sh exists:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    bash: localscript.sh: No such file or directory
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Any feedback on the same would be appreciated, I think the first approach might be a feasible solution, except the fact that spawn is too fast and none of the 'sleep' or 'after' commands are helping/working. I think the second approach is also valid however it seems like there is a different way of running a local script on a remote server than the usual way we do on Linux when using 'expect'.










share|improve this question















I have automated most of the information required for the completion of this project but the only thing that is lagging is the running of local shell scripts on the remote machine.



As we are aware that no Linux command is recognized by the script that uses the 'expect' library.



Here in we have two use cases that I have tried:




  1. Running the desired list of commands on the remote server using only one expect script which has both the script execution as well as pushing of output using scp to the local machine, here is a snippet of this code:



    chmod 777 localscript.sh
    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    set timeout $timevalue
    spawn /usr/bin/scp username@$2:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    chmod 777 script1.sh
    ./script1.sh $password $2 $timevalue



  2. Running the desired list of commands on the remote server in a separate expect script and using scp to get files in a different script:



    cat > script1.sh <<- "ALL"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh
    expect "assword:"
    send "$passwordr"
    interact
    ALL
    cat > script2.sh <<- "ALL2"
    #!/usr/bin/expect
    set password [lindex $argv 0];
    set ipaddress [lindex $argv 1];
    set timevalue [lindex $argv 2];
    set timeout $timevalue
    spawn /usr/bin/scp username@ipaddress:"/path/from/source/*" /path/to/destination/folder/
    expect "assword:"
    send "$passwordr"
    interact
    ALL2
    chmod 777 localscript.sh script1.sh script2.sh
    ./script1.sh $password $2 $timevalue
    sleep 5
    ./script2.sh $password $2 $timevalue


==========================



I believe the above codes should both be valid in their own respect, however, the output for the same seem to be quite unexpected:




  1. Both the commands ssh and scp are being executed almost simultaneously after the password is entered hence, it is not giving localscript enough time to do its job, here's the output I see:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password: spawn /usr/bin/scp username@1.2.3.4:"/home/some/file/*" /another/file/
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Please note: This functionality is working fine without the involvement of 'expect'




  1. Here we are executing ssh and scp separately, however, it seems like it is unable to recognize that the file localscript.sh exists:



    spawn /usr/bin/ssh username@1.2.3.4 /bin/bash < ./localscript.sh
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    bash: localscript.sh: No such file or directory
    Warning private system unauthorized users will be prosecuted.
    username@1.2.3.4's password:
    scp: /home/some/file/*: No such file or directory


Any feedback on the same would be appreciated, I think the first approach might be a feasible solution, except the fact that spawn is too fast and none of the 'sleep' or 'after' commands are helping/working. I think the second approach is also valid however it seems like there is a different way of running a local script on a remote server than the usual way we do on Linux when using 'expect'.







linux shell-script remote expect






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 23 at 15:51

























asked Aug 23 at 14:29









user307080

11




11











  • Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
    – user307080
    Aug 23 at 14:36
















  • Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
    – user307080
    Aug 23 at 14:36















Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
– user307080
Aug 23 at 14:36




Sorry about that, I raised that query in one of my udemy courses but was not able to find a response so I copied the same here, sorry for not truncating that information.
– user307080
Aug 23 at 14:36










1 Answer
1






active

oldest

votes

















up vote
0
down vote













Some notes:



  • the expect shebang line is wrong: # #!/usr/bin/expect should be just #!/usr/bin/expect

  • you ssh into a remote host, but you scp from your local machine. Is this what you intend?

    • if not, the 2nd spawn should be send instead.

    • I suspect this is the source of the scp "file not found" errors.


  • you use $2 instead of $ipaddress

  • if you don't intend to actually interact with the spawned process, wait for it to end with expect eof not interact

  • your shell script creates "script1.sh" and "script2.sh" but does not create "localscript.sh"

  • ".sh" is not a descriptive extension for expect code: ".exp" would be better

  • quote all shell variables: ./script1.sh "$password" "$2" "$timevalue"


I'd write that like this. Obviously untested:



#!/bin/bash
export password=$1
export ipaddress=$2
export timevalue=$3:--1 # use default -1 if not specified

[[ -z "$password" ]] && echo "Error: missing password"; exit 1;
[[ -z "$ipaddress" ]] && echo "Error: missing IP address"; exit 1;

/usr/bin/expect -d <<END_EXPECT
set timeout $env(timevalue)

spawn sh -c "/usr/bin/ssh username@$env(ipaddress) /bin/bash < ./localscript.sh"
expect "assword:"
send "$env(password)r"
expect eof

spawn /usr/bin/scp username@$env(ipaddress):"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$env(password)r"
expect eof
END_EXPECT


I added the -d option which turns on debug output for expect. Remove it when no longer needed.



The problem is that the spawn command does not know how to do the shell redirection: spawn is receiving the arguments "ssh", "user@host", "/bin/bash", "<" (a literal less-than), and "./localhost.sh". I'm explicitly executing that ssh command with a shell here so that the redirection can be done correctly.






share|improve this answer






















  • Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
    – user307080
    Aug 23 at 15:53











  • -The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
    – user307080
    Aug 23 at 16:00











  • -Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
    – user307080
    Aug 23 at 16:01










  • Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
    – user307080
    Aug 24 at 14:18










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f464419%2fuse-of-expect-to-run-scripts-on-remote-machine%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













Some notes:



  • the expect shebang line is wrong: # #!/usr/bin/expect should be just #!/usr/bin/expect

  • you ssh into a remote host, but you scp from your local machine. Is this what you intend?

    • if not, the 2nd spawn should be send instead.

    • I suspect this is the source of the scp "file not found" errors.


  • you use $2 instead of $ipaddress

  • if you don't intend to actually interact with the spawned process, wait for it to end with expect eof not interact

  • your shell script creates "script1.sh" and "script2.sh" but does not create "localscript.sh"

  • ".sh" is not a descriptive extension for expect code: ".exp" would be better

  • quote all shell variables: ./script1.sh "$password" "$2" "$timevalue"


I'd write that like this. Obviously untested:



#!/bin/bash
export password=$1
export ipaddress=$2
export timevalue=$3:--1 # use default -1 if not specified

[[ -z "$password" ]] && echo "Error: missing password"; exit 1;
[[ -z "$ipaddress" ]] && echo "Error: missing IP address"; exit 1;

/usr/bin/expect -d <<END_EXPECT
set timeout $env(timevalue)

spawn sh -c "/usr/bin/ssh username@$env(ipaddress) /bin/bash < ./localscript.sh"
expect "assword:"
send "$env(password)r"
expect eof

spawn /usr/bin/scp username@$env(ipaddress):"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$env(password)r"
expect eof
END_EXPECT


I added the -d option which turns on debug output for expect. Remove it when no longer needed.



The problem is that the spawn command does not know how to do the shell redirection: spawn is receiving the arguments "ssh", "user@host", "/bin/bash", "<" (a literal less-than), and "./localhost.sh". I'm explicitly executing that ssh command with a shell here so that the redirection can be done correctly.






share|improve this answer






















  • Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
    – user307080
    Aug 23 at 15:53











  • -The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
    – user307080
    Aug 23 at 16:00











  • -Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
    – user307080
    Aug 23 at 16:01










  • Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
    – user307080
    Aug 24 at 14:18














up vote
0
down vote













Some notes:



  • the expect shebang line is wrong: # #!/usr/bin/expect should be just #!/usr/bin/expect

  • you ssh into a remote host, but you scp from your local machine. Is this what you intend?

    • if not, the 2nd spawn should be send instead.

    • I suspect this is the source of the scp "file not found" errors.


  • you use $2 instead of $ipaddress

  • if you don't intend to actually interact with the spawned process, wait for it to end with expect eof not interact

  • your shell script creates "script1.sh" and "script2.sh" but does not create "localscript.sh"

  • ".sh" is not a descriptive extension for expect code: ".exp" would be better

  • quote all shell variables: ./script1.sh "$password" "$2" "$timevalue"


I'd write that like this. Obviously untested:



#!/bin/bash
export password=$1
export ipaddress=$2
export timevalue=$3:--1 # use default -1 if not specified

[[ -z "$password" ]] && echo "Error: missing password"; exit 1;
[[ -z "$ipaddress" ]] && echo "Error: missing IP address"; exit 1;

/usr/bin/expect -d <<END_EXPECT
set timeout $env(timevalue)

spawn sh -c "/usr/bin/ssh username@$env(ipaddress) /bin/bash < ./localscript.sh"
expect "assword:"
send "$env(password)r"
expect eof

spawn /usr/bin/scp username@$env(ipaddress):"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$env(password)r"
expect eof
END_EXPECT


I added the -d option which turns on debug output for expect. Remove it when no longer needed.



The problem is that the spawn command does not know how to do the shell redirection: spawn is receiving the arguments "ssh", "user@host", "/bin/bash", "<" (a literal less-than), and "./localhost.sh". I'm explicitly executing that ssh command with a shell here so that the redirection can be done correctly.






share|improve this answer






















  • Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
    – user307080
    Aug 23 at 15:53











  • -The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
    – user307080
    Aug 23 at 16:00











  • -Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
    – user307080
    Aug 23 at 16:01










  • Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
    – user307080
    Aug 24 at 14:18












up vote
0
down vote










up vote
0
down vote









Some notes:



  • the expect shebang line is wrong: # #!/usr/bin/expect should be just #!/usr/bin/expect

  • you ssh into a remote host, but you scp from your local machine. Is this what you intend?

    • if not, the 2nd spawn should be send instead.

    • I suspect this is the source of the scp "file not found" errors.


  • you use $2 instead of $ipaddress

  • if you don't intend to actually interact with the spawned process, wait for it to end with expect eof not interact

  • your shell script creates "script1.sh" and "script2.sh" but does not create "localscript.sh"

  • ".sh" is not a descriptive extension for expect code: ".exp" would be better

  • quote all shell variables: ./script1.sh "$password" "$2" "$timevalue"


I'd write that like this. Obviously untested:



#!/bin/bash
export password=$1
export ipaddress=$2
export timevalue=$3:--1 # use default -1 if not specified

[[ -z "$password" ]] && echo "Error: missing password"; exit 1;
[[ -z "$ipaddress" ]] && echo "Error: missing IP address"; exit 1;

/usr/bin/expect -d <<END_EXPECT
set timeout $env(timevalue)

spawn sh -c "/usr/bin/ssh username@$env(ipaddress) /bin/bash < ./localscript.sh"
expect "assword:"
send "$env(password)r"
expect eof

spawn /usr/bin/scp username@$env(ipaddress):"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$env(password)r"
expect eof
END_EXPECT


I added the -d option which turns on debug output for expect. Remove it when no longer needed.



The problem is that the spawn command does not know how to do the shell redirection: spawn is receiving the arguments "ssh", "user@host", "/bin/bash", "<" (a literal less-than), and "./localhost.sh". I'm explicitly executing that ssh command with a shell here so that the redirection can be done correctly.






share|improve this answer














Some notes:



  • the expect shebang line is wrong: # #!/usr/bin/expect should be just #!/usr/bin/expect

  • you ssh into a remote host, but you scp from your local machine. Is this what you intend?

    • if not, the 2nd spawn should be send instead.

    • I suspect this is the source of the scp "file not found" errors.


  • you use $2 instead of $ipaddress

  • if you don't intend to actually interact with the spawned process, wait for it to end with expect eof not interact

  • your shell script creates "script1.sh" and "script2.sh" but does not create "localscript.sh"

  • ".sh" is not a descriptive extension for expect code: ".exp" would be better

  • quote all shell variables: ./script1.sh "$password" "$2" "$timevalue"


I'd write that like this. Obviously untested:



#!/bin/bash
export password=$1
export ipaddress=$2
export timevalue=$3:--1 # use default -1 if not specified

[[ -z "$password" ]] && echo "Error: missing password"; exit 1;
[[ -z "$ipaddress" ]] && echo "Error: missing IP address"; exit 1;

/usr/bin/expect -d <<END_EXPECT
set timeout $env(timevalue)

spawn sh -c "/usr/bin/ssh username@$env(ipaddress) /bin/bash < ./localscript.sh"
expect "assword:"
send "$env(password)r"
expect eof

spawn /usr/bin/scp username@$env(ipaddress):"/path/from/source/*" /path/to/destination/folder/
expect "assword:"
send "$env(password)r"
expect eof
END_EXPECT


I added the -d option which turns on debug output for expect. Remove it when no longer needed.



The problem is that the spawn command does not know how to do the shell redirection: spawn is receiving the arguments "ssh", "user@host", "/bin/bash", "<" (a literal less-than), and "./localhost.sh". I'm explicitly executing that ssh command with a shell here so that the redirection can be done correctly.







share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 23 at 18:29


























community wiki





3 revs
glenn jackman












  • Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
    – user307080
    Aug 23 at 15:53











  • -The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
    – user307080
    Aug 23 at 16:00











  • -Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
    – user307080
    Aug 23 at 16:01










  • Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
    – user307080
    Aug 24 at 14:18
















  • Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
    – user307080
    Aug 23 at 15:53











  • -The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
    – user307080
    Aug 23 at 16:00











  • -Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
    – user307080
    Aug 23 at 16:01










  • Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
    – user307080
    Aug 24 at 14:18















Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
– user307080
Aug 23 at 15:53





Hi Glenn, Thank you for the response. -The Shebang is wrong because I was not aware of the coding indentations in this platform as the '#' was leading to a bigger format so I had to use two '#' in order to get the appropriate display. -I intend to ssh to a remote host to execute the script localscript.sh on that host and the output will be redirected to a file which will be pushed back to the local machine
– user307080
Aug 23 at 15:53













-The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
– user307080
Aug 23 at 16:00





-The reason for scp "not found" error is because the folder from where the file has to copied is empty because the operations performed by the localscript.sh takes time to execute which was not provided by second spawn command - I am using $2 because my main script will have the argument of the ipaddress -I will try using eof instead of interact -localscript.sh is a part of the main programme which I have not shared in this post since this is just a snippet of the code where I see the issue. The rest of it works as expected.
– user307080
Aug 23 at 16:00













-Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
– user307080
Aug 23 at 16:01




-Sure, I will work on the 'exp' and the quoted remarks mentioned and will let you know if that helps. Thank you so much for your inputs.
– user307080
Aug 23 at 16:01












Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
– user307080
Aug 24 at 14:18




Hi Glenn, Thank you so for the response. You were spot on with the inclusion of sh -c "/usr/bin/ssh username@$ipaddress /bin/bash < ./localscript.sh" This helped me in solving the first part of the puzzle and later, I added 'expect eof' instead of interact. The reason I was getting scp "not found" was because I was using quotes while specifying the path which was literally taking * as the filename. After the quotes were removed, I was able to get the desired output. It seems like this anomaly is seen while using spawn as the desired output was seen using quotes manually.
– user307080
Aug 24 at 14:18

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f464419%2fuse-of-expect-to-run-scripts-on-remote-machine%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?