解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题
最近接到一个 case:大数据分析那边反馈我们这边推送的数据同比去年同期少了很多。这是很不正常的,因为业务一直在增长。
于是,我开始顺藤摸瓜的跟进。一开始就发现一个小问题:scp 推送文件脚本执行后居然会报错:
[root@netdata :/data]# sh pushdata.sh dos2unix: converting file pushdata.log to UNIX format ... dos2unix: problems renaming './u2dtmp8jwsge' to 'pushdata.log' output file remains in './u2dtmp8jwsge' dos2unix: problems converting file pushdata.log
原来是将生成的日志转换成 Unix 格式。按理说应该不会影响数据的推送,不过还是顺手处理下。
奇怪的是,人工去执行 dos2unix 却是正常的,看来和脚本有关系了。看了半天的脚本,也没看出哪儿有明显的错误:
dos2unix /data/pushdata.log
还是先不浪费时间自己摸索了,直接丢百度一下,发现并没有什么 luan 用。进而丢谷歌,终于在一个国外论坛找到了正确的解释:
It turns out that when you run the script from cron your current directory (PWD) is set to your home directory. Unix2dos creates the temporary file used in the conversion in your home directory then can't find it to rename it. Not sure why it can't find it. I added a change directory command (cd) and Unix2dos worked.
大概意思是,crontab 计划任务中的脚本当前执行路径默认会设置为家目录。所以,dos2unix/unix2dos 会在家目录下创建转换后的临时文件(u2dtmp****),导致命令无法在目标路径找到将临时文件,并重命名为被处理的文件名,作者表示他也不知道为什么会找不到。不过他给出的解决办法就是:在脚本里面加入 cd 到日志所在路径的命令即可。
比如,本文 case 中可以在脚本一开始处加入 cd /data
我解决之后发现就释然了。其实问题的原因很简单:
crontab 下执行的脚本,默认的工作路路径是家目录(手动执行的脚本,默认的工作路径则是当前所在目录)。由于脚本中并没有加入工作路径的定义,所以就用了默认的家目录作为工作路径。
dos2unix/unix2dos 这 2 个命令的工作原理是:在工作路径将转换后的内容保存为一个临时文件,然后在将这个临时文件重命名为被处理的文件,完成格式转换。若工作路径和被处理文件并不在同一个目录,就会导致这个报错,生成的临时文件也被保留下来。
所以,若是 crontab 中存在这个问题,将会在家目录下生成大量的 u2dtmp*** 临时文件。
哦了,若是发现 dos2unix/unix2dos 报类似错误,肯定是脚本没有定义工作路径。可以在脚本的前面加入 cd 到文件所在目录再执行 dos2unix/unix2dos 即可。
当然,如果只是要转换格式,我们还有多种替代方案,没必要吊死在 dos2unix/unix2dos 上。毕竟有些系统可能没有这 2 个命令。
替代命令①:sed
#以下2种都可以:
sed -e 's/.$//g' oldfile > newfile
sed 's/^M//' oldfile > newfile #注意 ^M = Ctrl + v,Ctrl + m 命令组合打印出来的字符
替代命令②:tr
cat oldfile | tr -d "r" > newfile
好了,解决了这个问题,我该继续跟进同步问题了。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Windows平台安装Oracle11.2.0.4客户端报错INS-30131
- 实战丨如何制作一个完整的外卖微信小程序开发项目(已开源)
- CMake入门实战——多个源文件
- CMake入门实战——自定义编译选项
- CMake入门实战——其他
- git报错,远程克隆和更新不下来解决方法
- CMake入门实战——生成安装包
- PyTorch 60分钟入门系列之PyTorch简介
- 解决Nginx转发http后不走https的问题 后端tomcat
- PyTorch 60分钟入门系列之自动求导
- Roslyn 打包 NuGet 包添加改动日志
- PyTorch 60分钟入门系列之神经网络
- Linux 是如何管理内存的?
- Jmeter 常用函数(17)- 详解 __substring
- Jmeter 常用函数(14)- 详解 __strLen