shell脚本报错之-No such file or directory究极分析及解决
🍁博主简介:
🏅云计算领域优质创作者
🏅2022年CSDN新星计划python赛道第一名
🏅2022年CSDN原力计划优质作者
🏅阿里云ACE认证高级工程师
🏅阿里云开发者社区专家博主
💊交流社区:CSDN云计算交流社区欢迎您的加入!
目录
1、脚本执行报错内容
2、故障分析解决
2.1、原因及解决方法1:文件权限问题
2.2、原因及解决方法2:文件依赖问题
2.3、原因及解决方法3:文件格式问题
2.4、原因及解决方法4:通过dirname来定义脚本路径问题
1、脚本执行报错内容
当我们在执行shell脚本时,脚本内容中需要引用某个其他路径下的文件或者对其做处理时,
比如:
cat /root/libs/sql/echat.sql awk '{print $NF}' /root/libs/sql/echat.sql grep "字符串" /root/libs/sql/echat.sql
等等....
然后执行脚本的时候报错显示/root/libs/sql/echat.sql:No such file or directory,文件找不到?
但是我们退出脚本在命令行执行时候却能找到这个文件!
root@xiaopeng:~# ll /root/libs/sql/echat.sql -rw-r--r-- 1 999 1000 92915 Apr 9 09:04 /root/libs/sql/echat.sql
2、故障分析解决
2.1、原因及解决方法1:文件权限问题
可能是你在脚本中的命令是对此文件进行处理,比如sed替换文件内容等,这个时候如果此文件没有可执行权限,那么脚本中就会调用失败。
解决方法:
#给文件添加可执行权限 chmod +x /root/libs/sql/echat.sql #再次查看权限 ll /root/libs/sql/echat.sql -rwxr-xr-x 1 999 1000 92915 Apr 9 09:04 /root/libs/sql/echat.sql*
2.2、原因及解决方法2:文件依赖问题
如果问题仍然存在,可能是由于缺少文件的依赖项
解决方法:
用ldd命令查看文件,若返回 not a dynamic executable则说明此文件不是动态可执行文件,不需要考虑依赖问题,那么就继续排查其他原因
ldd /root/libs/sql/echat.sql not a dynamic executable
2.3、原因及解决方法3:文件格式问题
如果问题仍然存在,
可能是此文件实在windows下用一些idea工具编写,
或者直接是在windows下用其他记事本写好再拿到linux中的
或者是从其他脚本文件中直接复制了内容粘贴到此脚本文件中
解决方法:
先查看文件格式是否为unix
vim或者vi命令打开脚本,然后按一下“:”左下角显示出“:”之后输入:set ff然后回车
如下:
如果返回了fileformat=dos,那么说明你的脚本文件格式不正确,需要修改为unix格式
修改方法一:
vim或者vi命令打开脚本,然后按一下“:”左下角显示出“:”之后输入:set ff=unix 然后回车
如下:
然后再次用:set ff查看,显示为fileformat=unix了,然后:wq保存退出脚本,就能正常执行啦!
修改方法一:
不需要打开脚本,直接在linux命令行里面输入dos2unix 脚本名就可以了,如下:
dos2unix install.ini
如果返回The program 'dos2unix' is currently not installed说明没有这个命令,安装一下就可以了
centos和redhat操作系统执行如下命令:
yum -y install The program dos2unix #安装dos2unix命令 dos2unix 脚本名 #将脚本文件的格式修改为linux平台支持的格式
ubuntu操作系统执行如下命令:
apt update apt install -y dos2unix #安装dos2unix命令 dos2unix 脚本名 #将脚本文件的格式修改为linux平台支持的格式
2.4、原因及解决方法4:通过dirname来定义脚本路径问题
这个原因导致我的脚本执行报错No such file or directory,排查了一下午时间折腾死了
原因就是为了能让脚本在linux的任何路径下都可以执行,也为了方便调用其他文件,就用dirname来定义了脚本路径的变量。如下:
Script_Path=`dirname "$0"` # $0就是脚本文件名 # dirname命令可以获取到文件所在的路径 # Script_Path是脚本文件所在路径的变量名
最后排查发现,此`dirname "$0"`输出的内容并不是绝对路径,而是相对路径。
相当于$Script_Path调用到的值就只是个“.”在linux中“.”代表当前的路径,如果脚本在/opt下执行,$Script_Path输出的也只是一个点,理论上代表的就是当前路径,但是当你需要调用此路径下的其他文件的时候,就会出错了!写一个小测试脚本展示一下
比如我的脚本中调用了脚本所在路径下的一个speech.sql文件,然后脚本执行报错./libs/sql/speech.sql:No such file or directory
我根据报错在命令行执行ls ./libs/sql/speech.sql却能找到这个文件
但是脚本执行过程中它只认绝对路径,在脚本内部它并不能解释出这个“.”是当前路径
解决办法:
将脚本中的脚本路径变量的值用其他方法表示,比如:Script_Path=`pwd`
如下:
也可以写成Script_Path=$(pwd),这两种写法都是一样的,如下:
至此,No such file or directory问题就完美解决了!
还有一种原因就是windows写的文件和linux中的文件内容因为换行符不同导致无法正常执行,这个问题我暂时还没遇到过,以后遇到了再追加到此篇博文中吧