- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
当我们使用 Windows 桌面下的编辑器编写一个 Shell 文件时,很容易将文件使用的换行符保存为 dos 格式。如果将文件上传到 Linux 服务器执行时,可能会遇到下面的错误。这是因为 。
# 显示一个简单的shell文件
$ cat dosnewline.sh
#!/bin/sh
echo "This is a file with dos newline"
# 该文件使用了 dos 格式的换行符
$ od -bc dosnewline.sh
0000000 043 041 057 142 151 156 057 163 150 015 012 015 012 145 143 150
# ! / b i n / s h \r \n \r \n e c h
0000020 157 040 042 124 150 151 163 040 151 163 040 141 040 146 151 154
o " T h i s i s a f i l
0000040 145 040 167 151 164 150 040 144 157 163 040 156 145 167 154 151
e w i t h d o s n e w l i
0000060 156 145 042 015 012 015 012 015 012
n e " \r \n \r \n \r \n
0000071
# 使用 sh 执行的时候就会有一个报错
$ h dosnewline.sh
: command not found 2:
This is a file with dos newline
: command not found 4:
: command not found 5:
# 获取脚本的返回码也不是0,在一些自动化调用的场景中就会认为脚本执行失败,从而引发后续的问题
$ echo $?
127
# 退出码 127 的意思是 command not foud,对应具体的 dos 换行符所在的行
我们通常所说的换行符在 ASCII 码表中对应下面两个字符.
十进制 | 十六进制 | 字符 | 编程时 |
---|---|---|---|
10 | A | LF(Line feed,New Line) | \n |
13 | D | CR(Carriage return) | \r |
这两个字符被用作换行的标志,但是在不同操作系统中使用的不一样,具体如下:
操作系统 | 换行符 |
---|---|
Unix(包括 Linux) | \n |
Windows | \r\n |
MacOS X 之前的版本 | \r |
MacOS X 及之后的版本 | \n |
为什么 Windows 中会用两个字符而其他系统使用一个字符呢?
据说很久以前,人们在使用老式电传打字机作为输入设备的年代,这种设备内部使用两个字符来另起新行。一个字符把滑动架移回首位 (称为回车),另一个字符把纸上移一行 (称为换行).
当电子计算机问世后,由于存储器曾经非常昂贵。有些人认定没必要用两个字符来表示行尾。于是 UNIX 开发者决定他们可以用一个字符(LF)来表示行尾,Apple 开发者规定了用 (CR)来表示行尾,而 MS-DOS(以及后来的 Windows)开发人员则沿用了老式的两个字符 .
正是因为不同操作系统默认的换行符不同,导致在 Windows 下编写的文件采用了 Windows 下的换行符。而不幸的是 sh 做为 Linux 下的应用,只认识 Unix(包括 Linux)下的换行符,引发的文章开头的问题.
解决的方法有很多,从脚本来源上说,最好我们在编辑过程中就指定使用的换行符,大多数编码常用编辑器例如 Notepadd++ 等都支持这个选项,如下图在 Notepadd++ 的右下角会显示换行符的类型。千万不要使用 Windows 自带的记事本来编写 shell 脚本,记事本是不支持调整换行符的.
除了在编写阶段注意,脚本编写完成后,还可以通过 $ sh -x hello.sh 的方式来检查脚本是否有语法错误,对于本文提供的示例来说输出结果如下,可以看到输出结果给出提示多了 \r 的字符.
$ sh -x dosnewline.sh
+ $'\r'
: command not found 2:
' echo 'This is a file with dos newline
This is a file with dos newline
+ $'\r'
: command not found 4:
+ $'\r'
: command not found 5:
最后如果不小心,这样的脚本已经进入了生产环境,也还有很多的方法来进行修改。很多文章推荐使用 dos2unix 这个命令来快速修改,这个命令使用起来比较方便,但是对于一些生产环境管理严格的单位来说,这个命令未必允许在生产环境安装.
那就还可以用一般都有的 tr 、 awk 、 sed 命令来实现,下面给出具体示例.
$ tr -d '\r' < dosnewline.sh > dosnewline.sh-tr
# 使用 od 比较两个文件,后续的脚本可类似方式比较
$ od -bc dosnewline.sh-tr
0000000 043 041 057 142 151 156 057 163 150 012 012 145 143 150 157 040
# ! / b i n / s h \n \n e c h o
0000020 042 124 150 151 163 040 151 163 040 141 040 146 151 154 145 040
" T h i s i s a f i l e
0000040 167 151 164 150 040 144 157 163 040 156 145 167 154 151 156 145
w i t h d o s n e w l i n e
0000060 042 012 012 012
" \n \n \n
0000064
$ od -bc dosnewline.sh
0000000 043 041 057 142 151 156 057 163 150 015 012 015 012 145 143 150
# ! / b i n / s h \r \n \r \n e c h
0000020 157 040 042 124 150 151 163 040 151 163 040 141 040 146 151 154
o " T h i s i s a f i l
0000040 145 040 167 151 164 150 040 144 157 163 040 156 145 167 154 151
e w i t h d o s n e w l i
0000060 156 145 042 015 012 015 012 015 012
n e " \r \n \r \n \r \n
0000071
$ awk '{ sub("\r$", ""); print }' dosnewline.sh > dosnewline.sh-awk
$ sed 's/\r//' dosnewline.sh > dosnewline.sh-sed
这篇文章首发在我的个人站点 大江小浪 上,更多内容,欢迎访问.
最后此篇关于文件格式引起的脚本执行错误的文章就讲到这里了,如果你想了解更多关于文件格式引起的脚本执行错误的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有没有办法使用 Clojure format(基于 java.util.Formatter)或 cl-format(基于 Common Lisp 的format) 以编程方式设置空格填充?如果您事先知
我正在尝试创建一个用户实体以及数据/文件(pdf格式)。上传并保存到数据库很好,但是当我让用户进入 postman 时尝试发送获取请求方法,然后在数据字段中显示一些糟糕的数据,而且我无法在数据库中看到
我必须将值为 {"STX","ETX"} 的普通字符串数组转换为十六进制值,并且我应该根据 http://www.asciitable.com/ 得到 {2,3} . 最佳答案 听起来你想要一个 Ma
我想格式化我的代码,但不确定哪种格式类型最适合我的项目需要。 我发现仅对于 dart 和 flutter 项目(我都有),有不止一个选项可用于格式化编程语言/框架中预先构建的代码。 Dart : da
我已经尝试了多个代码,例如这样 Sub DateFixer() Application.ScreenUpdating = False Application.Calculation =
SolrQuery query = new SolrQuery(); query.setQuery("*:*"); query.add("wt","csv"); server.query(query)
我有一个包含多个字符串的数据库,我从查询中获取了这些记录,并且我在 QString 中收到了这种格式的数据: "Mon, 13 Nov 2017 09:48:45 +0000" 所以,我需要根据文化来
我有一个 Delphi 2007 DBGrid,我想让用户以更新的 Excel 格式 (OOXML) 保存它,但我的标准是用户不需要安装 Excel。有没有人知道任何已经这样做的组件?是的,我已经搜索
我正在我们的普通 html 站点旁边创建一个移动站点。使用 rails 3.1。移动站点在子域 m.site.com 中访问。 我已经定义了移动格式(Mime::Type.register_alias
我正在尝试使用 xmlstarlet 格式化 xml 文件,但我不想创建新的 xml 文件。 我试过了 xmlstarlet fo --inplace --indent-tab --omit-decl
我在 A 列中有一个带有文本的电子表格。 例如 A1=MY TEXT1 A2=MY TEXT2 A3=MY TEXT3 A4=MY TEXT4 A5=MY TEXT5 我想在文本的前后添加撇号 结果是
我想做一些源代码转换(自动导入列表清理),我想保留注释和格式。我听说过一些关于解析器这样做的事情,我认为是 ghc 解析器。 看起来我可以通过从文件中提取内容来使用 hs-src-exts Langu
我在 Excel 中工作,我想根据另一张表中的列表找出一张表中是否有匹配项。 我已将值粘贴到列表中,并希望从另一张表中返回它们的相应值。包含字母和数字的单元格可以正常工作(例如:D5765000),但
我有一个 DurationField在我的模型中定义为 day0 = models.DurationField('Duration for Monday', default=datetime.time
我正在为我的应用程序开发 WMI 查询。它需要为给定的 VID/PID 找到分配的虚拟 COM 端口。使用 WMI Code Creator 我发现...... 命名空间:root\CIMV2 类:W
我试图弄清楚如何使用 NSTextList,但除了 this SO question 之外,在网上几乎没有找到有用的信息。和 the comment in this blog . 使用这个我已经能够创
我要查询all_objects表在哪里last_ddl_time='01 jan 2010'但它拒绝日期格式... 任何机构给我查询的确切格式? 最佳答案 正如 AKF 所说,您应该使用 Trunc除
我试图在我的应用程序中实现聊天功能。我使用了 2 个 JEditorPane。一个用于保存聊天记录,另一个用于将聊天发送到前一个 JEditorPane。 JEditorPane 是 text/h
我在大学里修了一个编译器类(class),内容非常丰富,很有趣,尽管也很多工作。既然给了我们要实现的语言规范,所以我学不到的一件事就是语言设计。我现在正在考虑创建一种有趣的简单玩具语言,以便我可以玩耍
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
我是一名优秀的程序员,十分优秀!