在Vagrant引导Shell脚本中,我能否切换用户?

30

编辑: 显然,问题在于我应该执行
su - postgres -c "commands, commands, commands"
也就是将任何命令传递给 su,而不是试图在 su 下面列出它们,因为那些命令(在 su 下面)不受 su 的影响。 /编辑

编辑 2: 请参考David Braun的回答,他提供了更好的解决方案:https://dev59.com/JWQn5IYBdhLWcg3wg3eR#22947716


在 Vagrant 启动脚本中,我不能切换用户 (su - postgres),为什么?

我正在编写这样一个脚本,在脚本中,我执行了以下操作:

echo '===== Creating PostgreSQL databases and users'

su - postgres

psql -c "
  create user SomeUserName password '...';
  alter user ...;
  "

在这里,psql 应尝试以用户 postgres 的身份登录。然而,发生的是 su - postgres 显然失败了,shell 尝试作为用户 root 登录。(显然,root 是运行 Vagrant 引导 shell 脚本的用户。)

因此,出现了这个错误,而且 psql 命令也没有被调用:

 

psql: FATAL: role "root" does not exist

sudo su - postgres 替换 su - postgres 没有任何效果(我认为脚本已经以 root 运行了)。

我在 su - postgres 前后添加了 id (打印当前用户 ID),id 在调用 su 之前和之后都打印 uid=0(root) gid=0(root) groups=0(root)。所以据我所知,su - postgres 被忽略了?当我试图切换回 root 用户时,某个 exit 命令会完全退出引导脚本 :-(

但是。在执行 vagrant ssh 后,我可以非常好地执行 sudo su - postgres,然后启动 psql。但无法从配置脚本中执行。

(一种解决方法是在调用 psql 时指定 -h 127.0.0.1 --username postgres(而不是切换用户到 postgres)。并为 VM 本地连接启用基于 PostgreSQL trust 的身份验证。)

4个回答

25
echo '===== Creating PostgreSQL databases and users'

su postgres << EOF
psql -c "
  create user SomeUserName password '...';
  alter user ...;
  "
EOF

1
很好,它可以运行,我已经测试过了 :-) 我在问题本身中添加了一个链接。 - KajMagnus
我收到一个错误:CREATE DATABASE不能从函数或多条命令字符串中执行。 - Ichwardort

14

我在寻找以非root身份运行Vagrant提供程序脚本的方法时发现了这个问题,并希望为观察到的行为添加一个解释,这是相当基本的Unix知识,对读者有用。

在shell脚本中运行程序(例如/bin/sh、sudo或su)不能改变其运行的上下文(工作目录、运行用户等),只能为它创建的进程设置上下文(如果以root - uid 0身份运行,则仅更改运行uid)。这也是为什么cd是shell内建命令的原因。su是一个setuid程序(注意使用“ls -l which su”命令时的“s”),这意味着它将作为拥有该程序的用户(root)而不是作为运行它的用户运行。


1
这是解决方法:https://dev59.com/a3I-5IYBdhLWcg3wKVA9 - Ciro Santilli OurBigBook.com

10

LHP是正确的:这并不是一个流浪者问题。我以前也需要这样做,下面是我的解决方法:

#!/bin/bash

case $(id -u) in
    0) 
         echo first: running as root
         echo doing the root tasks...
         sudo -u vagrant -i $0  # script calling itself as the vagrant user
         ;;
    *) 
         echo then: running as vagrant user
         echo doing the vagrant user's tasks
         ;;
esac

也许这对某些人有用,但另一个显而易见的解决方案是只需运行第二个使用sudo的脚本。

已修复:感谢Macattack。我直接在stackoverflow上写了,但仍未测试。

编辑:问题已被编辑,现在其描述和大多数答案都集中在“如何创建具有正确用户的postgres数据库”,而不是如何在vagrant脚本中切换用户。


你在每个case结尾处都缺少了;;。除此之外,非常棒的解决方案,正是我所需要的。 - Macattack
使用引号在行 echo doing the vagrant user's tasks 中!正确的语法应该是 echo "doing the vagrant user's tasks" - Doka
@Doka:尽管那完全不相关,但我没有看到任何支持你的说法的文档。 - olivecoder

3

我不确定在Vagrant shell脚本中是否可以切换用户,因为这可能需要用户输入,而当脚本在提供程序中运行时,您无法提供它...但是,为什么不直接使用psql命令指定用户呢?

psql --username=postgres -c "..."

1
回复:“因为这可能需要用户输入”——好的,我没有考虑到这一点。所以如果我将--command COMMAND指定为su选项,最终可能会使所有东西都正常工作。我想这就解释了一切,问题在于我对Bash不太熟悉,而不是与Vagrant相关的任何问题。 (?) - KajMagnus
1
感谢提供--username建议。(我在问题的结尾处提到了一个解决方法:“一种解决方法是指定-h 127.0.0.1 --username postgres”。) - KajMagnus
是的,抱歉,我刚看到你也提到了用户名部分...我回答得太快了呵呵... - Matt Cooper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接