微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在bash脚本中获取不同用户的$HOME目录?

我需要执行一部分bash脚本作为不同的用户,并在该用户的$ HOME目录内。但是,我不知道如何确定这个变量。切换到该用户调用$ HOME不能提供正确的位置:
# running script as root,but switching to a different user...
su - $different_user
echo $HOME
# returns /root/ but should be /home/myuser

更新:

似乎问题是,我试图切换用户在我的脚本的方式:

$different_user=deploy

# create user
useradd -m -s /bin/bash $different_user

echo "Current user: `whoami`"
# Current user: root

echo "Switching user to $different_user"
# Switching user to deploy

su - $different_user
echo "Current user: `whoami`"
# Current user: root
echo "Current user: `id`"
# Current user: uid=0(root) gid=0(root) groups=0(root)

sudo su $different_user
# Current user: root
# Current user: uid=0(root) gid=0(root) groups=0(root)

在bash脚本中作为不同用户切换用户和执行命令的正确方法是什么?

更新:根据这个问题的标题,人们似乎来到这里只是寻找一种方法来找到一个不同的用户的主目录,而不需要模仿那个用户

在这种情况下,最简单的解决方案是使用用户名为感兴趣的tilde expansion,结合eval(这是必需的,因为用户名必须作为无引号文字为了波浪号展开工作):

eval echo "~$different_user"    # prints $different_user's home dir.

注:通常caveats regarding the use of eval适用;在这种情况下,假设您控制$ different_user的值,并且知道它是一个纯粹的用户名

相比之下,本回答的其余部分涉及冒充用户并在该用户的主目录中执行操作。

注意:

>认情况下管理员和其他用户(如果通过sudoers文件授权)可以通过sudo模拟其他用户
>以下是基于sudo的认配置 – 更改其配置可以使它的行为不同 – 请参阅man sudoers。

作为另一个用户执行命令的基本形式是:

sudo -H -u someUser someExe [arg1 ...]
  # Example:
sudo -H -u root env  # print the root user's environment

注意:

>如果您忽略指定-H,模拟进程(在指定用户的上下文中调用的进程)将在$ HOME中报告原始用户的主目录。
>模拟进程将具有与调用进程相同的工作目录。
>模拟过程对作为参数传递的字符串文字不执行shell扩展,因为在模拟过程中没有涉及shell(除非someExe恰好是一个shell) – 在传递给模拟过程之前,调用shell的扩展可以很明显仍然发生。

可选地,您可以通过或通过(n模拟)shell运行模拟进程,方法是将someExe前缀为-i或-s – 不指定someExe …创建一个交互式shell:

> -i为someUser创建一个登录shell,这意味着以下内容

> someUser的用户特定shell配置文件(如果已定义)将被加载。
> $ HOME指向someUser的主目录,所以没有必要-H(虽然你仍然可以指定它)
>模拟shell的工作目录是someUser的主目录。

> -s创建一个登录shell:

>没有加载shell配置文件(虽然交互式非登录shell的初始化文件是例如〜/ .bashrc)
>除非您也指定-H,否则模拟进程将在$ HOME中报告原始用户的主目录。
>模拟的shell将具有与调用进程相同的工作目录。

使用shell意味着在命令行上传递的字符串参数可能受到模拟shell(可能在调用shell初始扩展之后)的shell扩展 – 见下面的平台特定的区别。比较以下两个命令(使用单引号防止调用shell过早扩展):

# Run root's shell profile,change to root's home dir.
sudo -u root -i eval 'echo $SHELL - $USER - $HOME - $PWD'
  # Don't run root's shell profile,use current working dir.
  # Note the required -H to define $HOME as root`s home dir.
sudo -u root -H -s eval 'echo $SHELL - $USER - $HOME - $PWD'

调用的shell由“SHELL环境变量(如果已设置)或shell在passwd(5)中指定”(根据man sudo)确定。注意,使用-s它是调用用户的环境很重要,而-i它是被模拟的用户的。

请注意,有关shell相关行为(使用-i或-s)的平台差异:

> sudo on Linux显然只接受一个可执行文件或内建名称作为-s / -i之后的第一个参数,而OSX允许传递整个shell命令行;例如,OSX直接接受sudo -u root -s’echo $ SHELL – $ USER – $ HOME – $ PWD'(不需要eval),而Linux不(从sudo 1.8.95p开始)。
> Linux上的旧版本的sudo不会将shell扩展应用于传递给shell的参数;例如,使用sudo 1.8.3p1(例如,Ubuntu 12.04),sudo -u root -H -s echo’$ HOME’只是回显字符串文字“$ HOME”,而不是在root用户的上下文中扩展变量引用。至少sudo 1.8.9p5(例如,Ubuntu 14.04),这已经修复。因此,为了确保在Linux上扩展,即使使用较旧的sudo版本,也可以将整个命令作为单个参数传递给eval;例如:sudo -u root -H -s ev​​al’echo $ HOME’。 (虽然在OSX上不是必需的,但也可以在那里工作。)
> root用户的$ SHELL变量在OSX 10.9上包含/ bin / sh,而在Ubuntu 12.04上是/ bin / bash。

无论模拟进程是否涉及shell,其环境都将设置以下变量,反映调用用户和命令:SUDO_COMMAND,SUDO_USER,SUDO_UID =,SUDO_GID。

看到人sudo和人sudoers更多的微妙。

提示帽子@DavidW和@Andrew的灵感。

原文地址:https://www.jb51.cc/bash/390288.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐