1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Add ${.sh.ppid} (re: 48f78227)

Since we now have sh.current_ppid, we might as well point a shell
variable to it, as the cost is nil.

Together, ${.sh.pid} and ${.sh.ppid} (updated when a virtual
subshell forks) form a logical counterpart pair to $$ and $PPID
(never updated in subshells).

This commit also adds a section to the manual page that hopefully
does away with the depressingly widespread subshell/child shell
confusion once and for all... :P
This commit is contained in:
Martijn Dekker 2022-07-27 19:08:57 +02:00
parent 305073af9d
commit 1a0d75d47c
5 changed files with 91 additions and 16 deletions

View file

@ -103,6 +103,7 @@ const struct shtable2 shtab_variables[] =
".sh.math", 0, (char*)0,
".sh.pool", 0, (char*)0,
".sh.pid", NV_PID|NV_NOFREE, (char*)0,
".sh.ppid", NV_PID|NV_NOFREE, (char*)0,
".sh.tilde", 0, (char*)0,
"SHLVL", NV_INTEGER|NV_NOFREE|NV_EXPORT, (char*)0,
"", 0, (char*)0

View file

@ -113,7 +113,8 @@ extern void sh_save_rand_seed(struct rand *, int);
#define SH_MATHNOD (sh.bltin_nodes+61)
#define SH_JOBPOOL (sh.bltin_nodes+62)
#define SH_PIDNOD (sh.bltin_nodes+63)
#define SH_TILDENOD (sh.bltin_nodes+64)
#define SHLVL (sh.bltin_nodes+65)
#define SH_PPIDNOD (sh.bltin_nodes+64)
#define SH_TILDENOD (sh.bltin_nodes+65)
#define SHLVL (sh.bltin_nodes+66)
#endif /* SH_VALNOD */

View file

@ -192,9 +192,9 @@ shell option is on)
by a
.IR pipe (2)
to the standard input of the next command.
Each command,
except possibly the last,
is run as a separate process.
Each command except the last is run asynchronously in a subshell (see
.I Subshells\^
below).
If the
.B monitor
or
@ -562,7 +562,9 @@ status is 0, otherwise the exit status is 1.
.br
Execute
.I list\^
in a separate environment.
in a subshell (see
.I Subshells\^
below).
Note, that if two adjacent open parentheses are
needed for nesting, a space must be inserted to avoid
evaluation as an arithmetic command as described above.
@ -927,6 +929,55 @@ If this value is non-empty and does not start with a
.BR \(ap ,
it replaces the default tilde expansion when the function terminates.
Otherwise, the tilde expansion is left unchanged.
.SS Subshells.
A
.I subshell\^
is a separate execution environment that is a complete duplicate of the
current shell environment, except for two things: all traps are reset to
default except those for signals that are being ignored, and subshells
cannot be interactive (i.e., they have no command prompt).
Changes made within a subshell do not affect the parent environment and are
lost when the subshell exits.
.PP
Particular care should be taken not to confuse a subshell with a newly
invoked shell that is merely a child process of the current shell,
and which (unlike a subshell) starts from scratch in terms of
variables and functions and may be interactive.
Beware of shell tutorials on the Internet that confuse these.
.PP
Subshells are not themselves invoked as commands.
Instead, the following are automatically run in or from a subshell:
.RS 8
.IP \[bu] 3
any command or group of commands enclosed in parentheses;
.IP \[bu]
command substitutions of the first and third form (see
.I "Command Substitution"
below);
.IP \[bu]
process substitutions (see
.I "Process Substitution"
below);
.IP \[bu]
all elements of a pipeline except the last;
.IP \[bu]
any command executed asynchronously (i.e., in a background process).
.RE
.PP
Creating processes is expensive, so as a performance optimization, a
subshell of a non-interactive shell may share the process of its parent
environment. Such a subshell is known as a virtual subshell.
Subshells are virtual unless or until something (such as asynchronous
execution, or an attempt to set a process limit using the
.B ulimit
built-in command, or other implementation- or system-defined requirements)
makes it necessary to fork it into a separate process.
Barring any bugs in the shell, virtual subshells should be indistinguishable
from real subshells except by their execution speed and their process ID.
See the description of the
.B .sh.pid
variable below for more information.
.RE
.SS Command Substitution.
The standard output from a command list enclosed in
parentheses preceded by a dollar sign (
@ -1614,7 +1665,8 @@ that run in the current environment may return status values in this range.
.B $
The process ID of the main shell process. Note that this value will not
change in a subshell, even if the subshell runs in a different process.
See also \f3.sh.pid\fP.
See also
.BR .sh.pid .
.TP
.B _
Initially, the value of
@ -1783,14 +1835,30 @@ discipline function is invoked.
The current depth for subshells and command substitution.
.TP
.B .sh.pid
Set to the process ID of the current shell.
This is distinct from
.B $$
as in forked subshells this is set to the process ID of the
subshell instead of the parent shell's process ID.
In virtual subshells
Set to the process ID of the current shell process.
Unlike
.BR $$ ,
this is updated in a subshell when it forks into a new process.
Note that a virtual subshell may have to fork mid-execution
due to various system- and implementation-dependent requirements,
so the value should not be counted on to remain the same
from one command to the next.
If a persistent process ID is required for a subshell,
it must be ensured it is running in its own process first.
Any attempt to set a process limit using the
.B ulimit
built-in command, such as
.BR "ulimit -t unlimited 2>/dev/null" ,
is a reliable way to make a subshell fork if it hasn't already.
.TP
.B .sh.ppid
Set to the process ID of the parent of the current shell process.
Unlike
.BR $PPID ,
this is updated in a subshell when it forks into a new process.
The same note as for
.B .sh.pid
retains its previous value.
applies.
.TP
.B .sh.value
Set to the value of the variable at the time that the
@ -1864,7 +1932,11 @@ built-in command.
.TP
.B
.SM PPID
The process ID of the parent of the shell.
The process ID of the parent of the main shell process.
Note that this value will not change in a subshell,
even if the subshell runs in a different process.
See also
.BR .sh.ppid .
.TP
.B
.SM PWD

View file

@ -1923,6 +1923,7 @@ static Init_t *nv_init(void)
#endif /* _hdr_locale */
(PPIDNOD)->nvalue.pidp = (&sh.ppid);
(SH_PIDNOD)->nvalue.pidp = (&sh.current_pid);
(SH_PPIDNOD)->nvalue.pidp = (&sh.current_ppid);
(SH_SUBSHELLNOD)->nvalue.ip = (&sh.realsubshell);
(TMOUTNOD)->nvalue.lp = (&sh.st.tmout);
(MCHKNOD)->nvalue.lp = (&sh_mailchk);

View file

@ -1007,7 +1007,7 @@ set -- $(
[[ -n $varname && $varname != '.sh' ]] && print -r -- "$varname"
done
)
(($# >= 64)) || err_exit "could not read shtab_variables[]; adjust test script ($# items read)"
(($# >= 65)) || err_exit "could not read shtab_variables[]; adjust test script ($# items read)"
# ... unset
$SHELL -c '