Im having trouble setting error level in an autohotkey script.
As of now, it works fine unless the putty session closes unexpectedly.
I am calling a sub after setting ip and password to reboot equipment via telnet.
Basically I need a message box to pop up and a return command instead of a crash
like
MsgBox, reboot of %IP% failed
return
havent been able to get it to work myself, so figured i'd ask here
Proximreboot:
{
SetKeyDelay, 10, 10
Run, C:\Program Files\PuTTY\putty.exe -load "script" telnet://%IP%, , , NewPID ; ------------run putty.exe also get a new PID
WinWaitActive, ahk_pid %NewPID%
Loop ;---------------------------- loop to look for password prompt in putty
{
Loop, read, C:\Program Files\PuTTY\%IP%.script.log ;----------loop to read the log file
last_line := A_LoopReadLine
IfInString, last_line, password
{
break
}
}
ControlSend, ,%PASS%{Enter},ahk_pid %NewPID%, , ,
Sleep, 1000
ControlSend, ,reboot 30{Enter},ahk_pid %NewPID%, , ,
Sleep, 1563
ControlSend, ,exit{Enter},ahk_pid %NewPID%, , ,
Sleep, 1000
filedelete, C:\Program Files\PuTTY\*.script.log
last_line := blank
}
return
I finally figured it out
Loop
{
Process, Exist, %NewPID%
Loop, read, C:\Program Files\PuTTY\%IP%.script.log
last_line := A_LoopReadLine
IfInString, last_line, password
{
break
}
if !errorlevel
{
MsgBox, Reboot of %IP% Failed.
Return
}
}
I don't know if I'm happier that I figured it out, or that a device timed out the first time I tested it.
Related
i've checked following URL: Lua os.execute return value
I've made a program with C which returns 111 or 222.
Here is part of my code.
if (stat == NULL)
{
system("echo \"stat is NULL\"");
return 111;
}
else
{
system("echo \"stat is NOT NULL\"");
return 222;
}
when i run this at Linux like this, ~/c-program; echo $?, it prints
stat is NULL
111
or,
stat is NOT NULL
222
at my terminal.
or like this,
~/c-program
echo $?
it also prints same way like ~/c-program; echo $?
I need to run that program via Lua. Here is part of my lua script.
local foo = io.popen(~/c-program; echo $?)
local bar = foo:read("*a")
foo:close()
if (tonumber(bar) == 111) then
os.execute("echo 111")
elseif (tonumber(bar) == 222) then
os.execute("echo 222")
else
os.execute("echo \"something is wrong\"")
os.execute("echo "..bar)
end
this prints like this
something is wrong
Even it has a script that prints the value of bar, it does not print.
I thought that ``os.execute("echo "..bar)``` syntax is wrong, but it's not.
i tried like this at https://www.lua.org/cgi-bin/demo
local bar = 111
if (tonumber(bar) == 111) then
print("bar is "..bar)
elseif (tonumber(bar) == 222) then
print("bar is "..bar)
else
print("something is wrong")
print("bar is "..bar)
end
it prints bar is 111. In case bar's value is 333, it also prints something is wrong
So, how should i do to use that c-program's return value as a Lua's variable?
local foo = io.popen(~/c-program; echo $?) looks wrong: popen expects a string, and I have no idea what that unquoted stuff will look like to the Lua parser.
If it did work, it would give "stat is NULL" or "stat is not NULL" followed by the exit code of the C program. It would be tricky to get the number from that, since tonumber will NOT skip past non-number text to find one. It would be simpler to get the exit code directly:
First, skip the echo $? part of the command, so that the shell call will just run the C program and nothing else.
If the Lua code doesn't need the output "stat is NULL" or "stat is not NULL", use just os.execute instead of io.popen.
Documentation for os.execute says
Its first result is true if the command terminated successfully, or fail otherwise. After this first result the function returns a string plus a number, as follows:
"exit": the command terminated normally; the following number is the exit status of the command.
"signal": the command was terminated by a signal; the following number is the signal that terminated the command.
And documentation for file:close() says
When closing a file handle created with io.popen, file:close returns the same values returned by os.execute.
So you should be able to do any one of
-- Don't need the output text, and allow c-program to print it.
local ok, how, code = os.execute("~/c-program")
-- OR, Don't need the output text, and make sure it's not printed anywhere.
local ok, how, code = os.execute("~/c-program >/dev/null")
-- OR, Need the output text within Lua
local foo = io.popen("~/c-program")
do_stuff(foo)
local ok, how, code = foo:close()
followed by
if how == "exit" then
if code == 111 then
print("Got 111")
elseif code == 222 then
print("Got 222")
else
print("Exited with code " .. code)
end
elseif how == "signal" then
print("Stopped by signal " .. code)
else
print("What happened?")
end
A Program can exit in two different ways...
An exit code like 0 (On Linux that means: OK - No Error)
Textoutput...
a) Normal: stdout
b) Error: stderr
With Lua you can produce an errorless exit code wit: os.exit(0)
And an Error with: os.exit(1)
Also, like in other languages, it is common to use echo or/and print to produce dynamic output i.e. like XML/HTML/CSS/Javascript code.
Example for returning error code 1 in Lua Standalone:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> rc = 1
> if rc ~= 0 then
>> io.output(io.stderr)
>> io.write('ERROR - EXIT\n')
>> os.exit(rc)
>> end
ERROR - EXIT
$ echo $?
1
$
...so in case of an error stderr is used to put out the errortext and the exit code of 1 can be used as a condition for further processing (in bash/shellscript).
Something to read about exit command and code...
https://linuxize.com/post/bash-exit/
Now lets check what os.execute() is returning...
> os.execute('echo "Hello World"')
Hello World
true exit 0
os.execute() is returning three values and you want the third one.
You can grab it then by defining three locals with os.execute() and use only the last one...
local one, two, three = os.execute('~/c-program')
print(three)
return three
I have the following code which I am trying to run, however the wait_for_connection() appears to be being run before the preceding 2 lines, and I can't seem to understand why? I really need the two preceding lines to be run before the wait_for_connection() function is called. Even if I enter a sleep(1) before calling the wait_for_connection() function, it is still run before the preceding lines.
My code is as follows:
void wait_for_connection() {
for (int i = 0; i < 10; i++) {
g_print("Checking server...\n");
if (connected == 1) {
g_print("Connected to: %s", selectedServerStr);
break;
}
sleep(1);
}
}
int connect_server(GtkButton *button, gpointer user_data) {
.......
if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selectedServer), &model, &iter)) {
path = gtk_tree_model_get_path(model, &iter);
serverIndex = *gtk_tree_path_get_indices(path);
g_print("Selected Server IP: %s\n", serverIPArray[serverIndex][0]);
gtk_widget_set_sensitive(serverList, FALSE); // These 2 lines needs to be run first
append_to_log("Attemping connection, please wait...", 1);
wait_for_connection(); // This is where the error lies, this runs before the above 2 lines
return 1;
} else {
gtk_widget_set_name(serverBox, "fieldsError");
g_print("No server selected: Aborting...\n");
return -1;
}
}
The line gtk_widget_set_sensitive() is used to disable user interaction of a selection widget, however this doesn't seem to happen until after the wait_for_connection() function has finished printing "Checking server..." 10 times. The value connected is 0, so currently the function just print "Checking server..." 10 times.
Does anyone have any idea as to what may be happening? Any help would be greatly appreciated, thanks.
GUI applications on almost all platforms are event-driven. They need their event-handling functions to execute at regular interval, or the user-interface will seem unresponsive and maybe even seem like it locks up or nothing is happening.
In your wait_for_connection you have a loop which can iterate up to ten times, and each iteration you will do sleep(1) which sleeps a whole second. While this loop is iterating and sleeping, the event-handling will not happen, and as mentioned that will make it seem like your user-interface is unresponsive and doesn't do anything.
You need to modify your code to be event-driven as well, so the "connection" status will be sent as an event that you can handle, or somehow make the polling asynchronous so it happens in parallel to the event-handling.
A little background info:
PC is a Windows 7 64 bit machine with all SP's and windows updates.
I wrote an OPC server using LightOPC as the base and having issues reading network files as the title says. If I run the program manually it reads the files just fine.
There are no permissions issues obviously when running it manually but something else happens when the client launches it (FactoryTalk View 8.0).
The problem occurs when the program starts during the normal OPC connection launching. In the code std::strerror(errno) function returns
no such file or directory
which is obviously a lie. So hopefully someone can shed some light on what I can do to adjust the code (maybe some security level up or something like that) to let it read from these network files (about 10 total). I log data to the Windows Event viewer and I log the user name used to attach to the server, it is using NT AUTHORITY\SYSTEM at program launch.
Here is 1 of the pieces of code used to read 1 of the files (fin.is_open() is returning false so it falls into the else and I am writing the error to the OPC tag so I could debug it):
ifstream fin;
fin.open("\\\\SCS\\C\\Sorter Software\\Data\\TocStatus.dat"); // open a file | std::ios::binary | std::ios::app
if (fin.is_open())
{
char buf[512];
fin.getline(buf, 512);
char *theString = TrimCString(buf);
if (strlen(theString))
mbstowcs_s(NULL, V_BSTR(&tagValues[TAGS_MOTIONTL_STATUS_TOC].tvValue), strlen(theString)*2, theString, strlen(theString));
if (use_window)
ListView_SetItemText(TheListView, TAGS_MOTIONTL_STATUS_TOC-1, 1, theString);
if (tagValues[TAGS_MOTIONTL_STATUS_TOC].tvState.tsQuality == OPC_QUALITY_BAD)
{
tagValues[TAGS_MOTIONTL_STATUS_TOC].tvState.tsQuality = OPC_QUALITY_GOOD;
SetListViewItem(TAGS_MOTIONTL_STATUS_TOC, tagActivationFlags[TAGS_MOTIONTL_STATUS_TOC]);
}
if (tagValues[TAGS_MOTIONTL_STATUS_TOC].tvState.tsQuality != OPC_QUALITY_GOOD)
{
tagValues[TAGS_MOTIONTL_STATUS_TOC].tvState.tsQuality = OPC_QUALITY_GOOD;
SetListViewItem(TAGS_MOTIONTL_STATUS_TOC, 1);
}
}
else
{
V_BSTR(&tagValues[TAGS_MOTIONTL_STATUS_TOC].tvValue) = SysAllocString(L"UNKNOWN ERROR9 ");
mbstowcs_s(NULL, V_BSTR(&tagValues[TAGS_MOTIONTL_STATUS_TOCLOADED].tvValue), strlen(std::strerror(errno)) * 2, std::strerror(errno), strlen(std::strerror(errno)));
tagValues[TAGS_MOTIONTL_STATUS_TOC].tvState.tsQuality = OPC_QUALITY_GOOD;
if (use_window)
{
ListView_SetItemText(TheListView, TAGS_MOTIONTL_STATUS_TOC-1, 1, "UNKNOWN");
SetListViewItem(TAGS_MOTIONTL_STATUS_TOC, 2);
}
UpdateConnStatus(false);
}
fin.close();
I'm attempting to write a function that will pull text from different sources (Ethernet client/Serial/etc.) into a single line, then compare them and run other functions based on them. Simple..
And while this works, I am having issues when trying to call a simple Serial.println() from a function OTHER than loop().
So far, I have around 140 lines of code, but here's a trimmed down version of the portion that's causing me problems:
boolean fileTerm;
setup() {
fileTerm = false;
}
loop() {
char character;
String content="";
while (Serial.available()) {
character = Serial.read();
content.concat(character);
delay(1);
}
if (content != "") {
Serial.println("> " + content);
/** Error from Serial command string.
* 0 = No error
* 1 = Invalid command
*/
int err = testInput(content);
}
int testInput(String content) {
if (content == "term") {
fileTerm = true;
Serial.println("Starting Terminal Mode");
return 0;
}
if (content == "exit" && fileTerm == true) {
fileTerm = false;
Serial.println("Exiting Terminal Mode");
return 0;
}
return 1;
}
(full source at http://pastebin.com/prEuBaRJ)
So the point is to catch the "term" command and enter some sort of filesystem terminal mode (eventually to access and manipulate files on the SD card). The "exit" command will leave the terminal mode.
However, whenever I actually compile and type these commands with others into the Serial monitor, I see:
> hello
> term
> test for index.html
> exit
> test
> foo
> etc...
I figure the function is catching those reserved terms and actually processing them properly, but for whatever reason, is not sending the desired responses over the Serial bus.
Just for the sake of proper syntax, I am also declaring the testInput() function in a separate header, though I would doubt this has any bearing on whether or not this particular error would occur.
Any explainable reason for this?
Thanks.
Model: Arduino Uno R3, IDE version: 1.0.4, though this behavior also happened on v1.0.5 in some instances..
It is kinda guessable how you ended up putting delay(1) in your code, that was a workaround for a bug in your code. But you didn't solve it properly. What you probably saw was that your code was too eager to process the command, before you were done typing it. So you slowed it down.
But that wasn't the right fix, what you really want to do is wait for the entire command to be typed. Until you press the Enter key on your keyboard.
Which is the bug in your code right now, the content variable doesn't just contain "term", it also contains the character that was generated by your terminal's Enter key. Which is why you don't get a match.
So fix your code, add a test to check that you got the Enter key character. And then process the command.
If I'm setting up in my php.ini the zlib compression support, won't really seems to work.
zlib.output_compression = On
; http://php.net/zlib.output-compression-level
zlib.output_compression_level = -1
; You cannot specify additional output handlers if zlib.output_compression
; is activated here. This setting does the same as output_handler but in
; a different order.
; http://php.net/zlib.output-handler
;zlib.output_handler =
I'm using php-5.3.9
I have been testing with the following php code, I must say I'm not a professional but seems like don't work.
<?php
$filename = tempnam('/tmp', 'zlibtest') . '.gz';
echo "<html>\n<head></head>\n<body>\n<pre>\n";
$s = "Only a test, test, test, test, test, test, test, test!\n";
// open file for writing with maximum compression
$zp = gzopen($filename, "w9");
// write string to file
gzwrite($zp, $s);
// close file
gzclose($zp);
// open file for reading
$zp = gzopen($filename, "r");
// read 3 char
echo gzread($zp, 3);
// output until end of the file and close it.
gzpassthru($zp);
gzclose($zp);
echo "\n";
// open file and print content (the 2nd time).
if (readgzfile($filename) != strlen($s)) {
echo "Error with zlib functions!";
}
unlink($filename);
echo "</pre>\n</body>\n</html>\n";
?>
there is no output
The zlib output handler has nothing to do with th gz file functions.
So there is something else wrong, turn on error_reporting.
Otherwise the shown code is working fine. The "no output" behaviour is not reproducible.