如何获得Ansible远程用户的主目录?

我可以使用getentawk组合来做到这一点: getent passwd $user | awk -F: '{ print $6 }' getent passwd $user | awk -F: '{ print $6 }'

为了参考,在木偶我可以使用一个自定义的事实,就像这样:

 require 'etc' Etc.passwd { |user| Facter.add("home_#{user.name}") do setcode do user.dir end end } 

…将用户的主目录作为home_<user name>事实提供。


编辑:

我需要得到家的任意用户的主目录的目录,不仅是用于与Ansible服务器连接的目录。

Ansible(从1.4开始)已经在ansible_envvariables下显示了用户的ansible_envvariables。

 - hosts: all tasks: - name: debug through ansible.env debug: var="{{ ansible_env.HOME }}" 

或者,您可以使用env上的查找访问环境variables:

 - hosts: all tasks: - name: debug through lookup on env debug: var="{{ lookup('env','HOME') }}" 

不幸的是,你可以显然只使用这个获得连接用户的环境variables,因为这个剧本和输出显示:

 - hosts: all tasks: - name: debug specified user's home dir through ansible.env debug: var="{{ ansible_env.HOME }}" become: true become_user: "{{ user }}" - name: debug specified user's home dir through lookup on env debug: var="{{ lookup('env','HOME') }}" become: true become_user: "{{ user }}" 

输出

 vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser" PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [192.168.0.30] TASK: [debug specified user's home dir through ansible.env] ******************* ok: [192.168.0.30] => { "var": { "/home/vagrant": "/home/vagrant" } } TASK: [debug specified user's home dir through lookup on env] ***************** ok: [192.168.0.30] => { "var": { "/home/vagrant": "/home/vagrant" } } PLAY RECAP ******************************************************************** 192.168.0.30 : ok=3 changed=0 unreachable=0 failed=0 

和Ansible中的任何东西一样,如果你不能得到一个模块来给你想要的东西,那么你总是可以自由地掏腰包(尽pipe这应该谨慎使用,因为它可能是脆弱的,将不那么描述)使用这样的东西:

 - hosts: all tasks: - name: grep and register shell: > egrep "^{{ user }}:" /etc/passwd | awk -F: '{ print $6 }' changed_when: false register: user_home - name: debug output debug: var=user_home.stdout 

有可能是一个更干净的方式做到这一点,我有点惊讶,使用become_user切换到指定的用户似乎并不影响env查找,但这应该给你你想要的。

问题

可悲的是,用于查找任意用户家庭的lookup()或ENV var方法不能可靠地与Ansible一起工作,因为它以用户指定的用户身份运行,并且可选地使用sudo (如果sudo: yes在playbook或--sudo通过)。 这两种运行模式(sudo或no sudo)将会改变Ansible运行的shell环境,即使这样你也会被限制在指定为-u REMOTE_USERroot

你可以尝试使用sudo: yes ,和sudo_user: myarbitraryuser一起…但是由于某些版本的Ansible中的错误,你可能会看到它不像它应该那样运行。 如果您在Ansible> = 1.9 ,则可以使用become: truebecome_user: myarbitraryuser来代替。 但是,这意味着您编写的剧本和angular色将不适用于以前版本的Ansible。

如果您正在寻找一种可移植的方式来获取用户的家庭目录,也可以使用LDAP或其他目录服务,请使用getent

Ansible getent示例

创build一个名为: playbooks/ad-hoc/get-user-homedir.yml的简单剧本

 - hosts: all tasks: - name: shell: > getent passwd {{ user }} | cut -d: -f6 changed_when: false register: user_home - name: debug output debug: var=user_home.stdout 

运行它:

 ansible-playbook -i inventory/racktables.py playbooks/ad-hoc/get-user-homedir.yml -e "user=someuser" 

您可以使用expanduser

例如,在循环用户列表时:

 - name: Deploys .bashrc template: src: bashrc.j2 dest: "{{ '~' + item | expanduser }}/.bashrc" mode: 0640 owner: "{{ item }}" group: "{{ item }}" with_items: user_list 

我知道这是相当古老的线程,但我认为这是获取用户主目录的一个简单的方法

 - name: Get users homedir local_action: command echo ~ register: homedir 

在Linux(或Unix)系统上,波形符号指向用户主目录。

现在有一个getent模块 。 它将潜伏期结果logging为主机事实。 以下示例打印给定user的主文件夹。

 - getent: database: passwd key: "{{ user }}" split: ":" - debug: msg: "{{ getent_passwd[user][4] }}" 

还做了一个自定义yaml在主机事实中创build一个查找表。

 --- - assert: that: - user_name is defined - when: user_homes is undefined or user_name not in user_homes block: - name: getent become: yes getent: database: passwd key: "{{ user_name }}" split: ":" - name: set fact set_fact: "user_homes": "{{ user_homes | d({}) | combine({user_name: getent_passwd[user_name][4]}) }}" ... 

但是,自定义的事实会更好。

在Ansible这个时候没有简单的方法来做这个,所以你应该在这个问题上添加你的投票

https://github.com/ansible/ansible/issues/15901

虽然你可以使用这个解决方法: https : //stackoverflow.com/a/33343455/99834你不应该忘记发送你想要的这个反馈,很容易被使用。

我想要一个类似的function,但有时我想为执行者获取不同用户的主文件夹。 所以我写了一个filter,似乎工作得很好 – 只有在一个机器的环境(见第一个评论)。

 import pwd from ansible.errors import AnsibleFilterError def user_attribute(user, key): """ User attribute lookup. :param user: the user to get the attribute for :param key: the attribute index to return :return: the attribute of the given user """ try: return pwd.getpwnam(user).__getattribute__(key) except KeyError: raise AnsibleFilterError('No such user {}'.format(user)) except AttributeError: raise AnsibleFilterError('Wrong index supplied: {}'.format(key)) class FilterModule(object): @staticmethod def filters(): return { 'user_home': lambda x: user_attribute(x, 'pw_dir'), } 

只要在你的filter中包括这个,你可以input{{ username | user_home }} {{ username | user_home }}为你想要的任何用户。 它依赖于pwd包,所以它可能不完美。