无法将目录更改为“/home/corey/scripts”:权限被拒绝

无法将目录更改为“/home/corey/scripts”:权限被拒绝

我收到错误消息...

could not change directory to "/home/corey/scripts": Permission denied

...当我运行以下脚本时...

#!/bin/bash
sudo -u postgres psql < setup_dev_db.sql
read -rsp $'Press any key to continue...\n' -n 1 key

... setup_dev_db.sql 的内容执行没有任何问题,但错误很烦人。

我可以摆脱它吗?

答案1

Postgres 想要创建一个$HOME/.psql_history文件,在其中存储来自psql客户端的所有查询和命令。它很可能想在 执行其他操作$HOME,但我没有看到其他隐藏文件形式的任何证据。除非您以交互方式使用,否则它实际上不会创建历史记录文件psql,但您并没有交互使用。

我遇到了完全相同的问题并发现了这个问题,但是接受的答案对我来说是不可接受的——我不应该授予 postgres 权限来在我运行时碰巧所在的任何目录中留下查询的踪迹一个脚本!

@Corey,您在评论中提到的解决方案(cd /tmp在致电之前sudo...)可能是最好的。psql不会创建此文件/tmp(我确信这是故意的,因为它可能允许非特权用户读取该文件)。

我能想到的还有另外两种解决方案:

  1. 通过添加到命令来psql在登录 shell 中运行-i

    sudo -i -u postgres psql < setup_dev_db.sql
    

    这将设置$HOMEpostgresHOME目录,在 中列出/etc/passwd。对于 Ubuntu,那就是/var/lib/postgres.但由于您正在输入命令,因此它不会创建.psql_history文件。但是,如果您使用 Interactive psql,则任何其他人sudo计算机权限的人将要可以访问您的命令历史记录。

    我不确定在这种情况下运行登录 shell 是否还会产生任何其他负面后果。

  2. psql以权限较低的用户身份运行,例如

    $ psql dev_db -hlocalhost corey_dev -W < setup_dev_db.sql
    

    如果这是一个问题,因为您将 postgres 用户创建留给了setup_dev_db.sql脚本,并且您还没有任何用户,只需createuser先在脚本中添加一个命令,如下所示:

    $ sudo -u postgres createuser corey_dev -P
    

    也许...

    $ sudo -u postgres createdb dev_db "Dev database"
    

注意:psql交互使用客户端时(这里不是你),如果你看到类似could not change directory to "/home/corey/scripts": Permission denied消息 **** 的消息,psql 将写信给/var/lib/postgres/.psql_history(或无论它$HOME在哪里)!如果您在使用交互式时看到过该警告psql,请查看一下 - 您可能会发现一个隐藏的历史文件。

答案2

要更改目录,用户必须拥有该目录的“x”权限。

我假设您正在运行“/home/corey/scripts”中的脚本。当“sudo -u postgres”将当前用户更改为“postgres”时,它会尝试将“postgres”的工作目录设置为生成您所看到的错误时调用的工作目录。

确保用户“postgres”具有“/home/corey/scripts”的权限“x”。

答案3

长话短说: 有关于这个问题的讨论在 Postgres 邮件列表中已在 PostgreSQL 16 中修复

错误原因
尽管@lambart 的解决方案是正确的,错误的原因不是因为它与文件无关.psql_history。这

could not change directory to "/home/corey/scripts": Permission denied

错误来自resolve_symlinks()功能它使用解析符号链接chdir并最终尝试chdir返回到原始目录,如果执行的用户psql没有执行此操作的权限,则会失败。该resolve_symlinks()调用来自find_my_exec(),而该调用又被调用set_pglocale_pgservice()(其中设置PGSYSCONFDIRPGLOCALEDIR)。

旧版本的解决方案:

对于 16 之前的版本,通过向用户授予发出命令的工作目录的执行psql命令权限来修复该错误。x这可以通过多种方式完成:

  1. 添加-i命令sudo以使用登录shell,在执行命令之前将工作目录更改为postgres用户的主目录 psql(postgres用户自然拥有x自己的主目录的权限):

    sudo -i -u postgres psql < setup_dev_db.sql
    
  2. x通过将 postgres 用户添加到拥有工作目录的组来授予 postgres 用户对当前工作目录的权限:

    # Get group owning the current directory
    stat -c "%G" .
    # Add postgres user to that group
    sudo usermod -aG <group above here> postgres
    
  3. 通过授予“其他”工作目录的权限来授予 postgres 用户x对当前工作目录的权限。x这可以很方便,例如,在用于开发的单用户基于 VM 的系统中,例如 WSL2,其中简单的chmod o+x /home/$USER命令即可修复错误。

  4. 使用当前用户运行psql,该用户当然拥有当前工作目录的权限。

  5. 执行该命令之前,请将工作目录更改为postgres用户有权限的目录x,例如cd /tmp.

答案4

对我来说这成功了,注意引号(')

sudo -Hiu postgres 'pg_dump --column-inserts --data-only --table=someTable entities_db > /var/backups/anywhere/$(date +%Y%m%d_%H%M%S)_someTable.sql'

注意-Hiufor sudo,或者使用su - postgres

你也可以将其放入 root 的 cronjob 中crontab -e

相关内容