I've made a simple Lua-execution in Ada, it cooly run everything I need via Lua.Load_Buffer("os.execute('wxlua.exe wx.lua')") but I don't need win32 cmd.exe-window, which is default opens on program's start-up. Is there any way to control this event directly from Ada?
P.S. os.execute() sends commands directly to Windows, not via cmd.exe.
To help see what's going on, try creating a desktop shortcut that executes that command.
If double-clicking on it also brings up the win32 cmd.exe window, then that means they compiled wxlua.exe to be a windows console app. You can try reading their docs or poking around in their exe directory to see if there's a Win32 version instead. If that doesn't do it for you, your best remaining option I know of is to call Win32's CreateProcess with the CREATE_NO_WINDOW or DETACHED_PROCESS flag set instead of using os.execute.
If the shortcut doesn't bring up a console window, that means os.execute is doing it to you. In that case, you'll have to go directly to the CreateProcess solution mentioned above.
Gnat should come with the Win32 bindings you need to call CreateProcess. If you'd like a cleaner interface to that routine, I have some thicker bindings I created to some of the Win32 calls, including that one and some other calls associated with creating Win32 services. I released them to the Public Domain (or tried to...) They are available in the source distribution of my old SETI#Home Service, and I believe they are somewhere in the examples directory of AWS (at least it used to be before ACT took it over).
Standard Lua os.execute calls the standard C function system(). The C standard only requires that system() do something platform dependent, and specifically avoids saying what that might be. On Unix-like platforms, system() usually invokes the shell /bin/sh. On Windows it usually invokes cmd.exe.
Of course, its exact implementation could depend on exactly which toolchain you are using. You haven't said where you got your Lua (or for that matter, who's Ada compiler you have). One likely and recommended source is Lua for Windows, which is linked to the C runtime library from VC8, aka VS2005. Quoting from VS2005's documentation:
int system(const char *command);
.... The system function passes command to
the command interpreter, which
executes the string as an
operating-system command. system
refers to the COMSPEC and PATH
environment variables that locate the
command-interpreter file (the file
named CMD.EXE in Windows NT and
later). If command is NULL, the
function simply checks to see whether
the command interpreter exists.
Since os.execute calls system which invokes cmd.exe, you will get the console window. The way to avoid that is to not use os.execute.
If the program being executed is compiled for Windows Console Mode, then you will get a console window, regardless. However, wxlua.exe is almost certainly not compiled as a console application since it is intended to host GUI applications written in Lua based on the wxWidgets library.
Edit:
Naturally, if your lua.exe is built in a way that replaces either the implementation of os.execute or the standard library routine system() with a different implementation then you might see different results.
To demonstrate that standard Lua's os.execute() eventually invokes cmd.exe, try the following:
C:\Documents and Settings\Ross>lua -e "os.execute[[pause]]"
Press any key to continue . . .
C:\Documents and Settings\Ross>wlua -e "os.execute[[pause]]"
C:\Documents and Settings\Ross>
This invokes a simple Lua script from the standard Lua interpreter, first the usual one that is a console application, and second from the variation supplied with Lua for Windows who's only difference is that it is linked to be a Windows GUI application.
Both cause the "Press any key" message to appear. The first in the same console window where I invoked Lua, and the second in a separate console.
Before hitting a key, I used PsList from Sysinternals in a separate console to show the process tree, with the command pslist -t. I've excerpted out only the relevant bits below:
C:\Documents and Settings\Ross>pslist -t
pslist v1.29 - Sysinternals PsList
Copyright (C) 2000-2009 Mark Russinovich
Sysinternals
Process information for LAMPWORK:
Name Pid Pri Thd Hnd VM WS Priv
Idle 0 0 2 0 0 16 0
System 4 8 79 1208 1884 220 0
...
explorer 3592 8 17 1263 115968 33964 25816
...
cmd 4300 8 1 96 35032 4448 2260
PsList 4688 13 2 109 29556 2776 1248
cmd 5208 8 1 33 30340 2704 1984
lua 5592 8 1 17 8528 1564 400
cmd 5680 8 1 30 30144 2428 1956
Notice that the instance of CMD that invoked Lua has a CMD as a child.
Repeating the experiment with wlua -e "os.execute[[pause]]" and pslist -t again:
C:\Documents and Settings\Ross>pslist -t
....
Name Pid Pri Thd Hnd VM WS Priv
Idle 0 0 2 0 0 16 0
...
explorer 3592 8 16 1251 115712 33956 25752
...
cmd 4300 8 1 96 35032 4448 2260
PsList 4888 13 2 109 29556 2780 1248
procexp 4800 13 7 328 108492 33232 29464
cmd 5208 8 1 32 30340 2704 1984
wlua 3272 8 1 15 8536 1576 400
cmd 5104 8 1 30 30144 2440 1956
Again, wlua has a CMD as a child.
Using ProcessExplorer, also from Sysinternals, I can see the command line of the child CMD process. It is CMD.EXE /C pause. In effect, system() prepends CMD /C to its argument and passes the result to spawn() for execution in a child process.
Related
I have used spiffsimg to create a single file containing multiple lua files:
# ./spiffsimg -f lua.img -c 262144 -r lua.script
f 4227 init.lua
f 413 cfg.lua
f 2233 setupWifi.lua
f 7498 configServer.lua
f 558 cfgForm.htm
f 4255 setupConfig.lua
f 14192 main.lua
#
I then use esptool.py to flash the NodeMCU firmware and the file containing the lua files to the esp8266 (NodeMCU dev kit):
c:\esptool-master>c:\Python27\python esptool.py -p COM7 write_flash -fs 32m -fm dio 0x00000 nodemcu-dev-9-modules-2016-07-18-12-06-36-integer.bin 0x78000 lua.img
esptool.py v1.0.2-dev
Connecting...
Running Cesanta flasher stub...
Flash params set to 0x0240
Writing 446464 # 0x0... 446464 (100 %)
Wrote 446464 bytes at 0x0 in 38.9 seconds (91.9 kbit/s)...
Writing 262144 # 0x78000... 262144 (100 %)
Wrote 262144 bytes at 0x78000 in 22.8 seconds (91.9 kbit/s)...
Leaving...
I then run ESPLorer to check the status and get:
PORT OPEN 115200
Communication with MCU..Got answer! AutoDetect firmware...
Can't autodetect firmware, because proper answer not received.
NodeMCU custom build by frightanic.com
branch: dev
commit: b21b3e08aad633ccfd5fd29066400a06bb699ae2
SSL: true
modules: file,gpio,http,net,node,rtctime,tmr,uart,wifi
build built on: 2016-07-18 12:05
powered by Lua 5.1.4 on SDK 1.5.4(baaeaebb)
lua: cannot open init.lua
>
----------------------------
No files found.
----------------------------
>
Total : 3455015 bytes
Used : 0 bytes
Remain: 3455015 bytes
The NodeMCU firmware flashed correctly, but the lua files can't be located.
I have tried flashing to other locations (0x84000, 0x7c000), but I am just guessing at these locations based on reading threads on github.
I used the NodeMCU file.fscfg() routine to get the flash address and size. If I only flash the NodeMCU firmware I get the following:
print (file.fscfg())
524288 3653632
534288 is 0x80000, so I tried flashing only the spiffsimg file (lua.img) to 0x8000, then ran the same print statement and got:
print (file.fscfg())
786432 3391488
The flash address incremented by the exact number of bytes in the lua.img - which I don't understand, why would the flash address change? Is the first number returned by file.fscfg not the starting flash address, but the ending flash address?
What is the correct address for flashing an image file, contain lua files, that was created by spiffsimg?
The version of spiffsimg found here will provide the correct address for flashing an image file that contains lua files.
Do not use this version of spiffsimg as it is out of date.
To install the spiffsimg utility, you need to download and install the entire nodemcu-firmware package (into a linux environment, use make to install - note: make on my debian linux box generated an error, but i was able to go to the ../tools/spiffsimg subdirectory and run make on the Makefile found in that directory to create the utility).
The spiffsimg instructions found here are quite clear, with one exception: the file name you specify, with the -f parameter, needs to include the characters %x. The %x will be replaced with the address that the image file should be flashed to.
For example, the command
spiffsimage -f %x-luaFiles.img -S 4MB -U 465783 -r lua.script
will create a file, in the local directory, with a name like: 80000-luaFiles.img. Which means you should install that image file at address 0x80000 on the ESP8266.
I've never done that myself but I'm reasonably confident the correct answer can be extracted from the docs.
-f specifies the filename for the disk image. '%x' will be replaced
by the calculated offset of the file system.
And a bit further down
The disk image file is placed into the bin directory and it is named
0x<offset>-<size>.bin where the offset is the location where it
should be flashed, and the size is the size of the flash part.
However, there's a slight mismatch between the two statements. We may have a bug in the docs. If "'%x' will be replaced..." then I'd expected the final name won't contain 0x anymore.
Furthermore, it is possible to define a fixed SPIFFS position when you build the firmware.
#define SPIFFS_FIXED_LOCATION 0x100000
This specifies that the SPIFFS filesystem starts at 1Mb from the start of the flash. Unless
otherwise specified, it will run to the end of the flash (excluding
the 16k of space reserved by the SDK).
Lets say I have opened two tabs in the konsole (Tab1 and Tab2).
When I run tty in both of them I have:
Tab1:
~$ tty
/dev/pts/23
Tab2:
~$ tty
/dev/pts/24
If I run a simple program hello.c with a printf("Hello") in Tab1, how the system goes from writing to the stdout (file id 1) to writing to /dev/pts/23, being read by the konsole and then appearing in Tab1?
How the system know it has to give the "Hello" string to /dev/pts/23 and not to /dev/pts/24? And how it does that?
Is there a parameter given by the bash to the program so it knows which psudoterminal to send the "Hello"? Or the program sends the string back to the bash (how?) who knows to which pseudoterminal to send the data?
Thank you for your help
If you look at your process open files, you can see that the STDOUT,STDERR, etc points to the specific psuedo terminal that you already figured out using tty in your question
root#hello:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3
As you might know, a process is created by a fork system call that actually duplicates the open file descriptors from the parent. so basically, your process gets the file descriptors from its parent.
How did the parent hot these associated with him ? well, konsole already dealt with that.
I'm trying to monitor actual URLs, and not only hosts, with Nagios, as I operate a shared server with several websites, and I don't think its enough just to monitor the basic HTTP service (I'm including at the very bottom of this question a small explanation of what I'm envisioning).
(Side note: please note that I have Nagios installed and running inside a chroot on a CentOS system. I built nagios from source, and have used yum to install into this root all dependencies needed, etc...)
I first found check_url, but after installing it into /usr/lib/nagios/libexec, I kept getting a "return code of 255 is out of bounds" error. That's when I decided to start writing this question (but wait! There's another plugin I decided to try first!)
After reviewing This Question that had almost practically the same problem I'm having with check_url, I decided to open up a new question on the subject because
a) I'm not using NRPE with this check
b) I tried the suggestions made on the earlier question to which I linked, but none of them worked. For example...
./check_url some-domain.com | echo $0
returns "0" (which indicates the check was successful)
I then followed the debugging instructions on Nagios Support to create a temp file called debug_check_url, and put the following in it (to then be called by my command definition):
#!/bin/sh
echo `date` >> /tmp/debug_check_url_plugin
echo $* /tmp/debug_check_url_plugin
/usr/local/nagios/libexec/check_url $*
Assuming I'm not in "debugging mode", my command definition for running check_url is as follows (inside command.cfg):
'check_url' command definition
define command{
command_name check_url
command_line $USER1$/check_url $url$
}
(Incidentally, you can also view what I was using in my service config file at the very bottom of this question)
Before publishing this question, however, I decided to give 1 more shot at figuring out a solution. I found the check_url_status plugin, and decided to give that one a shot. To do that, here's what I did:
mkdir /usr/lib/nagios/libexec/check_url_status/
downloaded both check_url_status and utils.pm
Per the user comment / review on the check_url_status plugin page, I changed "lib" to the proper directory of /usr/lib/nagios/libexec/.
Run the following:
./check_user_status -U some-domain.com.
When I run the above command, I kept getting the following error:
bash-4.1# ./check_url_status -U mydomain.com
Can't locate utils.pm in #INC (#INC contains: /usr/lib/nagios/libexec/ /usr/local/lib/perl5 /usr/local/share/perl5 /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5 /usr/share/perl5) at ./check_url_status line 34.
BEGIN failed--compilation aborted at ./check_url_status line 34.
So at this point, I give up, and have a couple of questions:
Which of these two plugins would you recommend? check_url or check_url_status?
(After reading the description of check_url_status, I feel that this one might be the better choice. Your thoughts?)
Now, how would I fix my problem with whichever plugin you recommended?
At the beginning of this question, I mentioned I would include a small explanation of what I'm envisioning. I have a file called services.cfg which is where I have all of my service definitions located (imagine that!).
The following is a snippet of my service definition file, which I wrote to use check_url (because at that time, I thought everything worked). I'll build a service for each URL I want to monitor:
###
# Monitoring Individual URLs...
#
###
define service{
host_name {my-shared-web-server}
service_description URL: somedomain.com
check_command check_url!somedomain.com
max_check_attempts 5
check_interval 3
retry_interval 1
check_period 24x7
notification_interval 30
notification_period workhours
}
I was making things WAY too complicated.
The built-in / installed by default plugin, check_http, can accomplish what I wanted and more. Here's how I have accomplished this:
My Service Definition:
define service{
host_name myers
service_description URL: my-url.com
check_command check_http_url!http://my-url.com
max_check_attempts 5
check_interval 3
retry_interval 1
check_period 24x7
notification_interval 30
notification_period workhours
}
My Command Definition:
define command{
command_name check_http_url
command_line $USER1$/check_http -I $HOSTADDRESS$ -u $ARG1$
}
The better way to monitor urls is by using webinject which can be used with nagios.
The below problem is due to the reason that you dont have the perl package utils try installing it.
bash-4.1# ./check_url_status -U mydomain.com Can't locate utils.pm in #INC (#INC contains:
You can make an script plugin. It is easy, you only have to check the URL with something like:
`curl -Is $URL -k| grep HTTP | cut -d ' ' -f2`
$URL is what you pass to the script command by param.
Then check the result: If you have an code greater than 399 you have a problem, else... everything is OK! THen an right exit mode and the message for Nagios.
I need to change current working dir in lua script for execute specific actions, but i have a trouble with this simple task.
I write test script test.lua :
os.execute("cd /usr")
os.execute("ls")
But lua test.lua output is:
test.lua
Current dir doesn't change. What's is wrong? And i can't use LFS or any non-std modules.
Thanks to all for explaining it situation. I choose another way : change work dir before run lua script, but i have a lot of troubles with paths which use in scripts and with scripts.
On Unix, os.execute() spawns a child process and its children. In
jpjacobs's answer, the first process would execute the shell.
The directory change operation only affects the child process, not the
process in which the Lua interpreter is executing your program.
It's simply not possible without external libraries. You can use stuff like
os.execute("cd /usr/ && ls")
The Lua standard library is intended to be both small and portable. Therefore, it is based on the capabilities of the C-standard library for all but a select few functions. It has no function to change directories; that's why libraries like LFS exist.
Have you considered that Lua may not be the appropriate language for your needs? If you're doing shell-style scripting work in an environment where you're not allowed to load non-standard modules, perhaps Python or Perl would be better for you. Both of them have extensive standard libraries with a host of features, all without the need to download non-standard modules.
If you want to do any real shell-style scripting in Lua, you need modules. It's that simple. So you should either use external modules or use a different language.
This is a bit of hack, but have you tried creating symbolic links to the folders you need in the current folder, so you don't have to change the current folder at all?
os.execute("ln -s /usr/foo") -- link called "foo" in current dir
os.execute("ln -s /usr/bar") -- link called "bar" in current dir
baz = require('foo.baz') -- loading file /usr/foo/baz.lua
Here is the program written using Zerobranie Lua 5.2:
local sP = "E:/Documents/Lua-Projs/SVN/ScriptsWireE2"
local a, b, c = os.execute("cd "..sP.."&& dir")
print(a,b,c)
And the outpuit:
Програма 'lua.exe' пусната в 'E:\Documents\Lua-Projs\ZeroBraineIDE\ZeroBraineProjects' (pid: 8832).
Volume in drive E is Data
Volume Serial Number is DE34-ED00
Directory of E:\Documents\Lua-Projs\SVN\ScriptsWireE2
08-03-2016 18:25 <DIR> .
08-03-2016 18:25 <DIR> ..
17-03-2016 18:15 <DIR> Bridges
07-03-2016 18:21 11 558 license
07-03-2016 18:21 87 readme.md
2 File(s) 11 645 bytes
3 Dir(s) 181 729 161 216 bytes free
true exit 0
Програмата завършена за 0.06 секунди (pid: 8832).
I don't think this configuration is supported (maybe gcc isn't supported at all) because the esql script uses xlc options only.
But I want to know if other people are using this configuration gcc and informix 64 bits in AIX.
You can get ESQL/C (a part of ClientSDK or CSDK) to use GCC, but it isn't completely trivial. In principle, what I do is:
Make a copy of the original esql script.
Modify the original script to supply the GCC options on demand.
If you only want to use GCC, then this is sufficient. If you want to use both GCC and sometimes XLC (the native compiler), then it is harder.
I have a single script called esql in my private bin directory (which is always on my PATH ahead of things like $INFORMIXDIR/bin). It works out which version of ESQL/C I'm currently using, and runs the appropriate pre-patched version which is stored in a separate directory. And it automatically creates new versions of that script for me so if I work with CSDK 3.00.UC2 one minute and then CSDK 3.50.FC3 the next, it handles the switchover automatically.
Here's the patch applied to ESQL/C 3.50 on Solaris - you'll need to adapt it to AIX.
# #(#)$Id: patch.300.64,v 1.2 2007/09/02 21:46:55 jleffler Exp $
# GCC Patch for esql from CSDK 3.00.FC1
--- esql 2007-09-02 14:44:18.739067000 -0700
+++ esql.new 2007-09-02 14:44:26.812149000 -0700
## -23,10 +23,33 ##
INFDIR=${INFORMIXDIR=/usr/informix}
DB2CLIDIR=${INSTHOME=/usr/db2}
PREPCC=${INFDIR}/lib/esql/esqlc
-CC="${INFORMIXC=cc} -xarch=v9"
-CC_TH="${INFORMIXC=cc} -xarch=v9"
-CPP="${INFORMIXCPP=CC} -xarch=v9"
-CPP_TH="${INFORMIXCPP=CC} -xarch=v9"
+
+: ${INFORMIXC:=cc}
+: ${INFORMIXCPP:=CC}
+case "$INFORMIXC" in
+*perl*esqlcc*) # Building DBD::Informix
+ case "$ESQLCC" in
+ *gcc*|*g++)
+ CC_ARCHFLAGS="-m64"
+ ;;
+ *cc*|*CC*)
+ CC_ARCHFLAGS="-xarch=v9"
+ ;;
+ esac
+ ;;
+*gcc*|*g++*)
+ CC_ARCHFLAGS="-m64"
+ ;;
+# Beware - this normally needs to be last - because things like esqlcc and gcc match too!
+*cc*|*CC*)
+ CC_ARCHFLAGS="-xarch=v9"
+ ;;
+esac
+
+CC="$INFORMIXC $CC_ARCHFLAGS"
+CC_TH="$INFORMIXC $CC_ARCHFLAGS"
+CPP="$INFORMIXCPP $CC_ARCHFLAGS"
+CPP_TH="$INFORMIXCPP $CC_ARCHFLAGS"
STATICFLAGS=""
CP=${INFORMIXCP="$CC -E -C"} # cpp which runs before esqlc
## -51,9 +74,6 ##
then
CC="$CC $CC_AMD32"
CPP="$CPP $CC_AMD32"
-else
-CC=$CC
-CPP=$CPP
fi
: '
## -922,7 +942,7 ##
# Set the linker to CPP
# Set the source files to objects
#
- CC=$CPP
+ CC="$CPP"
A="$AO $CPPOPTS"
fi
fi
Lemme know if you want the controlling esql script that I use (see my profile). I have 9 32-bit scripts and 8 64-bit scripts, created by a set of 12 different patch files (all for Solaris, I'm afraid). The versions range from ESQL/C 5.20 (for OnLine 5.20) via ESQL/C 7.2x (long dead officially) through various versions of CSDK.