我可以使用getent
和awk
组合使用shell来完成此操作:
getent passwd $user | awk -F: '{ print $6 }'
作为参考,在Puppet中我可以使用自定义事实,如下所示:
require 'etc'
Etc.passwd { |user|
Facter.add("home_#{user.name}") do
setcode do
user.dir
end
end
}
使用户的主目录可用作home_<user name>
个事实。
如何获取任意远程用户的主目录?
答案 0 :(得分:53)
Ansible(从1.4开始)已经在ansible_env
变量下显示了用户的环境变量。
- hosts: all
tasks:
- name: debug through ansible.env
debug: var=ansible_env.HOME
或者,您可以使用env
上的lookup访问环境变量:
- hosts: all
tasks:
- name: debug through lookup on env
debug: var=lookup('env','HOME')
不幸的是,你可以显然只使用它来获取连接用户的环境变量,因为这个剧本和输出显示:
- 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中的任何内容一样,如果你无法获得一个模块来提供你想要的东西,那么你总是可以自由shell出来(尽管这应该谨慎使用,因为它可能很脆弱,并且会使用类似的东西:
- 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
查找,但这应该给出你想要什么。
答案 1 :(得分:17)
Ansible 1.8引入了getent
module。它将getent结果注册为主机事实 - 在这种情况下,它是getent_passwd
。
打印给定user
的主文件夹:
---
- getent:
database: passwd
key: "{{ user }}"
split: ":"
- debug:
msg: "{{ getent_passwd[user][4] }}"
累积查找表(user_homes
),利用set_fact
和Jinja2 combine()
filter:
---
- 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]}) }}"
虽然使用自定义事实模块会更好。
答案 2 :(得分:15)
用于查找任意用户家的lookup()
或ENV var方法遗憾地无法与Ansible一起使用,因为它以--user=REMOTE_USER
指定的用户身份运行,并且可选地使用sudo
(如果在playbook中sudo: yes
或--sudo
已通过)。这两种运行模式(sudo或no sudo)将改变Ansible正在其中运行的shell环境,即使这样,您也将被限制为指定为-u REMOTE_USER
或root
的用户。
您可以尝试同时使用sudo: yes
和sudo_user: myarbitraryuser
...但是由于certain versions of Ansible中的错误,您可能会发现它的行为不符合预期。如果您使用Ansible&gt; = 1.9
,则可以使用become: true
和become_user: myarbitraryuser
。但是,这意味着您编写的剧本和角色不适用于以前版本的Ansible。
如果您正在寻找一种可移植的方式来获取用户的主目录,该目录也适用于LDAP或其他目录服务,请使用getent
。
创建一个名为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"
答案 3 :(得分:12)
我认为这里给出了几个可行的答案,但我想我可以证明你可以通过将these模块注册为变量来获得它。
PyQT5
注意:如果用户不存在,它将创建用户......
因此我们可以使用debug来显示该var的值,包括路径......
- user:
name: www-data
state: present
register: webserver_user_registered
您可以在其他模块中使用这些属性;
- debug:
var: webserver_user_registered
TASK [wordpress : debug] ******************
ok: [wordpresssite.org] => {
"webserver_user_registered": {
"append": false,
"changed": false,
"comment": "www-data",
"failed": false,
"group": 33,
"home": "/var/www", <<------ this is the user home dir
"move_home": false,
"name": "www-data",
"shell": "/usr/sbin/nologin",
"state": "present",
"uid": 33
}
}
答案 4 :(得分:2)
我知道这是一个非常老的线程,但我认为这是获取用户主目录的一种更简单的方法
- name: Get users homedir
local_action: command echo ~
register: homedir
在Linux(或Unix)系统上,波形符号指向用户主目录。
答案 5 :(得分:2)
每个答案都提到如何在运行剧本并使用debug和var在屏幕上显示它时打印主目录详细信息。
适应@TrinitronX answer
有关将此信息用于新任务的其他信息。
我有一个需要提取其主目录的用户列表。所以我已将用户详细信息添加到列表中
- name: Get home directory
shell: >
getent passwd {{ item.user }} | cut -d: -f6
changed_when: false
with_items:
- "{{java}}"
register: user_home
此处,此步骤将遍历所有用户列表,并将该详细信息注册到user_home。这将是数组的形式。
然后,下一步是将这些信息用于新任务,例如,将文件源到bash配置文件中。这只是一个示例,可以是任何情况,但是方法将保持不变。
- name: Set Java home in .bash_profile
lineinfile: path="{{ item.stdout }}/.bash_profile" regexp='^source "{{ java_dir }}/.bash_profile_java"' line='source "{{ java_dir }}/.bash_profile_java"' state=present
with_items:
- "{{ user_home.results }}"
loop_control:
label: "{{ item.stdout }}"
我在同一个剧本中将java_dir的事实设置为/ usr / java / latest。
数组user_home.results将包含“获取主目录”任务的详细信息。
现在,我们遍历此数组并取出包含主目录路径的stdout值。
我放置了loop_control仅用于打印主目录,否则它将打印整个数组。
通过此过程,我们可以确保如果有n个用户在那里,我们可以采用此方法,并且将保重所有人。
注意:我已经开始学习Ansible,如果我使用的任何术语错误,请原谅。我花了一些时间弄清楚如何做到这一点,并想到了共享它。
答案 6 :(得分:1)
此时在Ansible中没有简单的方法可以做到这一点,这就是你的原因 应该将你的投票添加到这个问题
https://github.com/ansible/ansible/issues/15901
虽然您可以使用此解决方法:https://stackoverflow.com/a/33343455/99834但您不应忘记发送您希望这样易于使用的反馈。
答案 7 :(得分:1)
您可以使用expanduser
。
例如,在循环用户列表时:
- name: Deploys .bashrc
template:
src: bashrc.j2
dest: "{{ '~' + item | expanduser }}/.bashrc"
mode: 0640
owner: "{{ item }}"
group: "{{ item }}"
with_items: user_list
答案 8 :(得分:0)
我进入这个线程是因为我需要从postgres用户打印PGDATA env变量,我还没有找到如何在ansible中更“原生”地进行操作,但是我结束了这个工作:
- name: Find postgresql data directory
shell: 'echo $PGDATA'
become: yes
become_user: postgres
become_flags: "-i "
register: pgdata_dir
然后我可以在其他作业中使用“ {{pgdata_dir.stdout}}”引用它