gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:40:22 24 4
gpt4 key购买 nike

我需要以不同的用户身份执行 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创建一个 登录 shell someUser ,这意味着以下内容:
  • 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 环境变量(如果已设置)或在 passwd(5) 中指定的 shell”确定(根据 man sudo)。请注意,使用 -s重要的是调用用户的环境,而对于 -i它是模拟用户的。
    注意这里有 关于 shell 相关行为的平台差异(使用 -i-s) :
  • sudo在 Linux 上显然只接受可执行文件或内置名称作为 -s 之后的第一个参数。/-i ,而 OSX 允许传递整个 shell 命令行;例如,OSX 接受 sudo -u root -s 'echo $SHELL - $USER - $HOME - $PWD'直接(不需要 eval ),而 Linux 不需要(从 sudo 1.8.95p 开始)。
  • sudo 的旧版本在 Linux 上不要对传递给 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)这已被修复。因此,即使使用较旧的 sudo 也能确保在 Linux 上进行扩展版本,将整个命令作为单个参数传递给 eval ;例如:sudo -u root -H -s eval 'echo $HOME' . (虽然在 OSX 上不是必需的,但这也适用于那里。)
  • root用户的$SHELL变量包含 /bin/sh在 OSX 10.9 上,它是 /bin/bash在 Ubuntu 12.04 上。

  • 无论模拟进程是否涉及shell,其环境都会设置以下变量,反射(reflect)调用用户和命令: SUDO_COMMAND , SUDO_USER , SUDO_UID= , SUDO_GID .
    man sudoman sudoers更多的细节。
    向@DavidW 和@Andrew 致敬以寻求灵感。

    关于bash - 如何在bash脚本中获取不同用户的$HOME目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20504662/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com