操作系统

解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题

Jager · 8月19日 · 2015年 · · 5217次已读

最近接到一个 case:大数据分析那边反馈我们这边推送的数据同比去年同期少了很多。这是很不正常的,因为业务一直在增长。

解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题

于是,我开始顺藤摸瓜的跟进。一开始就发现一个小问题: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

好了,解决了这个问题,我该继续跟进同步问题了。

3 条回应
  1. 阿让达博客 2015-8-22 · 11:58

    技术大牛啊,兄弟佩服,能否换个链接

  2. 明月登楼的博客 2017-1-4 · 21:41

    我来手机上测试一下!好像没有全屏抖动! :evil:

    • avatar
      Jager 2017-1-5 · 9:52

      :evil: 手机上抖死你去。。