Bob*_*son 12 file-descriptors tmpfs
我们可以使用临时文件夹之类的临时文件吗
TMP=$(mktemp ... )
exec 3<>$TMP
rm $TMP
cat <&3
Run Code Online (Sandbox Code Playgroud)
这个shell退出后哪个会自动销毁?
Kus*_*nda 14
在临时文件的情况下,您在问题中的示例将创建它,然后将其从目录中取消链接(使其“消失”),并且当脚本关闭文件描述符时(可能在终止时),文件占用的空间可以被系统回收。这是在 C 等语言中处理临时文件的常用方法。
据我所知,不可能以相同的方式打开目录,至少不能以任何方式使目录可用。
在脚本终止时删除临时文件和目录的常用方法是安装清理EXIT
陷阱。下面给出的代码示例避免了必须完全处理文件描述符。
tmpdir=$(mktemp -d)
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"; rm -rf "$tmpdir"' EXIT
# The rest of the script goes here.
Run Code Online (Sandbox Code Playgroud)
或者你可以调用一个清理函数:
cleanup () {
rm -f "$tmpfile"
rm -rf "$tmpdir"
}
tmpdir=$(mktemp -d)
tmpfile=$(mktemp)
trap cleanup EXIT
# The rest of the script goes here.
Run Code Online (Sandbox Code Playgroud)
该EXIT
阱将不会在接收到执行KILL
信号(其不能被捕获),这意味着将没有清理然后进行。然而,它会在由于INT
orTERM
信号终止时执行(如果使用bash
or运行ksh
,在其他 shell 中,您可能希望EXIT
在trap
命令行之后添加这些信号),或者由于到达脚本末尾或执行一个正常退出时exit
称呼。
您可以 chdir 进入它然后将其删除,前提是您之后不要尝试使用其中的路径:
#! /bin/sh
dir=`mktemp -d`
cd "$dir"
exec 4>file 3<file
rm -fr "$dir"
echo yes >&4 # OK
cat <&3 # OK
cat file # FAIL
echo yes > file # FAIL
Run Code Online (Sandbox Code Playgroud)
我没有检查过,但是在 C 中使用 openat(2) 和文件系统中不再存在的目录时,这很可能是相同的问题。
如果您是 root 并且在 Linux 上,您可以使用单独的命名空间,并mount -t tmpfs tmpfs /dir
在其中使用。
如果您的脚本被迫进入不干净的退出(例如,使用 SIGKILL),则规范答案(在 EXIT 上设置陷阱)不起作用;这可能会留下敏感数据。
更新:
这是一个实现命名空间方法的小实用程序。它应该编译为
cc -Wall -Os -s chtmp.c -o chtmp
Run Code Online (Sandbox Code Playgroud)
并给定CAP_SYS_ADMIN
文件功能(以 root 身份)
setcap CAP_SYS_ADMIN+ep chtmp
Run Code Online (Sandbox Code Playgroud)
当(作为普通)用户运行时
./chtmp command args ...
Run Code Online (Sandbox Code Playgroud)
它将取消共享其文件系统命名空间,将 tmpfs 文件系统挂载到/proc/sysvipc
, chdir 并command
使用给定的参数运行。command
会不会继承CAP_SYS_ADMIN
能力。
该文件系统将无法从另一个不是从 启动的进程访问command
,并且当它的子进程command
死亡时,它会神奇地消失(包括在其中创建的所有文件),无论这种情况如何发生。请注意,这只是取消共享挂载命名空间——command
在同一用户运行的其他进程之间没有硬障碍;他们仍然可以潜行或者通过它的命名空间中ptrace(2)
,/proc/PID/cwd
或通过其他方式。
劫持“无用”/proc/sysvipc
当然是愚蠢的,但另一种选择是发送/tmp
带有空目录的垃圾邮件,这些目录必须被删除,或者通过分叉和等待使这个小程序大大复杂化。或者,dir
可以更改为例如。/mnt/chtmp
并在安装时由 root 创建;不要让它由用户配置,也不要将它设置为用户拥有的路径,因为这可能会使您暴露于符号链接陷阱和其他不值得花时间研究的毛茸茸的东西。
chtmp.c
#! /bin/sh
dir=`mktemp -d`
cd "$dir"
exec 4>file 3<file
rm -fr "$dir"
echo yes >&4 # OK
cat <&3 # OK
cat file # FAIL
echo yes > file # FAIL
Run Code Online (Sandbox Code Playgroud)
编写一个 shell 函数,当你的脚本完成时它会被执行。在下面的示例中,我将其称为“清理”并设置要在退出级别执行的陷阱,例如:0 1 2 3 6
trap cleanup 0 1 2 3 6
cleanup()
{
[ -d $TMP ] && rm -rf $TMP
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅此帖子。