问题描述

最近遇到一个问题:

执行命令 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:是附属提示符,默认是">"。

最新文章

  1. maven打包插件:appassembler
  2. Qt——组件位置随窗口变化
  3. 超小Web手势库AlloyFinger原理
  4. 使用FlaycoBanner实现图片轮播效果(加载网络图片)
  5. [NOIP2015] 斗地主(搜索)
  6. Python六大开源框架对比:Web2py略胜一筹
  7. sgdisk常用操作
  8. HDfs命令
  9. 通过maven添加quartz
  10. SecureCRT配色方案
  11. PostgreSQL的 initdb 源代码分析之十三
  12. Java NIO 学习笔记
  13. [置顶] ARM指令集和常用寄存器
  14. 一个label 里面 显示中文和英文不同颜色
  15. Android学习笔记之Intent
  16. 免费获取SSL证书/一键安装SSL证书/https加密
  17. 数据库主库从库宕机重启后binlog数据同步
  18. python基础内容目录
  19. HTML5之FileReader文件读取接口
  20. hdu 4348 To the moon (主席树 区间更新)

热门文章

  1. java.time 时间和简单任务
  2. Beta阶段团队项目开发篇章2
  3. 个人作业-week2(代码复审)
  4. python查询mysql以字典返回
  5. Lottie开源库实现Android动画效果
  6. c++11 智能指针 unique_ptr、shared_ptr与weak_ptr
  7. 【BZOJ2655】Calc(拉格朗日插值,动态规划)
  8. phpredis -- redis_cluster
  9. [Android Studio] *.jar 与 *.aar 的生成与*.aar导入项目方法(转)
  10. 【DP】【CF1099C】 Postcard