Docker中执行Shell出现乱码
问题描述
最近遇到一个问题:
执行命令 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出现乱码的更多相关文章
- 在docker中执行linux shell命令
在docker中执行shell命令,需要在命令前增加sh -c,例如: docker run ubuntu sh -c 'cat /data/a.txt > b.txt' 否则,指令无法被正常解 ...
- vim中执行shell命令小结
vim中执行shell命令,有以下几种形式 1):!command 不退出vim,并执行shell命令command,将命令输出显示在vim的命令区域,不会改变当前编辑的文件的内容 例如:!ls -l ...
- Jenkins 六: 构建中执行shell或者 windows的批处理程序
Shell/ bat Jenkins 可以在构建中执行shell命令或者windows的batch 命令. 1. 选择一个项目,点击“配置”. 2. 找到“构建” –> “增加构建步骤”.选择 ...
- Java中执行shell笔记
在java中执行shell有好几种方式:第一种(exec)方式一 public static synchronized void runshell2() { File superuser = n ...
- python中执行shell的两种方法总结
这篇文章主要介绍了python中执行shell的两种方法,有两种方法可以在Python中执行SHELL程序,方法一是使用Python的commands包,方法二则是使用subprocess包,这两个包 ...
- 在 Ruby 中执行 Shell 命令的 6 种方法
我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令.Ruby为我们提供了完成该任务的诸多方法. Exec Kernel#exec 通过执行给定的命令来替换当前进程,例如: $ irb & ...
- python中执行shell命令的几个方法小结(转载)
转载:http://www.jb51.net/article/55327.htm python中执行shell命令的几个方法小结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014- ...
- python中执行shell命令行read结果
+++++++++++++++++++++++++++++ python执行shell命令1 os.system 可以返回运行shell命令状态,同时会在终端输出运行结果 例如 ipython中运行如 ...
- Linux中执行shell脚本的4种方法总结
bash shell 脚本的方法有多种,现在作个小结.假设我们编写好的shell脚本的文件名为hello.sh,文件位置在/data/shell目录中并已有执行权限. 方法一:切换到shell脚本所在 ...
随机推荐
- 23_IO_第23天(字节流、字符流)_讲义
今日内容介绍 1.字节流 2.字符流 01输入和输出 * A:输入和输出 * a: 参照物 * 到底是输入还是输出,都是以Java程序为参照 * b: Output * 把内存中的数据存储到持久化设备 ...
- php htmlentities和htmlspecialchars 的区别
很多人都以为htmlentities跟htmlspecialchars的功能是一样的,都是格式化html代码的,我以前也曾这么认为,但是今天我发现并不是这样的. The translations ...
- 深度学习:卷积神经网络(convolution neural network)
(一)卷积神经网络 卷积神经网络最早是由Lecun在1998年提出的. 卷积神经网络通畅使用的三个基本概念为: 1.局部视觉域: 2.权值共享: 3.池化操作. 在卷积神经网络中,局部接受域表明输入图 ...
- sourcetree git合并问题
在使用sourcetree做多功能合并(合并不提交)的时候,有时按钮是灰色的,直接点击右上角命令行模式 git merge <branch1> --no-commit 转载请注明博客出处: ...
- TCP/IP协议三次握手和四次挥手大白话解说
前言 昨天晚上被一位师傅问到了TCP/IP的工作机制,心里很清楚三次握手,然而对于四次挥手却忘了,这是大学习里学过的,奋而翻阅书籍和网络对之前所学的做一个温顾,算是夯实自我吧. TCP(Transmi ...
- Asp.Net Core实现文件上传
1. Asp.Net Core Mvc方式 public class UploadController : Controller { private IHostingEnvironment _host ...
- 解决MySQL Slave 触发 oom-killer
最近经常有收到MySQL实例类似内存不足的报警信息,登陆到服务器上一看发现MySQL 吃掉了99%的内存,God ! 有时候没有及时处理,内核就会自己帮我们重启下MySQL,然后我们就可以看到 dme ...
- CF702F T-Shirts
题目描述 The big consignment of t-shirts goes on sale in the shop before the beginning of the spring. In ...
- Access数据库通过ODBC导出到Oracle的两个小问题ora-24801\Ora-01401
问题描述:从access通过odbc导出到oracle出现 ora-24801 非法值 错误 与 Ora-01401 值过大的错误 问题分析:access里面的字段类型为“备注”,导入到ora ...
- python之插入排序
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部 ...