当前位置:   article > 正文

Win10下写的shell脚本,在centOS7中运行报错:/bin/bash^M: bad interpreter: No such file or directory_windows编辑过的sh脚本在centos系统无法使用

windows编辑过的sh脚本在centos系统无法使用

目录

1. 测试过程遇到的问题

2. 问题产生的原因

3. 解决办法


 【写在前面】

问题的原因和解决方案的内容,参考自下方文章,可直接看原文:
shell脚本执行报错:/bin/bash^M: bad interpreter: No such file or directory

1. 测试过程遇到的问题

为了处理性能诊断的一些问题,T准备了一份topcpu.sh(内容见文末),用来自动获取某个进程的多个线程信息,并自动完成一些转换(比如进制转换等): ./topcpu.sh -p ${pid} 5   (5表示要展示的个数)。

文档是在在Win10环境下编写的,我直接使用这个脚本在centOS7中运行,结果报错了:/bin/bash^M: bad interpreter: No such file or directory......

2. 问题产生的原因

(1)报错原因?

经过搜索相关文章和资料,获知:shell脚本格式必须是unix,但这个脚本是在win10上编写,然后直接使用在Linux上,所以报错。

因为:windows环境下的文件是dos格式,即每行结尾以\r\n来标识,而linux下的文件是unix格式,行尾则以\n来标识。

(2)如何判断某脚本是dos格式还是unix格式?

1)方式一:cat -A filename

解析:输出结果中行末尾是^M$,则是dos格式;行末尾只是$,则是unix格式。

2)方式二:vim filename

解析:编辑文件,执行“:set ff”。若执行结果为fileformat=dos则为dos格式,若执行结果为fileformat=unix则为unix格式。

3)方式三:od -t x1 filename

解析:以16进制查看文件,若输出结果中存在“0d 0a”则为dos格式,若只有“0a”则为unix格式。其中“0d”即为回车符“\r”,“0a”即为换行符“\n”。

3. 解决办法

(1)方法一:sed -i "s/\r//" filename 或 sed -i "s/^M//" filename

解析:直接将回车符替换为空字符串。

(2)方法二:vim filename,编辑文件,执行“: set ff=unix”

解析:将文件设置为unix格式,执行“:wq”,保存退出。

(3)方法三:dos2unix filename 或 busybox dos2unix filename

解析:如果提示command not found,可以优先考虑使用前两种方法。

【附】  topcpu.sh脚本内容如下

  1. #!/bin/bash
  2. # @Function
  3. # TOP CPU Thread INFO.
  4. #
  5. #
  6. #
  7. PROG=`basename $0`
  8. usage() {
  9. cat <<EOF
  10. Usage: ${PROG} [OPTION]...
  11. Java top cpu print the stack of these threads.
  12. Example: ${PROG} -c 10
  13. Options:
  14. -p, --pid java process(use jps find)
  15. -c, --count set the thread count to show, default is 5
  16. -h, --help display this help and exit
  17. EOF
  18. exit $1
  19. }
  20. ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`
  21. [ $? -ne 0 ] && usage 1
  22. eval set -- "${ARGS}"
  23. while true; do
  24. case "$1" in
  25. -c|--count)
  26. count="$2"
  27. shift 2
  28. ;;
  29. -p|--pid)
  30. pid="$2"
  31. shift 2
  32. ;;
  33. -h|--help)
  34. usage
  35. ;;
  36. --)
  37. shift
  38. break
  39. ;;
  40. esac
  41. done
  42. count=${count:-5}
  43. redEcho() {
  44. [ -c /dev/stdout ] && {
  45. # if stdout is console, turn on color output.
  46. echo -ne "\033[1;31m"
  47. echo -n "$@"
  48. echo -e "\033[0m"
  49. } || echo "$@"
  50. }
  51. ## Check the existence of jstack command!
  52. if ! which jstack &> /dev/null; then
  53. [ -n "$JAVA_HOME" ] && [ -f "$JAVA_HOME/bin/jstack" ] && [ -x "$JAVA_HOME/bin/jstack" ] && {
  54. export PATH="$JAVA_HOME/bin:$PATH"
  55. } || {
  56. redEcho "Error: jstack not found on PATH and JAVA_HOME!"
  57. exit 1
  58. }
  59. fi
  60. uuid=`date +%s`_${RANDOM}_$$
  61. cleanupWhenExit() {
  62. rm /tmp/${uuid}_* &> /dev/null
  63. }
  64. trap "cleanupWhenExit" EXIT
  65. printStackOfThread() {
  66. while read threadLine ; do
  67. pid=`echo ${threadLine} | awk '{print $1}'`
  68. threadId=`echo ${threadLine} | awk '{print $2}'`
  69. threadId0x=`printf %x ${threadId}`
  70. user=`echo ${threadLine} | awk '{print $3}'`
  71. pcpu=`echo ${threadLine} | awk '{print $5}'`
  72. jstackFile=/tmp/${uuid}_${pid}
  73. [ ! -f "${jstackFile}" ] && {
  74. jstack ${pid} > ${jstackFile} || {
  75. redEcho "Fail to jstack java process ${pid}!"
  76. rm ${jstackFile}
  77. continue
  78. }
  79. }
  80. redEcho "The stack of busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) of java process(${pid}) of user(${user}):"
  81. sed "/nid=0x${threadId0x}/,/^$/p" -n ${jstackFile}
  82. done
  83. }
  84. [ -z "${pid}" ] && {
  85. ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk '$4=="java"{print $0}' |
  86. sort -k5 -r -n | head --lines "${count}" | printStackOfThread
  87. } || {
  88. ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}' |
  89. sort -k5 -r -n | head --lines "${count}" | printStackOfThread
  90. }

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/913526
推荐阅读
相关标签
  

闽ICP备14008679号