not found in shell to call expect - shell

i've installed expect,and checked the path not wrong(which expect)
my shell program is to call the rsync,here's the source code
#!/usr/bin/expect -f
set timeout -1
spawn rsync -ravz /home/mypath username#remotehost:/data/
expect "*password:"
send "mypassowrd\r"
interact
save it as aaa.sh
run the file
sh aaa.sh
the terminal give result
: not foundaaa.sh:
aaa.sh: 4: aaa.sh: spawn: not found
": no such file or directoryd:
aaa.sh: 6: aaa.sh: send: not found
: not foundaaa.sh: interact
set it executable and run it by
./aaa.sh
give the result
": no such file or directory
have no idea why this happens,seems the expect wouldn't be call in shell file.
directly type expect is ok,but doesn't make sense.

I believe that is because you are trying to interpret expect commands with sh.
What I would do is the following. Save your script with the standard expect file extension .exp (this is just for clarity), make it an executable, and then just run it from your shell.
mv aaa.sh aaa.exp
chmod u+x aaa.exp
./aaa.exp
You have already let your script know where the expect binary is located, so that should be enough for you.
Let me know how that works out for you.

Related

Bash wrapper for fortran code

I have a fortran code (wrote by somebody else - cannot change it...) that takes an input parameter file, executes it, then has an interactive prompt. This is how it works:
[user#host] ./mycode
Welcome; what is the file name? _
Once you give it the param file and hit enter, the program executes it and prompts options:
OPTIONS a=add something
u=undo
o=overplot
q=quit
You then interact with the code, and quit. The problem I have is that every time I quit the program and have to start over, I have to keep re-typing the param file name (which is a pain for long names). I would like to write a simple shell-script that would do:
./mycode_auto param_file
Then it would execute the param_file and give the prompt with options. My first naive attempt, which I knew it was missing something:
#!/bin/bash
./mycode << EOF
$1
EOF
It opens mycode, executes the param file, but breaks right after, and I get:
Fortran runtime error: End of file
I can actually understand what it happening, but don't know a way around it. Any ideas?
Thanks!
If you can not modify the fortran program, I believe your only solution will be to use expect. Have a look at the following script :
#!/usr/bin/expect -f
#we store the content of our 1st argument
set file_path [lindex $argv 0]
#process we need to interract with
spawn ./mycode
#if we encounter this message ...
expect "Welcome; what is the file name?" {
#... we send it our first argument
send "$file_path\r"
}
#we resume normal interaction with our script
interact
Simply call it like that : script.expect "/path/to/file", assuming the expect script and mycode are in the same folder.

How to change current work directory using expect script?

I want to write an expect script which can do some task and in the end change the directory and give control to the user. I tried using
spawn cd path\to\dir
interact
but i am still in the same directory.
Any leads on how to accomplish this using expect ?
To change the directory in an expect script, you don't need to use the keyword "spawn" it works without it.
You may be a little confused, because in the terminal, in which you are executing the script, you will stay in the same directory, but the script changed the directory in which it is doing things.
I suppose you have spawned some command (like ssh, bash) and the spawned command is still running. Then at the end you can do like this:
send "cd /some/dir\r"
interact

How to send a command using AppleScript to terminal one by one and save the output, which is not writable to file anywhere?

So, I have a problem. I have downloaded a program from the web. And it's a command line app. I have written a code, which generated some n-k commands to the app. I have written them into an output file. I can write an app in Python, but it freezes on some of the commands. I have tested them manually and seems like there are two issues:
Commands must be run one-by-one;
Some of the commands give an output like bla-bla-bla, this thing is not written into an output file. So, if I run a command ./app -p /file1 -o /file2 -s -a smth- > /fileOutput.txt The fileOutput.txt is empty, though in the terminal, there's is this bla-bla-bla message, stating, that something is wrong. If the command gives bla-bla-bla the app may freeze for a while.
Here is what I want to do:
CD into folder, the containing app;
For command in fileWithCommands perform command and start the next, only when the previous finishes;
If the command gives message, containing bla-bla-bla (cause it may look like file1 bla-bla-bla), write the command and this strange output into file badOutputs.txt.
Have never done applescript before. However, this's what I've done so far:
set theFile to "/Users/MeUser/Desktop/firstCommand"
set fileHandle to open for access theFile
set arrayCommand to paragraphs of (read fileHandle)
#I have found the previous code here: http://alvinalexander.com/mac-os-x/applescript-read-file-into-list-array-examples
close access fileHandle
tell application "Terminal"
activate
do script "cd /Users/MeUser/Desktop/anApp/"
repeat with command in arrayCommand
do script command
end repeat
end tell
Though there's a problem, if in one window the commands make up a huge queue. Without window 1 cd and the command are in different windows. And I am still unable to save the output.
UPDATE
Did with accordance to #Mark Setchell's recommendations. So now I have such code:
set theFile to "/Users/meUser/Desktop/firstCommand"
set fileHandle to open for access theFile
set arrayCommand to paragraphs of (read fileHandle)
close access fileHandle
repeat with command in arrayCommand
do shell script "cd /Users/meUser/Desktop/App/; " & command
end repeat
To the command I have added the following:
2>&1 /Users/meUser/Desktop/errorOut.txt
However, the apple script says that a mistake of the app is the mistake of the script. I.e.: file corrupted, app fails. I want it to write into error file where has it failed and move to the next command, while the script just fails.
Maybe not a complete solution, but more than a comment and easier to format this way...
First Issue
Your command-line app which writes on the Terminal may be writing to stderr rather than stdout. Try redirecting stderr to the same place as stdout by using
./app -p ... > /FileOutput.txt 2>&1
Second Issue
You cannot do:
do shell script cd somewhere
do shell script do_something
because each do shell script will execute in a separate, unrelated process. So your first process will start - in the default directory like all processes - and correctly change directory and then exit. Then your second process will start - in the default directory like all processes - and try to run your command. Rather than that, you can do this:
do shell script "cd somewhere; do_something"
which starts a single process which changes directory and then runs your command line program there.
Issue Three
Why do you want to send your commands to Terminal anyway? Does the user need to see something in Terminal - seems unlikely because you want to capture the output, don't you? Can't you just run your commands using do shell script?
Issue Four
If you want to keep your normal output separate from your error output, you can do:
./app ... params ... > OutputFile.txt 2> errors.txt
Suggestion 1
You can retain all the errors from all the scripts and accumulate them in a single file like this:
./app .. params .. >> results.txt 2>&1
That may enable you to deal with errors separately later.
Suggestion 2
You can capture the output of your shell script into an Applescript variable, say ScriptOutput, like this, then you can parse it:
set ScriptOutput to do shell script "..."
Suggestion 3
If errors caused by your script are stopping your loop, you can enclose them in a try block like this so they are handled and everything continues:
try
do shell script "..."
on error errMsg
display dialog "ERROR: " & errMsg
end try

rtorrent execute shell script

I can't figure out how to get output from shell script back to rtorrent after command has been executed.
Is it possible to return back output from exeternal command back to rtorrent session?
I use rtorrent scripting interface to auto execute shell command after torrent is finished
event line in .rtorrent.rc looks like this:
system.method.set_key = event.download.finished,mycustomcommand,"execute=~/myshellscript.sh"
myshellscript.sh file looks like this
#!/bin/sh
echo "Torrent finished!"
Is there a way to do this?
I'm not sure what you're searching for, but I found this on rtorrent's wiki site:
execute_capture_nothrow={command,arg1,arg2,...}
This will execute the external command with arguments arg1,arg2,.... It will return the
stdout output of the command.
system.method.set_key = event.download.finished,mycustomcommand,print="$execute_capture=/path/to/script"
should work, at least
print="$execute_capture=/path/to/script"
works when you do it inside rtorrent. If you want to store the output then intstead of print use d.custom1.set= if that helps.
You forgot to add parameters to the rtorrent.rc itself and also the bash script is incomplete according to me.
.rtorrent.rc line should have
method.set_key = event.download.finished,whatever,"execute2={/path/myscript.sh,$d.name=,$d.base_path=,$d.hash=}"
bash script
#!/bin/bash
TORRENT_NAME=1
TORRENT_PATH=2
TORRENT_HASH=3
touch "$1" Finished download!
exit
this will create touch file telling you particular file has finished downloading.

Logging terminal while running an install script of sorts

I have written an install script in shell that does some configuration of various things such as xserver, network, etc and then installs a few RPM's which is no problem. But I want to be able to log everything that goes to the terminal screen as well. Is this possible to do from within the script so if the end user runs ./Install.sh it will do everything (including the logging).
I have tried using "script" but doesn't work from within the Install.sh script itself.
Thanks
Just use:
script logfilename install.sh
when the install.sh finished the run, the script end too - so, you get everything logged into logfilename.
Probably you can make it two-stage, so, you should rename your current install.sh into install-stage2.sh and your install.sh will contain:
script ./install.log ./install-stage2.sh
UPDATE from my man script
NAME
script -- make typescript of terminal session
SYNOPSIS
script [-akq] [-t time] [file [command ...]]
DESCRIPTION
The script utility makes a typescript of everything printed on your terminal. It is useful for students who need
a hardcopy record of an interactive session as proof of an assignment, as the typescript file can be printed out
later with lpr(1).
If the argument file is given, script saves all dialogue in file. If no file name is given, the typescript is
saved in the file typescript.
If the argument command is given, script will run the specified command with an optional argument vector instead
of an interactive shell.

Resources