Using an expect Script to send the output of a command and store in a file - buffer

Hi I am trying to store the output of a command run through a spawn ssh remote window into my local host, I am new to expect and am not able to figure out where I am wrong.
My Code:
#!/bin/bash
while read line
do
/usr/bin/expect <<EOD
spawn ssh mininet#$line
expect "assword:"
send -- "mininet\r"
set output [open "outputfile.txt" "a+"]
expect "mininet#mininet-vm:*"
send -- "ls\r"
set outcome $expect_out(buffer)
send "\r"
puts $output "$outcome"
close $output
expect "mininet#mininet-vm:*"
send -- "exit\r"
interact
expect eof
EOD
done <read_ip.txt
I am getting the error
expect: spawn id exp6 not open
while executing
"expect "mininet#mininet-vm:*""
Please can any body help me on this code.

You have your expect program in a shell heredoc. The shell will expand variables in the heredoc before launching expect. You have to protect expect's variables from the shell.
One way is to use a 'quoted' heredoc, and pass the shell variable to expect through the environment:
#!/bin/bash
export host ## an environment variable
while read host
do
/usr/bin/expect <<'EOD' ## note the quotes here
spawn ssh mininet#$env(host) ## get the value from the environment
expect "assword:"
send -- "mininet\r"
set output [open "outputfile.txt" "a+"]
expect "mininet#mininet-vm:*"
send -- "ls\r"
set outcome $expect_out(buffer)
send "\r"
puts $output "$outcome"
close $output
expect "mininet#mininet-vm:*"
send -- "exit\r"
expect eof ## don't want both "interact" and "expect eof"
EOD
done <read_ip.txt
Putting single quotes around the heredoc terminator means the whole heredoc acts like a single quoted string, and expect's variables are left for expect to handle.
You might also investigate the expect log_file command: you can enable and disable logging at will, much as you are doing manually here.

Related

Lua: forward output from Minicom

I have a Lua script and in there I open a minicom session which executes a script (with the -S" parameter).
local myFile = assert(io.popen('minicom -S myScript.sh ' myDevice ' -C myLogFile.log'))
local myFileOutput = myFile:read('*all')
myFile:close()
This works really fine.
But I would like to get the same output as if I execute the minicom command itself:
minicom -S myScript.sh ' myDevice ' -C myLogFile.log
Right now I don't get any output at all (I know that that's somehow obvious).
I would that the output should also occur at (at least nearly) the same time as with the minicom command itself. Not one big chuck of data at the end.
Does anyone know how to achieve that?
If I understand you correctly, you need something like
local myFile = assert(io.popen('minicom ...'))
for line in myFile:lines('l') do
print(line)
end
myFile:close()

variable does not exist in sas data set

I am trying to check whether variable GROUP exist in SAS data set file or not from the UNIX command but unfortunately it's showing that GROUP variable does not exist in the data set,However GROUP variable is present in SAS data set.
In my command for case sensitive and whole word match I am using i and w options of grep command respectively. But still UNIX command is not giving the expected result.I s there any way to fix this issue?
Below is the command which I am using:
sasfile="sasdata"
rwords="GROUP"
cat $sasfile | grep -iqw "$rwords"
Thank you
As mentioned in earlier comment
SAS data sets are stored in disk files using a proprietary format.
There may be encodings and storage methodologies that do not yield the
information you seek in a plain text examination of said disk file.
Running SAS code in a SAS session is the definitive way to glean information about a data set.
What will that code look like ?
Proc CONTENTS
Data step or macro code that uses VARNAME function
... many other ways ...
In UNIX SAS can use stdio.
From "SAS(R) 9.2 Companion for UNIX Environments", STDIO System Option: UNIX
Details
This option tells SAS to take its input from standard input (stdin),
to write its log to standard error (stderr), and to write its output
to standard output (stdout).
This option is designed for running SAS
in batch mode or from a shell script. If you specify this option
interactively, SAS starts a line mode session.
The STDIO option
overrides the DMS, DMSEXP, and EXPLORER system options. The STDIO
option does not affect the assignment of the Stdio, Stdin, and Stderr
filerefs. See Filerefs Assigned by SAS in UNIX Environments for more
information.
For example, in the following SAS command, the file
myinput is used as the source program, and files myoutput and mylog
are used for the procedure output and log respectively.
sas -stdio < myinput > myoutput 2> mylog
If you are using the C shell, you should
use parentheses:
(sas -stdio < myinput > myoutput ) >& output_log
With -stdio you want a short SAS program that can indicate if a variable is present in a data set, or perhaps emit a list of variables in a data set for further shell processing. A Proc CONTENTS step is short and sweet.
So looking for your proverbial needle in a haystack
sasfile=<path to data set file>/<dataset>.sas7bdat
needle=GROUP
echo "Proc CONTENTS data=""$sasfile""" | sas -stdio | grep $needle
The default CONTENTS output might contain yield some false matches. So you could also try
echo "Proc CONTENTS noprint data=""$sasfile"" out=list;data _null_;set list;file print;put name;"
| sas -stdio
| grep -i "GROUP"
You could try:
sasfile="sasdata"
rwords="GROUP"
grep -iw "$rwords" "$sasfile"
The only difference between these and your original commands is that I omitted cat and grep's quiet flag -q.
Sample input in sasdata:
fasd group
fdsfds fdsfdsa
fdsfd as GROUP afdsfdsa
Output:
fasd group
fdsfd as GROUP afdsfdsa
The -q flag of grep will suppress standard output but echo $? can retrieve the return value of grep. Using the same input file as before:
grep -iqw "$rwords" "$sasfile" # No stout
echo $? # Prints 0, means grep succeeded
grep -iqw "word" "$sasfile" # No stout
echo $? # Prints 1, means grep failed

expect output only stdout of the command and nothing else

How to write expect script which executes command and prints just the command's output?
I've tried various things but none works, e.g.
#!/usr/bin/expect
log_user 0
spawn bash
send "echo 1\r"
log_user 1
expect "1"
log_user 0
send "exit\r"
expect eof
Gives in output:
echo 1
While I need just "1" . I hope somebody knows simple solution how to fix my example
Capturing the output from sent commands is a bit of a pain in expect.
Here's a more general case that does not rely on the log_user setting, it captures the output with a regular expression:
#!/usr/bin/expect
log_user 0
spawn bash
# set the prompt to a known value
send "PS1='>'\r"
expect -re {>$}
# send a command: we don't know what the output is going to be
send "echo \$RANDOM\r"
# capture the portion of the output that occurs just before the prompt
expect -re "\r\n(.*?)\r\n>$"
puts "output is: $expect_out(1,string)"
send "exit\r"
expect eof
A thought just occurred to me: if the command does not require any interaction, then expect is overkill: just use exec
set output [exec bash -c {echo $RANDOM}]
Ok, it looks following script does (at least similar to) what I need:
log_user 0
spawn bash
expect "#" {} "\\\$" {}
send -- "echo AA\r"
expect -- "echo AA\r" {}
log_user 1
expect -- "AA"
log_user 0
send -- "exit\r"
expect eof

error while executing lua script for redis server

I was following this simple tutorial to try out a simple lua script
http://www.redisgreen.net/blog/2013/03/18/intro-to-lua-for-redis-programmers/
I created a simple hello.lua file with these lines
local msg = "Hello, world!"
return msg
And i tried running simple command
EVAL "$(cat /Users/rsingh/Downloads/hello.lua)" 0
And i am getting this error
(error) ERR Error compiling script (new function): user_script:1: unexpected symbol near '$'
I can't find what is wrong here and i haven't been able to find someone who has come across this.
Any help would be deeply appreciated.
Your problem comes from the fact you are executing this command from an interactive Redis session:
$ redis-cli
127.0.0.1:6379> EVAL "$(cat /path/to/hello.lua)" 0
(error) ERR Error compiling script (new function): user_script:1: unexpected symbol near '$'
Within such a session you cannot use common command-line tools like cat et al. (here cat is used as a convenient way to get the content of your script in-place). In other words: you send "$(cat /path/to/hello.lua)" as a plain string to Redis, which is not Lua code (of course), and Redis complains.
To execute this sample you must stay in the shell:
$ redis-cli EVAL "$(cat /path/to/hello.lua)" 0
"Hello, world!"
If you are coming from windows and trying to run a lua script you should use this format:
redis-cli --eval script.lua
Run this from the folder where your script is located and it will load a multi line file and execute it.
On the off chance that anyone's come to this from Windows instead, I found I had to do a lot of juggling to achieve the same effect. I had to do this:
echo “local msg = 'Hello, world!'; return msg” > hello.lua
for /F "delims=" %i in ('type hello.lua') do #set cmd=%i
redis-cli eval "%cmd%" 0
.. if you want it saved as a file, although you'll have to have all the content on one line. If you don’t just roll the content into a set command
set cmd=“local msg = 'Hello, world!'; return msg”
redis-cli eval "%cmd%" 0

PHP CLI doesn't use stderr to output errors

I'm running the PHP CLI through a NSTask in MacOS, but this question is more about the CLI itself.
I'm listening to the stderr pipe, but nothing is output there no matter what file I try to run:
If the file type is not a plain text, stdout sets to ?.
If the file is a php script with errors, the error messages are still printed to stdout.
Is there a switch to the interpreter to handle errors through stderr? Do I have an option to detect errors other than parsing stdout?
The display_errors directive (can be set everywhere) takes optionally the parameter "stderr" for it to report errors to stderr instead of stdout or completely disabled error output. Quoting from the PHP manual entry:
Value "stderr" sends the errors to stderr instead of stdout. The value is available as of PHP 5.2.4.
Alternatively if you're using the commandline interface and you want to output the errors your own you can re-use the command-line nput/output streams:
fwrite(STDERR, 'error message');
Here STDERR is an already opened stream to stderr.
Alternatively if you want to do it just for this script and not in CLI you can open a filed handler to php://stderr and write the error messages there.
$fe = fopen('php://stderr', 'w');
fwrite($fe, 'error message');
If you want the error messages sent by the php interpreter should go to the stderr-pipe, you must set display_errors to stderr
This is required to return from PHP realm into shell environment in order to parse properly error message. You still need to exit(1) or whatever integer in order to return exit status code from PHP to shell.
fwrite(STDERR, 'error message'); //output message into 2> buffer
exit(0x0a); //return error status code to shell
Then, your crontab entry will look like:
30 3 * * * /usr/bin/php /full/path/to/phpFile.php >> /logdir/fullpath/journal.log 2>> /logdir/fullpath/error_journal.log
You can also use file_put_contents() with "php://stderr" to output to standard error, like:
php -r 'file_put_contents("php://stderr", "Hiya, PHP!\n"); echo "Bye!\n";' 1>/dev/null
which outputs "Hiya, PHP!\n" to standard error and nothing to standard output when executed in a Bash shell.

Resources