Python: when to use pty.fork() versus os.fork()
The child process created with os.fork()
inherits stdin/stdout/stderr from parent process, while the child created with pty.fork()
is connected to new pseudo terminal. You need the later when you write a program like xterm: pty.fork()
in parent process returns a descriptor to control terminal of child process, so you can visually represent data from it and translate user actions into terminal input sequences.
Update:
From pty(7) man page:
A process that expects to be connected
to a terminal, can open the slave end
of a pseudo-terminal and then be
driven by a program that has
opened the master end. Anything that
is written on the master end is
provided to the process on the slave
end as though it was input typed on
a terminal. For example, writing the
interrupt character (usually
control-C) to the master device
would cause an interrupt signal
(SIGINT) to be generated for the
foreground process group that is
connected to the slave. Conversely,
anything that is written to the
slave end of the pseudo-terminal can
be read by the process that is
connected to the master end.
What happens to the stdout and stdin for a forked process?
The word "child" doesn't appear because os.forkpty()
creates a new pseudo-terminal and routes the child's output to it.
Your understanding would be correct if you had used os.fork()
instead.
Can someone explain this Python code for me?
In Unix-like operating systems, the way to start a new process is a fork. That is accomplished with fork()
or its several cousins. What this does is it duplicates the calling process, in effect having two exactly the same programs.
The only difference is the return value from fork()
. The parent process gets the PID of the child, and the child gets 0
. What usually happens is that you have an if statement like the one that you're asking about.
If the returned PID is 0
then you're "in the child". In this case the child is supposed to be a shell, so bash
is executed.
Else, you're "in the parent". In this case the parent makes sure that the child's open file descriptors (stdin
, stdout
, stderr
and any open files) do what they're supposed to.
If you ever take an OS class or just try to write your own shell you'll be following this pattern a lot.
As for your other question, what does the 1
mean in os.write(1, data)
?
The file descriptors are integer offsets into an array inside the kernel:
- 0 is
stdin
- 1 is
stdout
- 2 is
stderr
i.e. that line just writes to stdout
.
When you want to set up pipes or redirections then you just change the meaning of those three file descriptors (look up dup2()
).
Related Topics
Can't Install Gcloud on Amazon Linux:Invalid Syntax
How to Disable Stdout Buffer When Running Shell
Error: Could Not Build Wheels for Glpk Which Use Pep 517 and Cannot Be Installed Directly
Python Not Displaying Executable Output Properly
Cat, Grep and Cut - Translated to Python
Python Valueerror: Embedded Null Byte When Reading Png File from Bash Pipe
How to Install Libpython2.7.So
How to Get a Process's Stdin by a Process Id
(Still) Cannot Properly Install Lxml 2.3 for Python, But at Least 2.2.8 Works
How to Find the Target File's Full(Absolute Path) of the Symbolic Link or Soft Link in Python
How to Rewrite Output in Terminal
What Is the Return Value of Subprocess.Call()
Package Libffi Was Not Found in the Pkg-Config Search Path Redhat6.5
What Is My Current Desktop Environment
How to Send Input on Stdin to a Python Script Defined Inside a Makefile