LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-08-2011, 11:59 AM   #1
szoftveres
LQ Newbie
 
Registered: Jul 2011
Posts: 2

Rep: Reputation: Disabled
Shell Programming - Child process and stdin


Hi All,

During development of a simple program, I've faced an issue that can be represented through this example:

Suppose a simple text file:

Code:
# ===============
bash
echo level 1 create
echo $$    # This prints the PID of the current shell
echo

bash
echo level 2 create
echo $$
echo

bash
echo level 3 create
echo $$
echo

# ===============

echo level 3 destroy
echo $$
echo
exit

echo level 2 destroy
echo $$
echo
exit

echo level 1 destroy
echo $$
echo
exit

# ===============
After redirecting this file into a shell, the following happens:

Code:
$ bash < myfile.txt
level 1 create
7396

level 2 create
7397

level 3 create
7398

level 3 destroy
Actually the last child shell exits, and afterwards, nothing happens. I expect the parent shells also write their things at the corresponding destroy sections.
Why don't they continue reading their standard inputs? If I enter the contents of the text file directly from terminal, everything just works fine. What is the difference?

Thanks in advance for your answers!
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 07-08-2011, 12:33 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Please explain what you think is happening when the script receives this call?
Code:
exit
 
0 members found this post helpful.
Old 07-08-2011, 01:01 PM   #3
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
I think this is a buffering issue: depending on which buffer mode the shell is reading, it might read past the exit command so that other shells don't get the chance to read the whole file.

Code:
~/tmp$ bash < bash-nest.txt
level 1 create
1909

level 2 create
1910

level 3 create
1911

level 3 destroy
1911

~/tmp$ cat bash-nest.txt | bash
level 1 create
1914

level 2 create
1915

level 3 create
1916

level 3 destroy
1916

level 2 destroy
1915

level 1 destroy
1914
 
2 members found this post helpful.
Old 07-08-2011, 02:46 PM   #4
szoftveres
LQ Newbie
 
Registered: Jul 2011
Posts: 2

Original Poster
Rep: Reputation: Disabled
Thanks for posting your experiment with piping, that is really representative. I think buffering can be the problem.
 
Old 07-09-2011, 02:25 AM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by ntubski View Post
I think this is a buffering issue: depending on which buffer mode the shell is reading, it might read past the exit command so that other shells don't get the chance to read the whole file.
That would make a lot of sense, especially if bash < bash-nest.txt replaces standard input with a descriptor to the regular file; however, I'd expect to see "level 1 destroy" instead of "level 3 destroy" in that case.

To explain the ouput in the first case, the initial process would have to read only until line 2, "level 1" to line 7, "level 2" to line 12, but "level 3" must read until at least line 31 to prevent the others from reading anything else.
Code:
     1  # ===============
     2  bash
     3  echo level 1 create
     4  echo $$    # This prints the PID of the current shell
     5  echo
     6
     7  bash
     8  echo level 2 create
     9  echo $$
    10  echo
    11
    12  bash
    13  echo level 3 create
    14  echo $$
    15  echo
    16
    17  # ===============
    18
    19  echo level 3 destroy
    20  echo $$
    21  echo
    22  exit
    23
    24  echo level 2 destroy
    25  echo $$
    26  echo
    27  exit
    28
    29  echo level 1 destroy
    30  echo $$
    31  echo
    32  exit
    33
    34  # ===============
The results are too uniform between our three systems; therefore, my next guess was it has to do with process control. Keep reading, though!

"level 3" doesn't read ahead like would happen if read-ahead was the issue; this is apparent if you replace the first exit with cat -n:
Code:
level 1 create
4826

level 2 create
4827

level 3 create
4828

level 3 destroy
4828

     1
     2  echo level 2 destroy
     3  echo $$
     4  echo
     5  exit
     6
     7  echo level 1 destroy
     8  echo $$
     9  echo
    10  exit
    11
    12  # ===============
This lead me to believe that the issue arises when the first input descriptor is closed; I thought bash might have set the file position to the end. But again, here is a counter-example:
Code:
#something.txt
bash
echo $$
dd bs=1 count=1 &> /dev/null; exit
#echo something bad
echo $$
Code:
bash < something.txt
Code:
4899
something bad
4898
If you take out the dd call, you don't see the output of the last echo $$; my final final guess, then, is that bash uses some fcntl or ioctl that makes other bash instances exit (or run out of input) when the descriptor is closed, but only if nothing other-than the interpreter has touched it*. Additionally, this has no effect if the input descriptor is a pipe.

Kevin Barry

*I initially said "if non-bash programs haven't touched it", but then I replaced the dd call with read something, which uses a bash built-in, and the last echo $$ showed up.

Last edited by ta0kira; 07-09-2011 at 02:42 AM.
 
1 members found this post helpful.
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ - Problems while taking over STDIN and STDOUT of child process! MaxistXXL Programming 1 09-30-2010 07:47 PM
[SOLVED] How to redirect stdin for child process (Linux Shell scripting) ausrasul Programming 4 08-21-2010 09:02 PM
How to redirect the stdin and stdout of child process which exec interactive prog? john.daker Programming 1 11-04-2008 08:27 AM
How to capture both stdin and stdout of a child process? jineshkj Linux - Software 2 04-21-2006 06:34 AM
writing to child process stdin avikosan Programming 2 11-11-2003 07:06 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:06 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration