10

I got a interesting behavior in Jenkins.
Jenkins' shell does not use my systems locales.

Jenkins runs as user jenkins on my system.

Logged in as jenkins via SSH:

locale displayed:

LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
etc...

env shows LANG and LANGUAGE variables:

LANG=en_US.UTF-8
LANGUAGE=en_US:en

id shows the ID of user:

uid=1008(jenkins) gid=...

Entered above commands to a jenkins job shell:

locale displayed:

LANG=
LANGUAGE=
LC_CTYPE="POSIX"
etc...

env does not show LANG and LANGUAGE variables

id shows the ID of user (as expected):

uid=1008(jenkins) gid=...

the files:

/etc/profile contains:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en

/etc/default/locale contains:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en

startup script /etc/init.d/jenkins should export system's locales:

# load environments
if [ -r /etc/default/locale ]; then
. /etc/default/locale
export LANG LANGUAGE
elif [ -r /etc/environment ]; then
. /etc/environment
export LANG LANGUAGE
fi


Of course I rebooted after modifying the locales ;)

Apache also uses the system's locales
My system is an Ubuntu 14.04 installation.
Did I miss to check something else?

Thank you for reading!
I hope somebody can help :)

2
  • Jenkins seems to reset all environment variables in build shells. Check the project settings. There is also an env-inject plugin. Commented Oct 29, 2014 at 10:06
  • Your solution should be an answer, not an edit to your question... Commented Oct 31, 2014 at 7:35

2 Answers 2

11

Solution:

This happens because the Jenkins master connects to the slave machine via non-interactive shell, so /etc/profile is not executed, and also /etc/default/locale does not have any effect.
non-interactive shells are usually using ~/.bashrc.

Nearly all details about this topic can be found on askubuntu:
https://askubuntu.com/questions/247738/why-is-etc-profile-not-invoked-for-non-login-shells

adding to ~/.bashrc:

export LANG=en_US.UTF-8
export LANGUAGE=en_US:en


did it for me.

This 'slave problem' is also discussed here:
https://groups.google.com/forum/#!topic/jenkinsci-users/hscDs4pKIoU https://groups.google.com/forum/#!topic/jenkinsci-users/g0fNnDltqeM Kind regards, whosit

0

Aside from what explained in @whosit's answer, a shell launched with the Jenkins sh command inherits the environment variables of the Jenkins process and it is executed as non-login & non-interactive shell. This means that the .bashrc file is not sourced at each sh invocation, but its values might be visible as they are inherited from the main process (either the one of the Jenkins controller or the agent's).

This can cause confusion when the .bashrc file or any other global variable is updated and the new value is not immediately visible in the shells launched after the change.

There are several ways to reflect the changes:

  • restart the Jenkins controller and/or the agents (depending on which the shell is running)
  • source the file .bashrc at each sh invocation
sh """ source .bashrc printenv """ 
  • launch the sh command with a shebang directive, to tell Jenkins to launch a login shell (with --login, that is, it forces the new shell to read the .bashrc file)
sh """#!/bin/bash --login printenv """ 

The fact that the environments variables are visible because they are inherited and not read from the profile files, is not very intuitive nor clearly documented.

In our case, it is not possible to change all the pipelines to add the shebang directive nor to source of the .bashrc file each time we use the Jenkins sh command, so we find it easier to restart the agent each time there is a change in the global environment settings (which is not a very frequent case).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.