help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: why does </proc/self/environ not work in bash?


From: Koichi Murase
Subject: Re: why does </proc/self/environ not work in bash?
Date: Mon, 12 Feb 2024 10:06:02 +0900

2024年2月12日(月) 7:44 Christoph Anton Mitterer <calestyo@scientia.org>:
> Well, even if technically it may make sense to do it in the forked
> process,

It does make sense to do it in the forked process. If we do the
redirections in the parent process, we need unnecessary bookkeeping of
file descriptors because the parent process needs to recover the
original file descriptors after running the command. It needs to dup
the file descriptor to a new one and dup2 back to the original
descriptor after the execution of the command. (In the actual
implementation, instead of dup/dup2, one usually wants to use fnctl
for a finer control on the duped file descriptors.) If we do that in
the forked process, such a bookkeeping is not needed. So if fork is
anyway performed, it is understandable we perform the redirections in
the forked process.

> "2.9.1 Simple Commands" says something like:
> [...]
> So I'd have read this at, by that point, all redirections have to be
> already performed,

I quickly checked XCU 2.9.1, but it doesn't seem to specify when the
fork (or in other words, the preparation of a separate execution
environment) should be performed. The section "Command Search and
Execution" mentions only execl. Then, Bash correctly performs the
redirections before execl is performed as required in POSIX. As for
the shell execution environment, I think POSIX doesn't strictly
specify how the shells should implement them. For example, ksh
performs aggressive reduction of fork, etc.

The following statement for the tempenv already implies that a
separate shell execution environment of the command exists in the
expansion stage:

>From Item 2 for Variable assignments in XCU 2.9.1
> If the command name is not a special built-in utility or function,
> the variable assignments shall be exported for the execution
> environment of the command and shall not affect the current
> execution environment

As 2.9.1/(3) and 2.9.1/(4) may be swapped, ``the current execution
environment'' for the redirections may be the execution environment of
the command, though I'm not sure if this is the original intent of the
standard or just a wording issue. Probably, it should be regarded as
unspecified technically.

> And one can at least assume, that POSIX wasn't written with magic files
> like those in /proc/ in mind.

I think this is also an important point. The standards usually
describe the behavior observed from the outside, and the way to
realize the behavior is not restricted as far as the behavior is
consistent. This is allowed for optimizations and workarounds for the
implementation issues. This means that if there is a way to take a
peek inside the implementation, there can be something in intermediate
steps that doesn't follow the exact processing steps POSIX specifies.
Procfs is not a part of POSIX but is closely related to the system.
Once you use it, you cannot expect the behaviors that POSIX specifies.

You might think the behavior of dash is the desired one, but dash also
doesn't always behave as you expect (This point was also mentioned by
Kerin and in the wiki page pointed by Lawrence).

$ dash -c 'cat < /proc/self/environ' | wc
      0       0       0
$ ksh -c 'cat < /proc/self/environ' | wc
      0       0       0
$ bash -c 'cat < /proc/self/environ' | wc
      0       0       0
$ mksh -c 'cat < /proc/self/environ' | wc
      0       0       0
$ zsh -c 'cat < /proc/self/environ' | wc
      0       0       0
$ yash -c 'cat < /proc/self/environ' | wc
     26      92    6388

Yash is the only one in this context. If you think there is still a
conflict with the standard, I think what should be fixed is not the
shells but the standard. The standard needs to make it explicit that
it is unspecified if you believe the current wording is not enough.

> But even with the explanation of yours, I don't understand how the
> environ can be empty.
> Shouldn't that be there and inherited, even if it
> forks,redirects,execs?

See this reply:

https://lists.gnu.org/archive/html/help-bash/2024-02/msg00026.html

I rather think /proc/self/comm and /proc/self/cmdline opened before
exec should also be invalidated after exec. Those generate
inconsistent results as they are kept valid after exec.

Anyway, as already mentioned by others, and as I assumed you already
knew it, you should always use /proc/$$ or /proc/PID instead of
/proc/self when multiple processes may be involved.

2024年2月12日(月) 7:57 Christoph Anton Mitterer <calestyo@scientia.org>:
> On Sun, 2024-02-11 at 11:04 +0000, Kerin Millar wrote:
> > I don't know whether bash is in the wrong per se, but would suggest
> > that you open /proc/$$/environ instead.
>
> I anyway need the behaviour of
>    cat /proc/self/environ
>
> [..]
>
> Plan is to do so via something like:
> env -i 'VAR=valid-shell-variable-name' '+=invalid-shell-variable-name' 
> /proc/self/exe -c "set -e; cd /; cd /;   cat /proc/self/environ  |  tr 
> '\\000' '\\n'"

I still don't understand why you need /proc/self/environ. In the above
case you can just write env -i 'VAR=...' '+=...' "/proc/$$/exe" -c
"..."

--
Koichi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]