欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > [Linux排查] “Permission Denied“?一文解决Linux文件/目录权限不足问题

[Linux排查] “Permission Denied“?一文解决Linux文件/目录权限不足问题

2025/5/21 3:55:15 来源:https://blog.csdn.net/Clownseven/article/details/148060542  浏览:    关键词:[Linux排查] “Permission Denied“?一文解决Linux文件/目录权限不足问题

更多服务器知识,尽在hostol.com

“Permission denied”——这恐怕是所有 Linux 用户,从初出茅庐的新手到身经百战的老司机,都或多或少会遇到的一个经典错误提示。它就像一个无形的“结界”,在你兴致勃勃地想要对某个文件或目录进行操作时,突然弹出来,冷冰冰地告诉你:“此路不通,你没权限!”那一刻,是不是感觉有点小抓狂,甚至想跟服务器“理论理论”?

别急,也别气馁!这个错误虽然常见且烦人,但它并不是什么不治之症。它其实是 Linux 系统强大而精细的权限管理机制正在忠实履行职责的表现。理解了这个错误的本质,掌握了正确的排查思路和解决方法,你就能轻松化解它,让你的操作重新顺畅起来。

这篇指南,就是你的“Permission Denied 终结者手册”。我们将一起深入分析这个错误到底在说什么,然后在各种常见场景下(比如读文件、写文件、执行脚本、访问目录等),一步步教你如何诊断问题所在,并用实战命令(主要是我们之前介绍过的 ls -l, chmod, chown)来对症下药。

“此路不通!”:Permission Denied 到底在说什么?

当我们看到 "Permission denied" 时,它传递的核心信息非常简单直接:你当前尝试执行的操作,对于你当前的用户身份来说,没有足够的权限去作用于那个特定的文件或目录。

Linux 的权限系统基于三个核心要素来做判断:

  1. 你是谁?(Who are you?) - 即你当前操作时所使用的用户身份 (User) 和你所属的用户组 (Group)。
  2. 你想干什么?(What are you trying to do?) - 你是想读取 (Read) 这个文件/目录的内容?想修改或写入 (Write) 它?还是想把它当作程序来执行 (Execute)?
  3. 这个东西允许谁干什么?(What does the file/directory allow?) - 这个文件或目录本身被设置了哪些权限位 (r, w, x),分别针对它的所有者 (Owner)、所属组 (Group) 和其他人 (Others)?

只有当“你是谁”和“你想干什么”这两者,与“这个东西允许谁干什么”的规则相匹配时,操作系统才会放行。如果不匹配,"Permission denied" 就会如期而至。这就像一个严格的门禁系统,你得有对应的“通行卡”才能进行相应的操作。

第一步:明确“案发现场” – 谁?在做什么?对哪个文件/目录?

在开始“破案”之前,我们首先要收集“案情信息”,明确几个关键要素:

  • 当前操作的用户是谁 (Who am I)? 你在哪个用户身份下执行的命令?用以下命令确认: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] whoami # 查看当前用户名 id # 查看当前用户的 UID, GID 以及所属的所有组 groups # 列出当前用户所属的所有组 了解你当前的有效用户和组身份,是判断权限匹配的第一步。
  • 你刚才尝试执行什么操作失败了 (What were you doing)? 是想用 catless 读取一个文件内容?还是用 nanovi 编辑并保存一个文件?或者是想用 ./your_script.sh 执行一个脚本?还是想用 cd 进入一个目录,或者用 ls 列出目录内容?不同的操作,需要的权限也不同。
  • 操作针对的是哪个具体的文件或目录 (Which file/directory)? 记下那个让你碰壁的文件或目录的**完整路径**。例如 /var/www/html/index.html 或者 /home/user/my_project/script.sh。路径中的每一个层级目录的权限都可能影响最终结果。
  • 完整的错误提示信息是什么? 除了 "Permission denied",后面通常还会跟着导致错误的具体文件名或操作。比如 bash: ./myscript.sh: Permission denied 就很明确是执行脚本时权限不足。

把这些信息搞清楚,就像侦探掌握了案发时间、地点、人物、事件一样,为我们后续的分析指明了方向。

第二步:“亮出证件” – 查看文件/目录的当前权限与归属

收集完“案情”,下一步就是去“案发现场”——那个让你碰壁的文件或目录——仔细勘察它的“门禁规则”(权限)和“户主信息”(所有者和所属组)了。我们的老朋友 ls -l 命令就是最好的“勘察工具”。

  • 查看单个文件的权限和归属: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] ls -l /path/to/your/file.txt
  • 查看目录本身的权限和归属(不是目录内容): [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] ls -ld /path/to/your/directory/ (注意这里的 -d 选项,它告诉 ls 只显示目录本身的信息,而不是其内容。)
  • 查看目录内容的权限和归属: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] ls -la /path/to/your/directory/ (-a 选项会显示包括以 . 开头的隐藏文件和目录,比如 . 代表当前目录,.. 代表上级目录,它们的权限也很重要。)

现在,仔细看 ls -l 输出的第一列(权限字符串,如 -rw-r--r--drwxr-xr-x)、第三列(所有者用户名)、第四列(所属组名)。回顾一下我们之前文章讲过的内容(如果你忘了,赶紧回去复习一下 Linux文件权限入门! - 请替换为实际链接):

  • 第一个字符是文件类型 (- 是文件, d 是目录)。
  • 接下来三组字符,每组三个,分别代表:
    • 所有者 (Owner) 的权限 (读r, 写w, 执行x)
    • 所属组 (Group) 的权限 (读r, 写w, 执行x)
    • 其他人 (Others) 的权限 (读r, 写w, 执行x)

现在,把你第一步确认的**当前用户身份**(你是所有者?还是属于那个所属组?或者只是“其他人”?)和你**尝试进行的操作**(需要读权限?写权限?还是执行权限?),与 ls -l 输出的这个文件/目录针对你这类用户的权限设置,进行**对比**!

比如,你用用户 john (属于 users 组) 尝试修改文件 /data/report.txtls -l /data/report.txt 的输出是 -rw-r----- 1 mary staff ... report.txt。这意味着:

  • 文件所有者是 mary,她有读写(rw)权限。
  • 文件所属组是 staff,该组成员只有读(r)权限。
  • 其他人没有任何权限(---)。

由于 john 既不是所有者 mary,也不属于 staff 组(假设 john 不在 staff 组里),那么 john 就属于“其他人”,而“其他人”对这个文件没有任何权限。所以,当 john 尝试修改(需要写权限)这个文件时,自然就会收到 "Permission denied"。

找到这个“权限不匹配”的点,你就离解决问题不远了!

第三步:对症下药 – 常见的“权限不足”场景与解决方案

找到了权限不匹配的原因,接下来就是“对症下药”了。我们来看看几种最常见的“Permission denied”场景以及对应的解决方法(主要是用 chmod 修改权限模式 和 chown 修改所有权)。

场景1:你想读取文件内容 (cat, less, grep 等),但没有读权限 (r)

症状: 比如执行 cat /path/to/file.txt 时,提示 "Permission denied"。用 ls -l /path/to/file.txt 查看,发现你对应的权限类别(所有者/组/其他人)下,第一个字符(读权限位)是 -

解决方案 (假设你有sudo权限,或者你是文件所有者):

  • 如果你是这个文件的所有者,但不知为何失去了读权限(很少见,但可能),给自己加上读权限: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] sudo chmod u+r /path/to/file.txt
  • 如果你属于文件的所属组,但组权限没有读,可以给组添加读权限: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] sudo chmod g+r /path/to/file.txt
  • 如果你是“其他人”,并且确实应该允许所有其他人读取这个文件(请谨慎评估安全性!),可以给“其他人”添加读权限: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] sudo chmod o+r /path/to/file.txt
  • 或者,如果你认为这个文件就应该是你来读写的,也可以考虑直接改变文件的所有者为你当前的用户(需要 sudo): [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] sudo chown $(whoami) /path/to/file.txt # 然后可能还需要调整一下权限,比如 chmod 600 或 644

场景2:你想修改或写入文件 (nano, vi, echo >, mv 到这里等),但没有写权限 (w)

症状: 比如用 nano file.txt 编辑后尝试保存时提示“Permission denied”,或者用 echo "text" > file.txt 时报错。用 ls -l 查看,发现你对应的权限类别下,第二个字符(写权限位)是 -

解决方案 (类似场景1,只是把 r 换成 w):

[提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中]


sudo chmod u+w /path/to/file.txt  # 如果你是所有者
sudo chmod g+w /path/to/file.txt  # 如果你想让同组用户也能写
sudo chmod o+w /path/to/file.txt  # (极不推荐!让所有人都能写通常非常危险!)
# 或者改变所有者
# sudo chown $(whoami) /path/to/file.txt
# sudo chmod u+w /path/to/file.txt

场景3:你想执行一个脚本或程序,但没有执行权限 (x)

症状: 比如你有一个 Shell 脚本 myscript.sh,尝试用 ./myscript.sh 运行时,系统提示 bash: ./myscript.sh: Permission denied。用 ls -l myscript.sh 查看,发现你对应的权限类别下,第三个字符(执行权限位)是 -

解决方案: 给它加上执行权限!

[提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中]


# 通常只给所有者加执行权限就够了
chmod u+x myscript.sh
# 或者,如果你想让所有能读到这个脚本的人都能执行它 (确保脚本本身是安全的!)
# chmod a+x myscript.sh

注意: 如果脚本是用特定解释器(如 Python, Perl)执行的,比如 python myscript.py,那么通常只需要对脚本文件有读权限,而不需要文件本身的执行权限位(因为实际执行的是 python 这个程序)。但如果脚本第一行写了 Shebang (如 #!/usr/bin/python3) 并且你想直接通过 ./myscript.py 来运行它,那它就需要执行权限。

场景4:你想进入一个目录 (cd) 或列出目录内容 (ls),但权限不足

目录的权限和文件有点不一样,要特别注意:

  • 想进入一个目录 (cd mydir/) 失败,提示 "Permission denied": 这通常是因为你对这个目录**没有执行 (x) 权限**!没错,对于目录来说,执行权限意味着“可以进入该目录并将其作为当前工作目录”。 解决方法: 给你对应的用户类别加上对该目录的执行权限。例如,如果你是所有者: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] chmod u+x /path/to/mydir/
  • 想列出目录内容 (ls mydir/) 失败,提示 "Permission denied" 或只显示问号: 这通常是因为你对这个目录**没有读 (r) 权限**。对于目录,读权限意味着“可以读取该目录中包含的文件和子目录的名称列表”。 解决方法: 给你对应的用户类别加上对该目录的读权限。通常,如果你能读一个目录,你也应该能进入它,所以一般会同时加上 rx: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] chmod u+rx /path/to/mydir/ # 如果你是所有者

重要: 如果你想访问一个深层目录(比如 /path/to/some/deep/dir/),你不仅需要对最终的 dir/ 有权限,还需要对它路径上的**所有父级目录**(/, /path/, /path/to/, /path/to/some/, /path/to/some/deep/)都拥有**至少执行 (x) 权限**,否则你连“路过”这些父目录都做不到,自然也到不了最终目的地。

场景5:你想在一个目录中创建、删除或重命名文件/子目录,但权限不足

症状: 比如执行 touch mydir/newfile.txt, rm mydir/oldfile.txt, 或者 mv mydir/file1 mydir/file2 时,提示 "Permission denied"。

“元凶”通常是: 你对这个**父目录 (mydir/)** 没有**写 (w) 权限**!对于目录来说,写权限控制的是能否在该目录中**修改其内容列表**,也就是创建、删除、重命名它里面的文件和子目录。这与你对目录内文件本身的写权限是两回事。

解决方法: 给你对应的用户类别加上对该**父目录**的写权限。

[提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中]


chmod u+w /path/to/mydir/ # 如果你是父目录的所有者

通常,如果一个目录允许你写入,它也应该允许你进入和读取,所以 chmod u+rwx mydir/ (即数字模式 7xx) 更常见。

场景6:Web 服务器 (Nginx/Apache) 访问网站文件时报 403 Forbidden

这个问题我们在 LEMP 排障指南里也提到过。403 Forbidden 通常就是权限问题。Web 服务器运行的用户(比如 www-datanginx)需要:

  • 对网站的根目录以及通往根目录的所有上级目录,拥有**至少执行 (x) 权限**(才能进入)。
  • 对它需要提供给用户的静态文件(HTML, CSS, JS, 图片等),拥有**至少读 (r) 权限**。
  • 如果配置了目录列表显示 (autoindex on;,通常不推荐),则对相应目录需要读 (r) 和执行 (x) 权限。
  • 如果 PHP 脚本需要读取或写入某些文件/目录(比如上传目录、缓存目录),那么 PHP-FPM 进程运行的用户(通常也是 www-data)需要对这些特定的文件/目录有相应的读/写权限。

解决方法:

  1. 确保网站根目录(如 /var/www/yourdomain.com/public_html)及其下所有文件和子目录的**所有者和所属组**是 Web 服务器运行的用户和组(如 www-data:www-data): [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] sudo chown -R www-data:www-data /var/www/yourdomain.com/public_html
  2. 设置合理的权限模式: [提示:请将以下代码片段复制并粘贴到 WordPress 的“代码”区块中] # 目录通常设为 755 sudo find /var/www/yourdomain.com/public_html -type d -exec chmod 755 {} \; # 文件通常设为 644 sudo find /var/www/yourdomain.com/public_html -type f -exec chmod 644 {} \;
  3. 对于需要 PHP 写入的特定目录(如 WordPress 的 wp-content/uploads),确保 www-data 用户有写权限。

第四步:更深层次的“拦路虎” – SELinux, AppArmor 与 ACLs (进阶排查)

有时候,即使你把传统的 Unix 文件权限 (rwx) 和所有权 (owner/group) 都设置得“完美无缺”了,仍然会遇到 "Permission denied"。这时候,你就得怀疑是不是有更“高维度”的安全机制在作祟了。常见的有:

  • SELinux (Security-Enhanced Linux): 主要用于 RHEL, CentOS, Fedora 等发行版。它是一种强制访问控制 (MAC) 机制,基于安全策略(Policy)来限制进程能对哪些文件、端口等资源进行何种操作,即使传统权限允许也不行。它通过给文件和进程打上“安全上下文标签 (Context Label)”来实现。如果一个进程的标签没有被策略允许访问某个文件的标签,就会被拒绝。 如何排查:
    • 检查 SELinux 当前状态:getenforce (可能是 Enforcing, Permissive, 或 Disabled)。
    • 查看 SELinux 的审计日志,寻找 AVC (Access Vector Cache) denied 记录:sudo ausearch -m avc -ts recent 或者直接查看 /var/log/audit/audit.log。日志会告诉你哪个进程 (scontext) 尝试对哪个目标 (tcontext) 进行什么操作 (permission) 时被拒绝了。
    • 常见解决方法:
      • 使用 restorecon -Rv /path/to/file_or_dir 来恢复文件/目录的默认正确安全上下文标签(比如你手动创建了一个文件,它可能没有正确的 Web 内容标签)。
      • 使用 setsebool -P boolean_name on/off 来修改 SELinux 的布尔值开关,允许某些特定的操作(比如允许 HTTPD 访问网络 setsebool -P httpd_can_network_connect on)。
      • (不推荐,但可用于临时测试) 将 SELinux 设为宽容模式:sudo setenforce 0。如果设为宽容模式后问题解决,说明确实是 SELinux 策略问题。之后务必设回强制模式 (sudo setenforce 1) 并正确配置策略,而不是长期关闭它!
  • AppArmor (Application Armor): 主要用于 Ubuntu, Debian, SUSE 等发行版。它也是一种 MAC 机制,通过为每个应用程序定义一个“安全配置文件 (Profile)”来限制该程序可以访问的文件、网络端口和执行的操作。如果程序的操作超出了其 Profile 的允许范围,就会被阻止。 如何排查:
    • 检查 AppArmor 状态:sudo aa-status
    • 查看 AppArmor 的拒绝日志,通常在内核日志 dmesg 或系统日志 /var/log/kern.log/var/log/syslog 中,搜索 "apparmor=" 和 "DENIED" 关键字。
    • 可以使用 aa-logprof 工具来扫描日志并帮助你更新或创建 AppArmor Profile。
    • (不推荐,但可用于临时测试)可以将某个应用的 Profile 设为抱怨模式 (Complain mode) 而不是强制模式 (Enforce mode):sudo aa-complain /path/to/binary
  • ACLs (Access Control Lists - 访问控制列表): ACL 提供了比传统 u/g/o 权限更细粒度的权限控制,允许你为特定的用户或组单独设置对某个文件/目录的权限,而不影响其基本权限。如果一个文件或目录设置了 ACL,ls -l 的权限字符串末尾会多一个加号 + (例如 -rw-rwxr--+)。 如何排查:
    • 检查文件/目录是否设置了 ACL:getfacl /path/to/file_or_dir
    • 如果 ACL 规则阻止了你的访问,你需要使用 setfacl 命令来修改 ACL(比如添加允许你的用户或组的条目,或者移除拒绝的条目)。

当你确信基本的 rwx 权限没问题,但仍然“Permission denied”时,就应该考虑是不是这些更高级的安全机制在“挡路”了。排查它们通常需要查看特定的日志并使用特定的命令来调整策略。

结论:成为权限“掌控者”,告别“被拒绝”的烦恼

“Permission denied”——这个在 Linux 世界里抬头不见低头见的错误,其实并不可怕。它就像一个忠实的“哨兵”,在时刻提醒我们注意系统中的访问规则和安全边界。

解决它的关键在于拥有一套清晰的“破案思路”:

  1. 明确身份与目标: 我是谁?我想对哪个“宝贝”(文件/目录)做什么“动作”?
  2. 查看“门禁规则”:ls -l 仔细看看这个“宝贝”允许哪些人(所有者、组、其他人)做哪些“动作”(读、写、执行)。
  3. 对比分析找差异: 我的身份和我想做的动作,跟“门禁规则”匹配吗?
  4. 对症下药用“钥匙”: 如果不匹配,并且我有权限(或者能拿到 sudo 这把“万能钥匙”),就用 chmod 来修改“门禁规则”,或者用 chown 来更换“户主”。
  5. 别忘了“高级警卫”: 如果基本权限没问题,再看看是不是 SELinux, AppArmor 或 ACL 这些更严格的“警卫系统”在发挥作用。

只要你掌握了这套流程,并对 Linux 的权限概念有了深入理解,那么下一次再遇到 "Permission denied" 时,你就能从容不迫地分析原因,手到病除,真正成为你服务器权限的“掌控者”,让那些无谓的“被拒绝”的烦恼随风而去!


还有疑问?常见问题解答 (FAQs)

  1. 问: Linux 系统中新创建的文件和目录的默认权限是怎么决定的?我能修改它吗? 答: 新创建的文件和目录的默认权限是由两个因素共同决定的:程序创建文件时指定的初始权限模式(通常文件是 666rw-rw-rw-,目录是 777rwxrwxrwx)和当前用户的 umask 值。umask 是一个“掩码”,它会从初始权限中“减掉”对应的权限位。例如,常见的 umask 0022 会让新文件默认权限变为 644 (666 - 022),新目录变为 755 (777 - 022)。你可以使用 umask 命令查看当前的掩码值,也可以通过修改 Shell 启动脚本 (如 ~/.bashrc) 或系统级配置文件 (如 /etc/profile) 来设置默认的 umask 值。
  2. 问: 我在执行一个需要 sudo 的命令时,比如 sudo echo "text" > /root/somefile.txt,为什么还是提示 "Permission denied"? 答: 这是一个非常经典的 Shell 重定向问题!当你执行 sudo echo "text" > /root/somefile.txt 时,sudo 只作用于 echo "text" 这个命令,它确实是以 root 权限执行了。但是,输出重定向符号 > 是由你当前登录的**普通用户 Shell** 来解释和执行的。所以,实际上是你的普通用户在尝试创建或写入 /root/somefile.txt 这个文件,而普通用户通常没有权限写入 /root/ 目录,因此就报 "Permission denied" 了。解决方法: 你需要让整个重定向操作也以 root 权限执行,常见的方法是使用 tee 命令配合管道: echo "text" | sudo tee /root/somefile.txt。或者,先用 sudo -ssudo su - 切换到 root Shell,再执行写入操作。
  3. 问: 我已经用了 sudo,为什么执行某些 chmodchown 命令时还是提示 "Operation not permitted"? 答: 即使是 root 用户(通过 sudo 获取权限),在某些极端情况下也可能遇到 "Operation not permitted"。可能的原因包括:1) **文件系统以只读方式挂载:** 如果文件所在的文件系统被以只读 (read-only) 模式挂载了,那么任何写操作(包括修改权限和所有者)都会失败。你需要先用 sudo mount -o remount,rw /mount_point 将其重新挂载为可读写。2) **文件设置了“不可变属性 (immutable bit)”:** Linux 文件系统支持一些扩展属性,其中“不可变位” (i 属性) 一旦被设置,即使是 root 用户也无法修改、删除、重命名或创建硬链接到该文件,除非先用 sudo chattr -i filename 清除这个属性。你可以用 lsattr filename 查看文件的扩展属性。3) (极罕见) 内核安全模块(如LSM)的更深层限制。
  4. 问: 我之前在 chmod 的符号模式里看到过大写 X,它和小写 x 有什么区别? 答: 这是一个非常实用的区别!小写 x 会无条件地为指定对象添加或移除执行权限。而大写 X 则更“智能”:如果作用对象是目录,则为其添加执行权限(因为目录总是需要执行权限才能进入);如果作用对象是文件,则只有当该文件已经至少对某类用户(所有者、组、或其他人中的任何一个)拥有执行权限时,才会为其添加执行权限。如果文件原本对任何用户都没有执行权限(比如它是个普通的文本文件),那么使用大写 X 就不会给它添加执行权限。这个特性在你使用 chmod -R a+X directory_name/ 这样递归地给整个目录树添加执行权限时非常有用,它能确保只给子目录和原本就是可执行的文件(如脚本)添加执行权限,而不会错误地给目录下的所有普通文本文件、图片等都加上无用的执行位。
  5. 问: Docker 容器里的文件权限和我宿主机上的权限有什么关系?经常遇到容器里权限不足的问题。 答: Docker 容器内的文件系统权限与宿主机是隔离的,但当你使用**数据卷挂载 (Volume Mounting)** 将宿主机的目录映射到容器内时,权限问题就可能变得复杂。容器内的进程通常以其在容器内部定义的 UID/GID 运行(比如容器内的 www-data 用户可能是 UID 33)。当这个进程尝试访问挂载进来的宿主机目录时,Linux 内核会根据这个进程的 UID/GID(映射到宿主机上可能是一个不同的用户)以及宿主机上该目录的权限和所有权来进行判断。如果宿主机上目录的所有者或权限不允许容器内进程的 UID/GID 进行操作,就会出现 "Permission denied"。常见解决方法: 1) 确保挂载到容器的宿主机目录,其所有者或权限允许容器内进程的 UID/GID 访问(比如将宿主机目录的所属组改成与容器内进程 GID 相同,并赋予组写权限)。2) 在启动容器时,通过 -u 参数指定容器内主进程以宿主机上拥有该目录权限的某个用户的 UID/GID 来运行。3) 使用 Docker 的命名数据卷,由 Docker 自身管理权限,通常问题较少。


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词