![Bash、用 CLOEXEC 分叉](https://rvso.com/image/89171/Bash%E3%80%81%E7%94%A8%20CLOEXEC%20%E5%88%86%E5%8F%89.png)
Bash 可以在執行子程序的同時防止子程序繼承檔案描述符嗎?
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
據我所知,沒有。您必須手動關閉它:
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
fcntl
如果你想獲得額外的 hacky,你可以透過直接呼叫該函數來設定標誌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
輸出:
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
(不是貼上錯誤-當子bash被執行時,9確實被關閉了)。
答案2
使用 bash 5.0+ 和範例可載入模組(debian 要求您也安裝該bash-builtins
軟體包),您可以使用 fdflags 可載入模組。
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