gpt4 book ai didi

linux - Ansible 中全局修改的 $PATH 无法按常规 Linux shell 的预期工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:14:29 26 4
gpt4 key购买 nike

我想下载一些二进制文件,例如 Helm并使用 $PATH 使它们在全局范围内可用。为了避免使用 root 权限下载或者必须执行步骤(使用标准用户下载并移动到 $PATH 中的某个 bin 文件夹,例如 /usr/local/bin),我的想法是创建 $HOME/bin 并将其添加到 $PATH

This blog article用于将自定义路径添加到 /etc/environment。然后我将其重新加载为 described here .这是我的 POC 剧本,我尝试在其中添加 exa :

- name: Test
hosts: all

vars:
- bin: /home/vagrant/bin

tasks:
- name: Test task
file:
path: "{{bin}}"
state: directory

- name: Add {{bin}} to path
become: yes
lineinfile: >
dest=/etc/environment
state=present
backrefs=yes
regexp='PATH=(["]*)((?!.*?{{bin}}).*?)(["]*)$'
line="PATH=\1\2:{{bin}}\3"

- name: Check path1
shell: echo $PATH

- name: Download exa
unarchive:
src: https://github.com/ogham/exa/releases/download/v0.8.0/exa-linux-x86_64-0.8.0.zip
dest: "{{bin}}"
remote_src: yes

- name: reload env file
shell: for env in $( cat /etc/environment ); do export $(echo $env | sed -e 's/"//g'); done

- name: Check path after reload env file
shell: echo $PATH

- name: Test exa from PATH
shell: exa-linux-x86_64 --version

在最后一个 tash Test exa from PATH 中抛出错误:

"stderr": "/bin/sh: 1: exa-linux-x86_64: not found"

echo $PATH 命令都保留在

"stdout": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

但修改后的 /etc/environment 有效。当我在没有 ansible 的机器上使用 ssh 时,$PATH 很好,而且 exa-linux-x86_64 --version 也可以工作:

~$ echo $PATH
/home/vagrant/bin:/home/vagrant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/vagrant/bin:/snap/bin

环境

Ubuntu 18.04 主机系统运行带有 Ubuntu 16.04 盒子的 Vagrant。 Ansible 由 Vagrant 在 Ubuntu 16.04 上执行。

可能的解决方法

使用单独的环境变量

像这样设置环境变量时

  - name: Test exa from PATH
shell: exa-linux-x86_64 --version
environment:
PATH: "{{ ansible_env.PATH }}:{{bin}}"

它有效。但我必须至少在游戏层面应用这些台词。我想像 /etc/environment 在常规 shell 中那样全局设置它。 This questions似乎有相同的目标,但在 Solaris 上。 answear 似乎只从主机设置$PATH,这对我没有用,因为自定义 bin 目录不存在。

只使用绝对路径

  - name: Test exa from PATH
shell: "{{bin}}/exa-linux-x86_64 --version"

这会减少开销,但您必须记住始终在命令前加上路径变量。似乎也容易出错

理解问题

我想要一个真正的解决方案并了解导致问题的原因。我不清楚为什么 $PATH 修改在 Ansible 上如此困难,而在底层 linux 系统中它可以很容易地完成。 This question假设我们在 ansible 中没有交互式 session 。似乎没有可用的 $PATH。根据the documentation ,我们可以通过将 -l 传递给 bash 来存档它。所以我发现以下工作:

  - name: Test exa from PATH
shell: bash -l -c "exa-linux-x86_64 --version"

但是下面会导致错误:

  - name: Test exa from PATH
shell: exa-linux-x86_64 --version
args:
executable: /bin/bash -l

Ansible 在这里用错误的 args 引号中断了命令:

"'/bin/bash -l' -c 'exa-linux-x86_64 --version'"

This ticket建议 Ansible 团队解决此问题,以便我们获得带有 $PATH 的登录 shell。自 2014 年以来,根本没有提供真正的解决方案。

问题

  1. 获取或不访问修改后的 $PATH 的不同 shell 类型的目的是什么?
  2. 为什么 Ansible 会使事情复杂化?提供一个解决这个问题的登录 shell 不是更容易吗?他们这样做有什么原因吗?
  3. 我们如何处理由此产生的问题?什么是最佳实践?

最佳答案

回答你的问题

1) What is the purpose of different shell types that get access to the modified $PATH or not?

在 Ansible 支持的所有操作系统中统一它是不值得的。这也解释了“我不清楚为什么 $PATH 修改在 Ansible 上如此困难,而在底层 linux 系统中它可以很容易地完成。”

2) Why Ansible complicates things? Wouldn't it be easier to provide a login shell that solve this issue? Are there reasons why they did what they did?

相反,不关心它更容易。保持简单愚蠢是原因。

3) How can we deal with the resulting problems? What is best practice?

几十年来的最佳实践是 Tools, no policy

关于linux - Ansible 中全局修改的 $PATH 无法按常规 Linux shell 的预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55199479/

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