4

Can Bash execute a subprocess while preventing a subprocess from inheriting a file descriptor?

if flock -nx 9
then
  # If begin program runs away, it will keep the lock.
  begin program
else
  echo "Lock held :/)" >&2
fi 9> /tmp/lk
1
  • In this specific case an explicit unlock with flock -u -n 9 in the main script will prevent the situation with a lock kept by the spawned program. Commented May 30, 2022 at 16:08

2 Answers 2

4

As far as I know, no. You have to close it manually:

if flock 9 -nx
then
   program 9>&- #<= manual close of fd 9 after `program` has forked but before it execs
else
  echo "Lock held :/)" >&2
fi 9> /tmp/lk

If you want to get extra hacky, you can set the flag by calling the fcntl function directly via ctypes.sh:

#!/bin/bash

echo initial
ls /proc/$$/fd/

echo with 9
{

ls /proc/$$/fd/

echo with 9 in an execced child
bash -c ' ls /proc/$$/fd/'

} 9</etc/passwd


echo
echo BEGIN MAGIC
FD_CLOEXEC=1
FD_SETFD=2

. ctypes.sh
echo initial
ls /proc/$$/fd/

echo with 9
{

dlcall fcntl int:9 int:$FD_SETFD int:$FD_CLOEXEC

ls /proc/$$/fd/

echo with 9 in an execced child
bash -c ' ls /proc/$$/fd/'

} 9</etc/passwd

Output:

initial
0
1
2
255
with 9
0
1
2
255
9
with 9 in an execced child
0
1
2
3
9

BEGIN MAGIC
initial
0
1
2
255
with 9
0
1
2
255
9
with 9 in an execced child
0
1
2
3

(Not a typo in pasting -- the 9 really did get closed when the child bash got execced).

4

With bash 5.0+ and the example loadable modules (debian requires you also install the bash-builtins package), you can use the fdflags loadable module.

if flock -nx 9
then
  enable -f /usr/lib/bash/fdflags fdflags
  fdflags -s+cloexec 9
  begin program
else
  echo "Lock held :/)" >&2
fi 9> /tmp/lk

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.