How to start a shell script within "expect script"? - expect

In this expect script there will be no ssh server connected, I just want to execute a ".sh" file locally, is that possible?
For instance:
#!/bin/expect
command "xxx.sh" # a command which starts a certain shell script
Also, is it possible to execute a expect script within a expect script?
For instance:
#!/bin/expect
command "xxx.exp" # a command which starts a certain expect script
Any help?

If you need to interact with this script, use spawn xxx.sh
If you just need to run it and capture the output, use set output [exec xxx.sh]
Expect is an extension of the Tcl language, so you would be well served to go through the Tcl tutorial.

The command in Expect to run a shell command is spawn.
#!/bin/expect
spawn command arg1 arg2 ...
command can be any program -- a binary executable, a shell script, another expect script, etc. So you can do:
spawn xxx.sh
or:
spawn xxx.exp

Related

Write ActiveState Tcl Program for Windows that expects a password and enters it

I want to write a shell program in windows that runs another shell script and expects a password prompt from the Git bash terminal and inputs it.
This is what I have so far:
#!/bin/sh
# \
exec tclsh "$0" ${1+"$#"}
package require Expect
spawn sampleScript.sh
expect "Password:"
send "pass123"
sampleScript.sh code:
echo 'Hello, world.' >foo.txt
my program outputs the following:
'The operation completed successfully. while executing "spawn sampleScript.sh"
(file "compare.tcl" line 6)'
However, there is no foo.txt that is created in my local file folder where the scripts are. Can you help?
The key with expect programs is to let the spawned program exit gracefully. As it currently stands, after your expect script sends the password, it immediately exits, and that kills the spawned program too early.
If you don't need to interact with the sampleScript (i.e. just let it run to completion), the last line in the expect script should be
expect eof
Otherwise, use
interact
Read How to create a Minimal, Reproducible Example -- your updated code does not reproduce the error you're seeing
Tcl code:
when you send something, you usually need to "hit Enter": send "password\r"
Did you add expect eof to the Tcl script? If not, you might be killing sampleScript.sh before it has a chance to create the output file
sampleScript.sh: Is that really your sample script? Where's the password prompt?

Can i automate a shellscript that will run a python file which asks for user input?

I know how to run shell scripts pretty easily.
I would have my file say:
#!/bin/zsh
python somefile.py
but the file, somefile in this case requires an input. example:
What is the password?
Can you write a script which will enter that password, or have pause while it waits for input?
My goal overall, is to run a tunneling python script to build a connection and watch a port, pull some data through the tunnel, and then close the python script.
Ideally: I want to have this shellscript option somefile.py in an alternate terminal, as i dont know if i can just no-hup until it is no longer needed then kill the process.
First thing is first. Can you have script which will do something like:
#!/bin/zsh
python somefile.py
echo admin12345
or something similar to auto enter info?
Assuming the python script reads from stdin, just do "echo admin12345 | somefile.py".
Usually, however, that's not the case, and scripts that read passwords will want to read from a terminal, not just any stdin.
In that case, look into "expect".
It worked for me with java and python examples:
#!/bin/bash
echo "1234" | python somefile.py
Just give some permissions to your script chmod +x yourscript.sh, and run it ./yourscript.sh.

bash and expect interaction

#!/bin/bash
# Bash commands go here
/usr/bin/expect - << EndMark
This is the expect script
expect commands go here
and here
until:
EndMark
# More bash commands go here.
exit 0
Something like this will allow me to start an expect script from within bash. However when it gets to the More bash commands part, it will stop the expect process (and the processes it spawned) Is it possible to get back into the same expect script?
eg - Start expect script
- At a certain point leave the expect to bash operations
- return to the same expect script?
It is not necessary to leave the expect process in order to issue shell commands - you can use the system command from within the expect script.

Input to Expect Script

in my test file, I had this line hello$LG. So, if I do
`cat /test`
It will show in my bash shell - hello$LG
But when I try to do this in my expect script,
$> expect test.sh `cat /test`
It gives me this {hello$LG} . I don't know why it is getting {}. Anyone knows how to fix this?
Expect is based upon TCL, you should use square brackets to execute code. When trying to execute a shell command you should use either exec or open or spawn.
I am not sure what the test.sh does, but
expect [exec test.sh 'cat /test']
might just do the trick.
There's more on running other programs from Tcl here:
http://www.tcl.tk/man/tcl/tutorial/Tcl26.html

Auto SSH and execute script

I have roughly 12 computers that each have the same script on them. This script merely pings all the other machines, and prints out whether the machine is "reachable" or "unreachable". However, it is inefficient to login to each machine manually using ssh to execute this script.
Suppose I'm logged into node 1. Is there any way to for me to login to node 2-12 automatically using SSH, execute the ping script, pipe the results to a file, logout and proceed to the next machine? Some kind of bash shell script?
I'm afraid I'm at a loss here since I haven't had experience with shell-scripting before.
Since the script is on the other machines, you can just have ssh run the command for you there:
ssh $hostname my_script >> results_file
When you specify a command like that, it's executed instead of the login shell.
I'll leave it up to you to figure out how to loop over hostnames!
One trick you'll need to use is setting up pre-authorized keys for each host. Then you can run a script on one host, running something like 'ssh hostname command > log.hostname'
This script might be what you are looking for: It allows you to execute one command (which can be your script) on multiple remote machines via ssh. It's a simple script with bash source available, so you should be able to customize it to your needs:
http://www.heinzi.at/projects/upgradebest.sh/
Yes you can
You need actually 2 small scripts as following:
remote_ssh.sh ( which takes as first argument the name of the machine and the rest of the arguments are your script that you want to execute with his own arguments)
Example : remote_ssh.sh node5 "echo hello world"
remote_ssh.sh as following:
#!/bin/bash
ALL_ARG=$#
FST_ARG=$1
REST_ARG=${ALL_ARG##$FST_ARG}
echo "Executing REMOTE COMMAND ON $FST_ARG"
/usr/bin/ssh $FST_ARG bash execute_ssh_command.sh $FST_ARG pwd $REST_ARG
execute_ssh_command.sh as following :
#!/bin/bash
ALL_ARG=$#
FST_ARG=$1
DIR_ARG=$2
REM_ARG="$1 $2"
REST_ARG=${ALL_ARG##$REM_ARG}
cd $DIR_ARG
$REST_ARG
of course you have to get this 2 scripts in your path of all your nodes ( maybe ~/bin/ )
Hope that it's helpful

Resources