我遇到了 Ansible playbook 的问题,其中区域设置似乎没有保留在目标主机上。我正在运行一个包含任务的剧本,该任务将注册为输出日期。它曾经采用这样的长格式: October 20 2045 1:18:21 PM,从日期的某个时刻变成 2045 10 20 13:18:21 GMT+02:00 并且下一个任务失败,因为它是强制转换迄今为止具有特定模式。
然后我创建了另一个任务来查看输出:
- name: show locale settings
ansible.builtin.shell:
cmd: locale
register: locale_otput
tags:
- inquire
目标主机的输出是:
LANG=
LC_CTYPE=C.UTF-8
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
当我手动登录到 host1 并执行“locale”时,输出:
`LANG=en_US.ISO-8859-1
LC_CTYPE=en_US.ISO-8859-1
LC_NUMERIC="en_US.ISO-8859-1"
LC_TIME="en_US.ISO-8859-1"
LC_COLLATE="en_US.ISO-8859-1"
LC_MONETARY="en_US.ISO-8859-1"
LC_MESSAGES="en_US.ISO-8859-1"
LC_PAPER="en_US.ISO-8859-1"
LC_NAME="en_US.ISO-8859-1"
LC_ADDRESS="en_US.ISO-8859-1"
LC_TELEPHONE="en_US.ISO-8859-1"
LC_MEASUREMENT="en_US.ISO-8859-1"
LC_IDENTIFICATION="en_US.ISO-8859-1"
LC_ALL=`
然后我将AAP中的作业切换到另一台主机2,同一作业(AAP)的输出是:
`LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=en_US.utf8`
当登录并本地时:
`LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
`
在主机2上,日期采用长格式(正如我需要的那样)并且任务成功。
我尝试在主机1上的任务中设置环境:
environment:
LANG: en_US.utf8
LC_ALL: en_US.utf8
它有效,日期再次是 2045 年 10 月 20 日下午 1:18:21,但这对我来说不是一个正确的解决方案,因为可能出现的其他问题是 ansible 获取那些 POSIX/空区域设置。
为什么两个输出不同?从 7.9 到 8.8 的修补是否可以实现这种情况?我该怎么做才能确保区域设置相同。
谢谢你。
区域设置基于环境变量。
例如,如果我明确设置它,请查看输出中的
LANG
如何变化:
% locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=sv_SE.UTF-8
LC_TIME=sv_SE.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=sv_SE.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=sv_SE.UTF-8
LC_NAME=sv_SE.UTF-8
LC_ADDRESS=sv_SE.UTF-8
LC_TELEPHONE=sv_SE.UTF-8
LC_MEASUREMENT=sv_SE.UTF-8
LC_IDENTIFICATION=sv_SE.UTF-8
LC_ALL=
% LANG=en_GB.UTF-8 locale
LANG=en_GB.UTF-8
LANGUAGE=
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC=sv_SE.UTF-8
LC_TIME=sv_SE.UTF-8
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY=sv_SE.UTF-8
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER=sv_SE.UTF-8
LC_NAME=sv_SE.UTF-8
LC_ADDRESS=sv_SE.UTF-8
LC_TELEPHONE=sv_SE.UTF-8
LC_MEASUREMENT=sv_SE.UTF-8
LC_IDENTIFICATION=sv_SE.UTF-8
LC_ALL=
登录时,bash 会加载多个文件,例如
/etc/profile
和 ~/.bashrc
。因此,您的区域设置是在这些文件中设置的,这就是为什么您在登录时会出现这种行为。Ansible 不会加载这些文件,因此它将使用默认值。我最好的猜测是,可能在 /etc/environment
中设置了语言环境(为每个进程加载,而不仅仅是 shell),并且这些语言环境被删除了。
如果您依赖于特定的区域设置,我建议使用
environment
显式设置它们(就像您所做的那样)。然后,您可以确保使用正确的区域设置,并且不依赖于系统上的预设,正如您所看到的,这可能会更改并破坏您的剧本。
此外,如果您尝试使用非 UTF-8 语言环境,ansible 会抱怨。
我不知道你在做什么,但我想可能有比从字符串解析日期更好的方法。也许你可以直接获取一个日期对象?但这是另一个话题了。