24999

125 分钟

#Bash 的 unshare 命令

unshare [OPTION]... [CMD [ARG]...]

功能

创建新的命名空间并执行命令。

类型

可执行文件(/usr/bin/unshare),属于 util-linux

参数

  • OPTION 选项:
    • -i, --ipc[=file] - 创建 IPC namespace,如果指定了 file 则在该文件上创建挂载点
    • -m, --mount[=file] - 创建 mount namespace,如果指定了 file 则在该文件上创建挂载点
    • -n, --net[=file] - 创建 network namespace,如果指定了 file 则在该文件上创建挂载点
    • -p, --pid[=file] - 创建 PID namespace,如果指定了 file 则在该文件上创建挂载点
    • -u, --uts[=file] - 创建 UTS namespace,如果指定了 file 则在该文件上创建挂载点
    • -U, --user[=file] - 创建 user namespace,如果指定了 file 则在该文件上创建挂载点
    • -C, --cgroup[=file] - 创建 cgroup namespace,如果指定了 file 则在该文件上创建挂载点
    • -T, --time[=file] - 创建 time namespace,如果指定了 file 则在该文件上创建挂载点
    • -f, --fork - 作为 unshare 的子进程运行命令,而非直接运行
    • --keep-caps - 创建用户命名空间时,在用户命名空间中授予进程的能力(capabilities)在子进程中保留
    • --kill-child[=signame] - unshare 退出时向子进程发送 signame 信号;默认为 SIGKILL
    • --mount-proc[=mountpoint] - 在运行程序直接挂载 proc 文件系统(默认 /proc
    • --map-user=uid|name - 仅在当前有效用户 ID 映射为 uid 后运行程序
    • --map-users=inneruid:outeruid:count|auto - 仅在从 outeruid 开始大小为 count 的用户 ID 块映射为 inneruid 开始的用户 ID 块后运行程序
    • --map-group=gid|name - 仅在当前有效组 ID 映射为 gid 后运行程序
    • --map-groups=innergid:outergid:count|auto - 仅在从 outergid 开始大小为 count 的组 ID 块映射为 innergid 开始的组 ID 块后运行程序
    • --map-auto - 将 /etc/subuid 中当前用户拥有的第一个用户 ID 块映射到以用户 ID 0 开始的块;将 /etc/subgid 中当前用户拥有的第一个组 ID 块映射到以组 ID 0 开始的块
    • -r, --map-root-user - 仅在当前有效用户 ID 和组 ID 映射为 root 用户的 UID 和 GID 后运行程序
    • -c, --map-current-user - 仅在当前有效用户 ID 和组 ID 映射为当前用户的 UID 和 GID 后运行程序
    • --propagation private|shared|slave|unchanged - 递归地在新挂载命名空间中设置挂载传播标志
    • --setgroups allow|deny - 运行或禁止在 user namespace 中使用 setgroups 系统调用
    • -R, --root=dir - 设置根目录
    • -w, --wd=dir - 设置工作目录
    • -S, --setuid uid - 设置 UID
    • -G, --setgid gid - 设置 GID
    • --monotonic offset - 设置 CLOCK_MONOTONIC 在 time namespace 中的偏移量
    • --boottime offset - 设置 CLOCK_BOOTTIME 在 time namespace 中的偏移量
    • -h, --help - 显示帮助
    • -V, --version - 显示版本
  • CMD - 要执行的命令;默认执行 ${SHELL}
  • ARG - 命令的参数列表

#Linux 的命名空间

Linux 命名空间(namespace)是一种内核级隔离机制,用于让不同进程看到不同的系统资源视图,从而实现资源隔离。是容器技术(如 Docker 与 Kubernetes)的核心基础之一。

命名空间说明
mount namespace挂载或卸载文件系统不会影响系统的其他部分,除非该文件系统被显式标记为共享(使用 mount --make-shared;共享标志可在 /proc/self/mountinfo 中查看)。更多细节参见 mount_namespaces(7) 以及 clone(2) 中关于 CLONE_NEWNS 标志的说明。
UTS namespace设置主机名(hostname)或域名(domainname)不会影响系统的其他部分。更多细节参见 uts_namespaces(7)
IPC namespace进程将拥有独立的 IPC 命名空间,包括 POSIX 消息队列,以及 System V 消息队列、信号量集合和共享内存段。更多细节参见 ipc_namespaces(7)
network namespace进程将拥有独立的 IPv4 和 IPv6 协议栈、IP 路由表、防火墙规则、/proc/net/sys/class/net 目录树、套接字等资源。更多细节参见 network_namespaces(7)
PID namespace子进程将拥有一套与 nsenter 进程分离的 PID 到进程映射关系。如果更改 PID 命名空间,nsenter 默认会执行 fork,以便新程序及其子进程共享同一个 PID 命名空间并彼此可见。如果使用 --no-fork,则新程序将在不进行 fork 的情况下通过 exec 启动。更多细节参见 pid_namespaces(7)
user namespace进程将拥有独立的一组 UID、GID 以及能力(capabilities)。更多细节参见 user_namespaces(7)
cgroup namespace进程将看到虚拟化后的 /proc/self/cgroup 视图,新创建的 cgroup 挂载点将以该命名空间的 cgroup 根目录为起点。更多细节参见 cgroup_namespaces(7)
time namespace进程可以拥有独立的 CLOCK_MONOTONIC 和/或 CLOCK_BOOTTIME 视图,这些时间偏移可通过 /proc/self/timens_offsets 进行修改。更多细节参见 time_namespaces(7)

#示例

隔离进程环境

$ sudo unshare -p -f --mount-proc       # 创建新的 PID 命名空间,运行 /bin/bash
# ps -afx                               # 查看进程树
    PID TTY      STAT   TIME COMMAND
      1 pts/4    S      0:00 -bash
     16 pts/4    R+     0:00 ps -afx
  • 由于创建了 PID 命名空间,隔离了进程环境,因此看不到其它进程

隔离网络环境

$ sudo unshare -n bash
# ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  • 只剩下 loopback 网卡

#相关命令

命令说明
nsenter进入指定的命名空间执行命令

#推荐阅读

#手册

更新: 2026/3/2

作者: PlanC

创建: 2026/3/2