我能在Bash脚本中运行'su'命令吗?

61

我能在脚本运行期间更改/切换用户吗?

if [ "$user" == "" ]; then
  echo "Enter the table name";
  read user
fi

gunzip *
chown postgres *
su postgres 
dropdb $user
psql -c "create database $user with encoding 'unicode';" -U dbname template1
psql -d $user -f *.sql

1
可能是重复的问题:如何使用su作为特定用户执行bash脚本的其余部分? - Ciro Santilli OurBigBook.com
6个回答

75

你可以这样做,但是bash不会将后续的命令作为postgres运行。相反,请执行以下操作:

su postgres -c 'dropdb $user'

-c 标志以用户身份运行命令(请参阅 man su)。


9
你需要在这里使用双引号:“su postgres -c“dropdb $user””。 - glenn jackman
2
如果结束引号在另一行上,您可以放置多行。在这种情况下,请注意引用。 - Bruno BEAUFILS

38

您可以使用 here document 在脚本中嵌入多个 su 命令:

if [ "$user" == "" ]; then
  echo "Enter the table name";
  read user
fi

gunzip *
chown postgres *
su postgres <<EOSU
dropdb $user
psql -c "create database $user with encoding 'unicode';" -U dbname template1
psql -d $user -f *.sql
EOSU

请注意,如果您将一些字符(例如反引号)放入文档中,可能需要进行转义。 - David Winiecki
2
还要注意,在将heredoc传递给su之前,所有变量都被替换。当您在内部创建和使用变量时,这可能会成为问题。为了避免这种情况,请使用单引号将第一个EOSU括起来以关闭参数替换,例如:su postgres <<'EOSU' - user2009388
请注意,在 [ 中使用 == 不能保证正常工作。唯一标准化的字符串比较运算符是 = - Charles Duffy

14

这样做是不正确的。su会调用一个进程,默认情况下是一个shell。在命令行上,这个shell将是交互式的,因此您可以输入命令。但在脚本的上下文中,shell会立即结束(因为它没有要处理的东西)。

使用:

su user -c command

su 命令会在成功执行的情况下,以 user 用户身份运行 - 通常只有在无需密码的用户或以 root 身份运行脚本时才会这样。

使用 sudo 可以获得更好的、更细粒度的控制。


7

1
在sudo后面加上-i以获取someuser的环境。 - notes-jj

4

不行,或者至少......你可以使用su命令,但是su只会在那一点上打开一个新的shell,当它完成后,它将继续执行脚本的其余部分。

解决方法之一是使用su -c '某些命令'


2

今天我听到一个有趣的想法,就是当你作为root运行脚本并想以另一个用户身份运行脚本时,在脚本上进行递归调用。请看下面的示例:

我正在以"root"用户身份运行脚本"my_script",希望脚本以"raamee"用户的身份运行。


#!/bin/bash

#Script name is: my_script

user=`whoami`

if [ "$user" == "root" ]; then
  # As suggested by glenn jackman. Since I don't have anything to run once 
  # switching the user, I can modify the next line to: 
  # exec sudo -u raamee my_script and reuse the same process
  sudo -u raamee my_script
fi

if [ "$user" == "raamee" ]; then
  #put here the commands you want to perform
  do_command_1
  do_command_2
  do_command_3
fi

1
如果在“raamee”完成工作后你没有其他事情要做,那么你可以执行以下命令:exec sudo -u raamee my_script -- 这将替换当前进程而不是让它一直挂起。 - glenn jackman
聪明,但是使用文档更简单(请参见我的答案)。 - David Braun
需要记住的一件事是,如果不是root用户,则sudo'd用户需要有权限运行脚本本身。 - Kyle Falconer

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