如何获得Ansible远程用户的主目录?
我可以使用getent
和awk
组合来做到这一点: 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_env
variables下显示了用户的ansible_env
variables。
- 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_USER
或root
。
你可以尝试使用sudo: yes
,和sudo_user: myarbitraryuser
一起…但是由于某些版本的Ansible中的错误,你可能会看到它不像它应该那样运行。 如果您在Ansible> = 1.9
,则可以使用become: true
和become_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
包,所以它可能不完美。