How messages from printf are routed to the terminal? - stdout

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.

Related

How to count the occurence of a string in a file, for all files in a directory and output into a new file with shell

I have hundreds of files in a directory that I would like to count the occurrence of a string in each file.
I would like the output to be a summary file that contains the original file name plus the count (ideally on the same line)
for example
file1 6
file2 3
file3 4
etc
Thanks for your consideration
CAUTION: I am pretty much an enthusiastic amateur, so take everything with a grain of salt.
Several questions for you - depending on your answers, the solution below may need some adjustments.
Are all your files in the same directory, or do you also need to look through subdirectories and sub-subdirectories, etc.? Below I make the simplest assumption - that all your files are in a single directory.
Are all your files text files? In the example below, the directory will contain text files, executable files, symbolic links, and directories; the count will only be given for text files. (What linux believe to be text files, anyway.)
There may be files that do not contain the searched-for string at all. Those are not included in the output below. Do you need to show them too, with a count of 0?
I assume by "count occurrences" you mean all of them - even if the string appears more than once on the same line. (Which is why a simple grep -c won't cut it, as that only counts lines that contain the substring, no matter how many times each.)
Do you need to include hidden files (whose name begins with a period)? In my code below I assumed you don't.
Do you care that the count appears first, and then the file name?
OK, so here goes.
[oracle#localhost test]$ ls -al
total 20
drwxr-xr-x. 3 oracle oinstall 81 Apr 3 18:42 .
drwx------. 39 oracle oinstall 4096 Apr 3 18:42 ..
-rw-r--r--. 1 oracle oinstall 40 Apr 3 17:44 aa
lrwxrwxrwx. 1 oracle oinstall 2 Apr 3 18:04 bb -> aa
drwxr-xr-x. 2 oracle oinstall 6 Apr 3 17:40 d1
-rw-r--r--. 1 oracle oinstall 38 Apr 3 17:56 f1
-rw-r--r--. 1 oracle oinstall 0 Apr 3 17:56 f2
-rwxr-xr-x. 1 oracle oinstall 123 Apr 3 18:15 zfgrep
-rw-r--r--. 1 oracle oinstall 15 Apr 3 18:42 .zz
Here's the command to count 'waca' in the text files in this directory (not recursive). I define a variable substr to hold the desired string. (Note that it could also be a regular expression, more generally - but I didn't test that so you will have to, if that's your use case.)
[oracle#localhost test]$ substr=waca
[oracle#localhost test]$ find . -maxdepth 1 -type f \
> -exec grep -osHI "$substr" {} \; | sed "s/^\.\/\(.*\):$substr$/\1/" | uniq -c
8 aa
2 f1
1 .zz
Explanation: I use find to find just the files in the current directory (excluding directories, links, and whatever other trash I may have in the directory). This will include the hidden files, and it will include binary files, not just text. In this example I find in the current directory, but you can use any path instead of . I limit the depth to 1, so the command only applies to files in the current directory - the search is not recursive. Then I pass the results to grep. -o means find all matches (even if multiple matches per line of text) and show each match on a separate line. -s is for silent mode (just in case grep thinks of printing messages), -H is to include file names (even when there is only one file matching the substring), and -I is to ignore binary files.
Then I pass this to sed so that from each row output by grep I keep just the file name, without the leading ./ and without the trailing :waca. This step may not be necessary - if you don't mind the output like this:
8 ./aa:waca
2 ./f1:waca
1 ./.zz:waca
Then I pass the output to uniq -c to get the counts.
You can then redirect the output to a file, if that's what you need. (Left as a trivial exercise - since I forgot that was part of the requirement, sorry.)
Thanks for the detailed answer it provides me with ideas for future projects.
In my case the files were all the same format (output from another script) and the only files in the directory.
I found the answer in another thread
grep -c -R 'xxx'

php popen(exim) from a webpage

Problem: Apache accessing programs in /usr/bin
Platform:
Win/7 Pro Sp1
Apache 2.4
Php 5.6
Cygwin emulator gives Linux/Unix emu and has
Exim 4.84-1
program: sendit.php
hndl popen( exim ... )
fwrite(hndle, email_headers);
fwrite(hndle, email_body);
fflush(hndle);
fclose(hndle);
(a)launch from user account
php sendit.php -> exim/exim_main.log updated
reports 368 bytes sent to exim
-> email arrives
demonstrates sendit.php works & Exim config and permissions are correct
(b)launch from apache account uid(apache) gid(srvc)
php sendit.php -> exim/exim_main.log updated
reports 368 bytes sent to exim
-> email arrives
demonstrates sendit.php runs from any account
(c)launch from within a web page
Apache is run from its own uid/gid as in (b)
page.phtml sendit.php
-> NO update to exim log
-> no mail recv'd
reports same NNN bytes send to exim
NO I/O errors
I fwriting_stream 368 bytes ...
* wrote body fragment 368
* wrote total 368
I Wrote Body:(368) of 368
I Wrote EOT(5) of 5
I FLUSHING pipe
I closing pipe
I is closed pipe
I returning 3
adding -d+deliver+host_lookup+lookup+rewrite options to the popen(), yields nice trace - -
EXCEPT when run withing Apache - - nothing shows up
Apache cfg has ExecCGI in the directory and other php / perl programs run there.
Issue is Exim is not within the Apache environment (/usr/bin/exim)
So, created link /usr/bin/exim -> docroot/exim
and reference this instance popen(docroot/exim ...)
Still fails to deliver via pipe -> exim
Any ideas???
btw: have used popen in webpages several places with success
and yes, I verifed the popen return
$PIPE = popen( ... ...);if ($PIPE === false) die("*FE*);
STATUS: SOLVED 2015-05-30
Issue is Windows + Cygwin pathing
PHP tolerates Cygwin as $PATH is available.
Running within
Apache LoadModule php5_module "c:/php/php5.6/php5apache2_4.dll" does not
Must use an absolute WINDOWS path like
c:/cygwin/bin/exim-4.84-1.exe within the server.
php cmdPath_Tests.php
uses file_exists($path) exec to
find that path usable within Apache
Jeff#JeffPC7%
case 0 0 trying:
$ ls -l /usr/bin/exim
lrwxrwxrwx 1 Administrator None 24 Apr 6 09:19 /usr/bin/exim -> /usr/bin/exim-4.84-1.exe
Jeff#JeffPC7%
$ ls -l /usr/bin/exim /cygwin/bin/exim{,-4.84-1}.exe c:/cygwin/bin/exim-4.84-1.exe
case 1 1
ls: cannot access /cygwin/bin/exim.exe: No such file or directory
ls: cannot access /cygwin/bin/exim-4.84-1.exe: No such file or directory
lrwxrwxrwx 1 Administrator None 24 Apr 6 09:19 /usr/bin/exim -> /usr/bin/exim-4.84-1.exe
case 3 1 trying:
-rwxr-xr-x 3 Jeff None 1192467 Jan 25 19:16 c:/cygwin/bin/exim-4.84-1.exe
/usr/bin/exim
0 0 /usr/bin/exim
/usr/bin/exim-4.84-1.exe
0 1 /usr/bin/exim-4.84-1.exe
which: no exim-4.84-1.exe in (/cygwin/bin)
1 1 File Exists
cmd 1 1 trying: /cygwin/bin/exim-4.84-1.exe
results:
/usr/bin/exim-4.84-1.exe
2 1 trying: /usr/bin/exim-4.84-1.exe
I found:
3 1 trying: c:/cygwin/bin/exim-4.84-1.exe
cmd results:
2015-05-30 11:58:24 NP6FDA-000530-QD Completed
ie: email sent

Dump shared memory

Is it possible to dump and investigate shared memory content from Linux? I spoted some strange shared memory segments in a "ipcs -m" output and want to see what is in there.
Also is it possible to determine the creator of this segment. "nattch" seems to be always zero.
Have a look at this tool
Shmcat
It's a good tool for your purpose.
What do you mean with creator? Do you mean the PID of the process? In this last case you can use
ipcs -mp
You'll get this output:
------ Shared Memory Creator/Last-op --------
shmid owner cpid lpid
3211265 root 1857 1866
where
CPID
The process ID of the job that created the shared memory segment.
and
LPID
The process ID of the last job to attach or detach from the shared memory segment or change the semaphore value.
Edit:
I don't think is possible to log those informations with standard tools.
I think we can do in this way.
Suppose we execute the command:
ipcs -m
and get these results
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 3211265 root 644 80 2
Then, with the command grep 3211265 /proc/*/maps, we obtain:
/proc/1862/maps:bla bla bla rw-s 00000000 00:09 3211265 /SYSV00000000 (deleted)
/proc/1863/maps:bla bla bla rw-s 00000000 00:09 3211265 /SYSV00000000 (deleted)
In this way we get the processes that was attached to the segment.
Scanning the elements in /proc/*/maps, you are able to discover the PIDs that are currently attached to a given segment.
You can make use of bash script that log these particular information.

Xcode 4.2 doesn't output exit code?

Since updating to iOS 5 and Xcode 4.2, it appears that Xcode no longer prints "Program ended with exit code: #" on completion of a run. Has anyone else noticed this and is there any way to enable it again? I have an automated testing tool that relies on this output to determine if tests pass or not, so it would be very helpful to have it back.
UPDATE: I looked into this in more detail, and it seems to be a deeper problem. It appears that whenever I run an app, it crashes with a segmentation fault on exit. Sometimes this occurs just before the exit code is printed, sometimes right after, which is why the exit code message appears inconsistently. The seg fault message appears in the device's console, though there is nothing in the Xcode debug output.
I just noticed this too. It seems that in Xcode 4.1 (tty /dev/ttys000) gdb is started like this:
This GDB was configured as "--host=i386-apple-darwin --target=arm-apple-darwin".tty /dev/ttys000
But in Xcode 4.2 - No tty /dev/ttys000:
This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all
To fix this you can do the following from a command line (Terminal.app/iTerm/etc):
echo 'tty /dev/ttys000' >> ~/.gdbinit
# Or, put it into the global gdb config:
# echo 'tty /dev/ttys000' >> /etc/gdb.conf
Then restart Xcode, and you have your exit code back!
Seems that Xcode 4.2's gdb wrapper has changed since 4.1
[ 13:29 Jonathan#MacBookPro / ]$ ls -l /Developer/Library/Xcode/PrivatePlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB /Developer-4.2/Library/Xcode/PrivatePlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB
-rwxrwxr-x 1 root admin 351936 Sep 20 13:23 /Developer/Library/Xcode/PrivatePlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB
-rwxrwxr-x 1 root admin 353776 Oct 8 14:21 /Developer-4.2/Library/Xcode/PrivatePlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB
[ 13:33 Jonathan#MacBookPro / ]$ ls -l /Developer/Library/Xcode/PrivatePlugIns/DebuggerGDB.ideplugin/Contents/MacOS/DebuggerGDB /Developer-4.2/Library/Xcode/PrivatePlugIns/DebuggerGDB.ideplugin/Contents/MacOS/DebuggerGDB
-rwxrwxr-x 1 root admin 1976144 Sep 20 13:23 /Developer/Library/Xcode/PrivatePlugIns/DebuggerGDB.ideplugin/Contents/MacOS/DebuggerGDB
-rwxrwxr-x 1 root admin 1948240 Oct 8 14:21 /Developer-4.2/Library/Xcode/PrivatePlugIns/DebuggerGDB.ideplugin/Contents/MacOS/DebuggerGDB

How to control cmd-window in win32 from Ada-code?

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.

Resources