与Windows那种单人操作系统的设计思路不同,Linux从骨子里就是一个多任务、多用户的系统。
这是什么意思呢?想象一下,一台电脑可以同时被好几个人使用。虽然通常只有一套键盘和显示器,但用户可以通过网络(比如用ssh命令)远程登录进来,同时进行各种操作,甚至运行图形界面的程序。
这种“多人共享”的特性并不是后来才加上的,而是Linux诞生之初就深植于其设计哲学中的。想一想Unix诞生的那个年代,计算机还是个庞然大物,非常昂贵,通常都集中存放在某个地方。 一所大学可能就一台主机,大家通过遍布校园的终端连接上去使用。为了让这么多人能和平共处,就必须有一套机制来保护每个人的“私人空间”,防止张三不小心删了李四的重要文件,或者王五的一个错误操作搞崩了整个系统。
这套机制的核心,就是权限管理。

在Linux的世界里,每个文件和目录都有明确的归属。你可以想象这就像你的私人物品。有些东西只属于你自己,比如你的日记本;有些东西属于一个特定的小组,比如项目组共享的设计图;还有些东西则对所有人开放,比如公园的长椅。 这对应到Linux中,就是三个身份:
我们可以用id命令来看看自己当前的身份信息。
|$ id uid=1000(jules) gid=1000(jules) groups=1000(jules),4(adm),24(cdrom)
这里的uid是用户ID,gid是主用户组ID。每个用户都有一个唯一的ID,用户名只是为了方便人类记忆。
在Linux中,权限系统的基石就是“所有者、所属组、其他人”这三个概念。系统正是通过区分这三种角色,来决定谁能对文件做什么操作。
对于任何一个文件或目录,Linux都规定了三种基本操作权限:
cd)这个目录。我们可以用ls -l命令来查看一个文件的详细信息,其中就包含了它的权限设置。
|$ ls -l myfile.txt -rw-r--r-- 1 jules jules 1024 Mar 20 10:30 myfile.txt
开头那一串-rw-r--r--就是权限描述。第一个字符表示文件类型(-代表普通文件,d代表目录)。接下来的九个字符,每三个一组,分别对应所有者、所属组和其他人的权限。
rw-:所有者(jules)有读(r)和写(w)的权限,但没有执行(-)权限。r--:所属组(jules)只有读(r)的权限。r--:其他人也只有读(r)的权限。下面是权限的详细解读:
chmod(change mode)命令可以让我们修改文件或目录的权限。只有文件的所有者和超级用户(root)才能使用它。chmod有两种使用方式:数字模式和符号模式。
数字模式非常高效。它是用一个三位数的八进制数字来一次性设置所有权限。规则很简单:r是4,w是2,x是1。把需要的权限数字加起来就行了。
所以,chmod 755 myfile.sh就意味着:
7 (rwx)5 (r-x)5 (r-x)这对于脚本文件来说是一个非常常见的设置。
符号模式则更加直观。它让你明确地“添加”(+)、“移除”(-)或“设置”(=)某个权限。
比如,想给所有者添加执行权限,可以这样写:
|$ chmod u+x myfile.sh
想移除其他人的写权限:
|$ chmod o-w data.log
想让所属组和主人有一样的权限,可以这样:
|$ chmod g=u data.log
|# 数字模式 $ chmod 755 script.sh # rwxr-xr-x $ chmod 644 file.txt # rw-r--r-- $ chmod 600 private.txt # rw------- $ chmod 750 directory/ # rwxr-x--- # 符号模式 $ chmod +x script.sh # 给所有人添加执行权限 $ chmod u+w file.txt # 给所有者添加写权限 $ chmod g-w file.txt # 移除组的写权限 $ chmod
每次我们创建新文件时,它都会有一个默认的权限。这个默认权限是由umask(user mask)命令控制的。umask设置的是一个“遮罩”,它告诉系统在赋予新文件最大权限(通常是666 for files, 777 for directories)时,需要“拿掉”哪些权限。
比如,一个常见的umask值是0022。这意味着:
所以,新创建的文件权限就会是666 - 022 = 644 (rw-r--r--),新目录的权限就是777 - 022 = 755 (rwxr-xr-x)。
|# 查看当前umask $ umask # 设置umask $ umask 022 # 文件644,目录755 $ umask 002 # 文件664,目录775 $ umask 077 # 文件600,目录700 $ umask 000 # 文件666,目录777 # 在~/.bashrc中永久设置 echo “umask 022” >> ~/.bashrc
|# 文件默认权限计算 最大权限: 666 (rw-rw-rw-) umask: 022 (----w--w-) 结果: 644 (rw-r--r--) # 目录默认权限计算 最大权限: 777 (rwxrwxrwx) umask: 022 (----w--w-) 结果: 755 (rwxr-xr-x)
在Linux中,有些管理任务必须由超级用户(root)来完成。但我们不应该一直用root身份登录,那样太危险了。正确的做法是,在需要的时候临时获取超级权限。
su(substitute user)命令可以让你切换到另一个用户,包括root。输入su -并提供root的密码后,你就能暂时成为root。
|$ su - Password: # whoami root
sudo(superuser do)则更进一步。系统管理员可以预先配置好,允许某个普通用户以root身份执行特定的命令,而不需要知道root的密码,只需要输入自己的密码即可。
这是现代Linux发行版(如Ubuntu)更推崇的方式,因为它更安全、更可控。
|$ sudo apt update [sudo] password for jules: ...
su和sudo都是用来获取超级用户权限的工具,但它们的使用方式和安全性有很大的不同。su命令允许用户切换到另一个用户的身份,通常是root用户,这需要输入目标用户的密码。
使用su后,用户会完全切换到目标用户的环境中,这意味着拥有该用户的所有权限。
而sudo命令则是让用户在不切换用户身份的情况下,以超级用户的权限执行特定的命令。sudo的配置文件可以限制哪些用户可以执行哪些命令,并且只需要输入当前用户的密码。
这种方式更加安全,因为它限制了权限的范围,并且可以记录每个命令的执行情况。
因此,su适用于需要长时间以另一个用户身份工作的场景,而sudo则更适合执行单个需要超级用户权限的命令。
|# su命令 $ su - # 切换到root用户 $ su - username # 切换到指定用户 $ su username # 切换到指定用户(不改变环境变量) # sudo命令 $ sudo command # 以root权限执行单个命令 $ sudo -i # 切换到root用户(推荐) $ sudo -s # 切换到root用户(保持当前环境) $ sudo su - # 通过sudo切换到root
chown(change owner)命令是Linux系统中一个非常重要的工具,它的主要功能是更改文件或目录的所有者。
想象一下,你有一个文件需要转交给你的同事继续处理,这时就需要用到chown命令。通过这个命令,你可以将文件的所有权从自己转移给另一个用户,这样对方就可以完全控制这个文件,包括读取、修改甚至删除它。
这个过程就像是把一把钥匙交给了另一个人,让他可以自由进出一个房间。
|$ sudo chown newuser file.txt $ sudo chown newuser:newgroup file.txt
chgrp(change group)命令是Linux系统中用于更改文件或目录所属组的工具。假如你有一个项目文件夹,里面的文件需要与团队成员共享,但你希望只有特定的组成员可以访问和修改这些文件。
这时,chgrp命令就派上用场了。通过这个命令,你可以将文件或目录的所属组更改为团队的组名,从而控制哪些用户组可以访问这些资源。这就像是给一个房间换了一把新锁,只有拥有新钥匙的人才能进入。
|$ sudo chgrp newgroup file.txt
一个更常见的用法是同时改变所有者和所属组:
|$ sudo chown tony:tony /home/tony/myfile.txt
上面这个命令就把myfile.txt的所有者和所属组都改成了tony。
|# 递归更改目录及其内容 $ sudo chown -R user:group directory/ # 只更改目录,不更改内容 $ sudo chown user:group directory/ # 保持链接指向 $ sudo chown -h user:group symlink # 显示详细信息 $ sudo chown -v user:group file.txt
setuid(Set User ID)权限是一种特殊的权限设置,它使得用户在执行文件时,能够以文件所有者的身份运行该文件。 这意味着,即使用户本身没有文件所有者的权限,也可以通过setuid权限来临时获得这些权限,从而执行文件。 这种机制在需要提升权限执行某些操作时非常有用,比如在系统中执行一些需要管理员权限的程序。
|# 设置setuid权限 $ sudo chmod u+s program $ sudo chmod 4755 program # 查看setuid权限 $ ls -l /usr/bin/passwd -rwsr-xr-x 1 root root 68208 Mar 20 10:30 /usr/bin/passwd
setgid(Set Group ID)权限是一种特殊的权限设置,它有两个主要功能。首先,它允许用户在执行文件时,以文件所属组的身份运行该文件,这意味着即使用户不是该组的成员,也可以利用该组的权限来执行文件。 其次,当在设置了setgid权限的目录中创建新文件时,这些文件会自动继承该目录的组属性,而不是创建者的默认组属性。这在需要多个用户协作的环境中非常有用,因为它确保了新创建的文件始终属于同一个组,从而简化了权限管理。
|# 设置setgid权限 $ sudo chmod g+s directory/ $ sudo chmod 2755 directory/ # 查看setgid权限 $ ls -ld /var/local/ drwxr-sr-x 2 root staff 4096 Mar 20 10:30 /var/local/
sticky bit权限是一种特殊的权限设置,通常应用于目录。它的主要作用是保护目录中的文件安全,确保只有文件的所有者或具有适当权限的用户才能删除或修改这些文件。 这样,即使其他用户可以在该目录中创建文件,他们也无法删除或更改不属于自己的文件,从而有效地防止了意外或恶意的文件删除。
|# 设置sticky bit $ sudo chmod +t directory/ $ sudo chmod 1755 directory/ # 查看sticky bit $ ls -ld /tmp drwxrwxrwt 10 root root 4096 Mar 20 10:30 /tmp
|# 特殊权限位 4000 # setuid 2000 # setgid 1000 # sticky bit # 组合示例 4755 # setuid + rwxr-xr-x 2755 # setgid + rwxr-xr-x 1755 # sticky bit + rwxr-xr-x 6755 # setuid + setgid + rwxr-xr-x
假设我们有两个用户,小明和小红,他们想创建一个共享目录/projects来存放项目文件,希望两人都能往里面添加和修改文件。小明有sudo权限。
首先,小明需要创建一个新的用户组developers,并把小明和小红都加进去。
|$ sudo groupadd developers $ sudo usermod -a -G developers xiaoming $ sudo usermod -a -G developers xiaohong
然后,创建目录并设置权限:
通过这个例子,我们把权限、用户组和特殊权限的知识串联起来,解决了一个真实世界的问题。
|$ sudo mkdir /projects $ sudo chgrp developers /projects $ sudo chmod 770 /projects
770意味着所有者(root)和developers组的成员都有读、写、执行权限,而其他人没有任何权限。
但还有一个问题。当小明在/projects里创建一个新文件时,这个文件的所属组默认是小明自己的主用户组,而不是developers。为了解决这个问题,我们需要给/projects目录设置一个特殊的setgid权限。
|$ sudo chmod g+s /projects
这个s会让所有在这个目录下创建的新文件和子目录,都自动继承父目录的所属组,也就是developers组。这样,小明和小红创建的任何文件,对方都能修改了。
最后,为了确保组员创建的文件对方也能修改,最好让他们把自己的umask设置成0002,这样新建文件的默认权限就是664(rw-rw-r--),组员之间就可以互相编辑了。
|# 在~/.bashrc中添加 echo "umask 002" >> ~/.bashrc
让我们来验证一下设置是否生效:
|# 检查目录权限 $ ls -ld /projects drwxrws--- 2 root developers 4096 Mar 20 10:30 /projects # 检查用户组成员 $ groups xiaoming xiaohong # 测试文件创建 $ touch /projects/test.txt $ ls -l /projects/test.txt