问题描述

最近遇到一个问题:

执行命令 docker exec f4af9b sh -c 'bash /tmp/build.sh' 命令在docker中执行shell,会出现中文乱码的问题。但是在docker容器中单独执行shell脚本却没有出现乱码。查看环境变量存在LANG=en_US.UTF-8,因此从原理上来说是不应该出现乱码的。

但是既然出现了乱码,那么LANG=en_US.UTF-8应该就没有读取到,于是在 build.sh中运行env命令,发现通过docker exec f4af9b sh -c 'bash /tmp/build.sh'方式没有LANG=en_US.UTF-8环境变量,那么原因是什么?

原因定位

原因如下:

docker exec f4af9b sh -c 'bash /tmp/build.sh' 对于docker 容器来说是非登录和非交互式shell,这样就不会读取某些配置文件,导致LANG=en_US.UTF-8没有加载成功。

Linux Shell

下面介绍一下Linux交互式和非交互式shell、登录和非登录shell之间的区别。

  • 交互式shell(interactive shell)和非交互式shell(non-interactive shell)

    • 交互式的shell会有一个输入提示符,并且它的标准输入、输出和错误输出都会显示在控制台上。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、退出。当你退出后,shell也终止了。
    • 非交互式shell是bash script.sh这类的shell。在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾EOF,shell也就终止了。
  • 登录式shell(login shell)和非登陆式shell(no-login shell)

    • 需要输入用户名和密码的shell就是登陆式shell。因此通常不管以何种方式登陆机器后用户获得的第一个shell就是login shell。不输入密码的ssh是公钥打通的,某种意义上说也是输入密码的。
    • 非登陆式的就是在登陆后启动bash等,即不是远程登陆到主机这种。

对于常用环境变量设置文件,整理出如下加载情况表:

文件 非交互+登陆式 交互+登陆式 交互+非登陆式 非交互+非登陆式
/etc/profile 加载 加载 - -
/etc/bashrc 加载 加载 - -
~/.bash_profile 加载 加载 - -
~/.bashrc 加载 加载 加载 -
BASH_ENV - - - 加载

执行脚本,如bash script.sh是属于non-login + non-interactive。

解决思路

因而,执行命令docker exec f4af9b sh -c 'bash /tmp/build.sh'对于docker容器来说是属于non-login + non-interactive。

将上面的bash /tmp/build.sh改为bash --login /tmp/build.sh变为登录shell,就可以读取/etc/profile和~/.bash_profile等文件。

或者在执行bash /tmp/build.sh时在build.sh加入export LANG="en_US.UTF-8"手动设置。

常见的shell变量

PATH:决定了shell将到哪些目录中寻找命令或程序
HOME:当前用户主目录
MAIL:是指当前用户的邮件存放目录。
SHELL:是指当前用户用的是哪种Shell。
HISTSIZE:是指保存历史命令记录的条数
LOGNAME:是指当前用户的登录名。
HOSTNAME:是指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的。
LANG/LANGUGE:是和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
PS1:是基本提示符,对于root用户是#,对于普通用户是$。
PS2:是附属提示符,默认是">"。

Docker中执行Shell出现乱码的更多相关文章

  1. 在docker中执行linux shell命令

    在docker中执行shell命令,需要在命令前增加sh -c,例如: docker run ubuntu sh -c 'cat /data/a.txt > b.txt' 否则,指令无法被正常解 ...

  2. vim中执行shell命令小结

    vim中执行shell命令,有以下几种形式 1):!command 不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容 例如:!ls -l ...

  3. Jenkins 六: 构建中执行shell或者 windows的批处理程序

    Shell/ bat Jenkins 可以在构建中执行shell命令或者windows的batch 命令. 1. 选择一个项目,点击“配置”. 2. 找到“构建” –> “增加构建步骤”.选择 ...

  4. Java中执行shell笔记

    在java中执行shell有好几种方式:第一种(exec)方式一 public static synchronized void runshell2() {    File superuser = n ...

  5. python中执行shell的两种方法总结

    这篇文章主要介绍了python中执行shell的两种方法,有两种方法可以在Python中执行SHELL程序,方法一是使用Python的commands包,方法二则是使用subprocess包,这两个包 ...

  6. 在 Ruby 中执行 Shell 命令的 6 种方法

    我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令.Ruby为我们提供了完成该任务的诸多方法. Exec Kernel#exec 通过执行给定的命令来替换当前进程,例如: $ irb & ...

  7. python中执行shell命令的几个方法小结(转载)

    转载:http://www.jb51.net/article/55327.htm python中执行shell命令的几个方法小结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014- ...

  8. python中执行shell命令行read结果

    +++++++++++++++++++++++++++++ python执行shell命令1 os.system 可以返回运行shell命令状态,同时会在终端输出运行结果 例如 ipython中运行如 ...

  9. Linux中执行shell脚本的4种方法总结

    bash shell 脚本的方法有多种,现在作个小结.假设我们编写好的shell脚本的文件名为hello.sh,文件位置在/data/shell目录中并已有执行权限. 方法一:切换到shell脚本所在 ...

随机推荐

  1. 福大软工 · 第七次作业 - 需求分析报告(404 Note Found队)

    目录 组队后的团队项目的整体计划安排 项目logo及思维导图 项目logo 思维导图 产品思维导图 产品思维导图-引导 产品思维导图-后端数据处理.存储 产品思维导图-短信识别 产品思维导图-智能分析 ...

  2. Java分布式应用

    分布式计算就是通过计算机网络将计算工作分布到多台主机上,多个主机一起协同完成工作. 我试着列一下相关知识吧. 网络通讯,网络是分布式的基础,对分布式的理解建立在对网络的理解上,包括: OSI模型的7层 ...

  3. 消息队列第二篇:MessageQueue实战(课程订单)

    上一篇:消息队列介绍 本篇一开始就上代码,主要演练MessageQueue的实际应用.用户提交订单(消息发送),系统将订单发送到订单队列(Order Queue)中:订单管理系统(消息接收)端,监听消 ...

  4. Internet History, Technology and Security (Week 2)

    Week 2 History: The First Internet - NSFNet Welcome to week 2! This week, we'll be covering the hist ...

  5. GDI+ 支持的图片文件格式

    您可以使用许多标准格式将位图储存在磁盘文件中.GDI+ 支持以下各种图片文件格式. o 位图 (BMP) 位图是 Windows 用来储存设备无关和与应用程序无关的图片的标准格式.文件头决定了指定的位 ...

  6. 性能分析_linux服务器CPU_CPU利用率

    CPU度量 1.  指标范围 1.1  User mode CPU utilization+ System mode CPU utilization 合理值:60-85%,如果在一个多用户系统中us+ ...

  7. get方式传递的数组

  8. linux 配置文件(启动文件、环境文件)启动顺序

    1.登录shell 登录shell时,linux会按一定规则读取启动几个配置文件: /ect/profile $HOME/.bash_profile $HOME/.bashrc $HOME/.bash ...

  9. Hashtable 和 HashMap 以及 ConcurrentHashMap

    备忘: ConcurrentHashMap与Hashtable的区别: Hashtable中采用的锁机制是一次锁住整个hash表,从而同一时刻只能由一个线程对其进行操作:而ConcurrentHash ...

  10. mysql二进制日志的开启和使用

    二进制日志(BINLOG)记录了所有的ddl和dml语句,但不包括数据查询语句.语句以“事件”的形式保存,描述数据更改过程. 环境:win8   mysql5.6.23 1.mysql开启二进制日志 ...