【ansible】關於ansible執行過程中載入環境變數問題

HunterMichaelG發表於2020-10-03

一、問題背景

 

SSH遠端執行指令碼報錯"command not found",且環境變數不生效,執行env命令後發現列印出來的環境變數少了很多。

原因是之前將環境變數配置在了/etc/profile中,但是SSH遠端執行指令碼時實際上執行的是non-login shell,而non-login shell不會讀取/etc/profile配置檔案。

 

 

二、關於login shell和non-login shell

 

簡單來說,用SSH客戶端(比如Putty)登陸Linux系統時,要求輸入使用者名稱/密碼登入或根據SSH key登入時,就是login shell。

而在A機器上使用SSH免密碼登入B機器,在B機器上執行Shell指令碼,就是non-login shell。

用Ansible在目標機器上遠端執行Shell指令碼時,也是non-login shell,因為Ansible是基於SSH的。

 

Linux的環境配置檔案

執行man bash可以檢視環境配置檔案的說明,以CentOS7為例:

#  man bash 

1. /etc 下的是系統環境配置,對所有使用者有效,但是/etc/profile只對login shell有效,而/etc/bashrc對login shell和non-login shell都有效。

2. ~下的是當前使用者環境配置,當前使用者環境配置會繼承/etc系統環境配置。 

 

login shell和non-login shell讀取的環境變數配置檔案

 

1. ansible這類遠端執行的non-login shell 並不會載入/etc/profile和~/.bash_profile下的環境變數,只是載入~/.bashrc和/etc/bashrc

2. 如果需要在ansible中執行需要特定環境變數的命令,可以在執行前source一下~/.bash_profile, 或者將環境變數寫在~/.bashrc   /etc/bashrc

 

三、解決non-login shell的環境配置問題

 

方法一:

將login-shell和non-login shell都需要的環境配置放在~/.bashrc中,其它配置放在~/.bash_profile中。

 

方法二:

如果環境配置只放在~/.bash_profile中,需要執行non-login shell時先source ~/.bash_profile再執行命令。

 

雖然大多數情況下,在Shell開頭用#!/usr/bin/env bash比#!/bin/bash更有通用性,但是在通過SSH遠端執行Shell指令碼時,Shell開頭要用#!/bin/bash。

 

事實上我們還可以使用其他的手段來使Ansible遠端執行的會話載入環境變數:既然non-login shell不載入全部的環境變數,那麼我們就再開啟一個login shell好了!

這種方法的好處是既不用對目標環境進行修改,也不用笨拙地顯式載入bash_profile了,只是充分利用ansible以及目標環境提供給我們的功能。

我們知道,Ansible提供了become以及其他一些相關的選項來提供遠端執行過程中進行使用者切換的功能,它們分別是:

你會驚奇地發現你無法使用命令選項設定become_flags的值……這也是個人十分無法理解ansible的設計的一點,既然其他的become相關引數都可以通過命令選項設定,為啥單單這個不可以?只能通過修改Ansible的配置檔案、增加環境變數或在playbook中定義become_flags來設定。

 

我們來看看base.yml:

你可能會說了,如果我登入的使用者就是我希望用來執行命令的使用者呢?

這個其實沒關係,該切換還切換,無非是自己切換到自己,畢竟我們的目標是開啟一個login shell而已。

這裡涉及到ansible的另外一個配置:

 

如果become_method不想用su,sudo也是可以的,只不過become_flags需要設定為-i 。

 

 

四、參考

 

關於ansible遠端執行的環境變數問題

https://blog.csdn.net/u010871982/article/details/78525367

https://www.bbsmax.com/A/6pdDw2WO5w

https://blog.csdn.net/wisdomhealth/article/details/83791130

 

解決Ansible遠端執行無法載入環境變數的問題

https://blog.csdn.net/u010871982/article/details/78525367

https://blog.csdn.net/avenger19/article/details/104858966

 

關於SSH連線遠端主機執行指令碼的環境變數問題

https://blog.csdn.net/whitehack/article/details/51705889

 

ansible-playbook設定java環境變數後不生效解決方法

https://blog.csdn.net/yushi6310/article/details/78683123

 

Execution sequence for .bash_profile, .bashrc, .bash_login, .profile and .bash_logout

https://www.thegeekstuff.com/2008/10/execution-sequence-for-bash_profile-bashrc-bash_login-profile-and-bash_logout

 

Difference between Login Shell and Non-Login Shell

https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell

 

相關文章