美文网首页
行结束符导致脚本执行错误

行结束符导致脚本执行错误

作者: yestyle | 来源:发表于2018-11-08 11:10 被阅读18次

    故障现象

    最近同事遇到一个问题,他的一段代码使用 system() 执行文件系统中的一个 shell 脚本时提示 not found 错误,简单记录帮他定位解决的过程。

    为简化问题,假设需要执行的脚本文件 echo.sh 在根目录中,内容如下:

    #!/bin/sh
    echo $PATH
    

    功能很简单,即打印环境变量 $PATH 的值。同事的 C 代码如下:

    system("/echo.sh");
    

    执行此语句时,只提示 not found,而没有提示具体什么找不到,需要依次排查几个可疑点。

    故障排查

    首先可以排除的是找不到脚本文件 echo.sh 本身。因为调用时使用的是绝对路径,且 ls 命令显示脚本文件确实存在,且有可执行权限。

    # ls -l /echo.sh
    -rwxr-xr-x    1 root     root           21 Nov  2  2018 /echo.sh
    

    由于脚本文件首行指定将 /bin/sh 作为解析器,因此接着排查 /bin/sh 是否指向了正确的 shell。

    # ls -l /bin/sh
    lrwxrwxrwx    1 root     root            4 Oct 30  2018 /bin/sh -> ash
    # ls -l /bin/ash
    -rwxrwxrwx    1 root     root            7 Oct 30  2018 /bin/ash -> busybox
    # ls -l /bin/busybox
    -rwxrwxrwx    1 root     root      2433952 Oct 30  2018 /bin/busybox
    

    进一步验证 shell 没有问题,在 C 代码中显式地使用 sh 执行脚本正常:

    system("sh /echo.sh");
    

    为了加速问题定位,直接尝试在系统 shell 下执行 /echo.sh,问题依旧。

    之后查看文件内容,使用系统 busybox 集成的功能极其简单的 vi 命令打开脚本文件,注意首行最后的 ^M

    #!/bin/sh^M
    echo $PATH
    

    由此怀疑是行结束符导致的找不到解析器,使用 busybox 集成的 dos2unix 命令将脚本文件转换成 Unix 风格的行结束符:

    # dos2unix /echo.sh
    

    之后再执行就正常了,问题解决。

    # /echo.sh
    /sbin:/bin:/usr/sbin:/usr/bin:/sbin
    

    其实同样的脚本在较新版本的 bash 中执行时可明确给出错误的原因:

    # /echo.sh
    sh: /echo.sh: /bin/sh^M: bad interpreter: No such file or directory
    

    因为出现问题的系统中使用的 busybox 版本较老,提示信息不完善,导致上述的几个排查步骤。

    查看行结束符

    vim 打开文件后,可使用 :set list:e ++ff=unix 显示行结束符,$ 表示换行符(ASCII 码 0x0A),^M 表示回车符(ASCII 码 0x0D)。Unix 风格仅有 $,DOS 风格同时有 ^M$

    file 命令查看文件类型时,若为 DOS 风格行结束符,会有 with CRLF line terminators 字样。

    # file deploy.sh
    deploy.sh: POSIX shell script, ASCII text executable
    # file echo.sh
    echo.sh: POSIX shell script, ASCII text executable, with CRLF line terminators
    

    小结

    • 交叉编译环境需要特别注意脚本文件的行结束符,将 Windows 下编写的脚本文件部署到 Unix 系统环境之前,最好使用 dos2unix 命令转换,反方向的部署请使用 unix2dos 命令。
    • 可使用 vimfile 查看文件的行结束符。

    以上。

    相关文章

      网友评论

          本文标题:行结束符导致脚本执行错误

          本文链接:https://www.haomeiwen.com/subject/gogixqtx.html