Skip to content

shell排错

shell排错

image-20240417082514933

目录

[toc]

案例:shell代码里出现不可见字符<0xa0>-2024.4.17==(已解决)==

故障现象

目标脚本:(格式有问题版脚本)

mysql5.7.29_install.sh

bash
#!/bin/bash#MySQL5.7 Download URL:https:./etc/init.d/functionsSRC_DIR=`pwd`MYSQL='mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz'COLOR='echo -e \E[01;31m'END='\E[0m'MYSQL_ROOT_PASSWORD=mageducheck(){if[$UID -ne0];thenaction"当前用户不是root,安装失败"false exit1ficd $SRC_DIRif[! -e$MYSQL ];then       $COLOR"缺少${MYSQL}文件"$END$COLOR"请将相关软件放在${SRC_DIR}目录下"$END       exitelif[-e/usr/local/mysql ];then      action"数据库已存在,安装失败"false       exitelsereturnfi}install_mysql(){   $COLOR"开始安装MySQL数据库..."$ENDyum -y-qinstalllibaionumactl-libs  libaio&>/dev/null   cd$SRC_DIR  tarxf$MYSQL -C/usr/local/   MYSQL_DIR=`echo $MYSQL| sed -nr 's/^(.*[0-9]).*/\1/p'`   ln-s/usr/local/$MYSQL_DIR /usr/local/mysql   chown-Rroot.root/usr/local/mysql/  idmysql&>/dev/null ||{useradd-s/sbin/nologin-rmysql;action"创建mysql用户";}          echo'PATH=/usr/local/mysql/bin/:$PATH'>/etc/profile.d/mysql.sh  ./etc/profile.d/mysql.sh   cat>/etc/my.cnf<<-EOF[mysqld]server-id=1log-bindatadir=/data/mysqlsocket=/data/mysql/mysql.sock                                                                                                   log-error=/data/mysql/mysql.logpid-file=/data/mysql/mysql.pid[client]socket=/data/mysql/mysql.sockEOFmkdir-p/data/mysqlchownmysql:mysql/data/mysql  mysqld--initialize--user=mysql--datadir=/data/mysql  cp/usr/local/mysql/support-files/mysql.server/etc/init.d/mysqld  chkconfig--addmysqld  chkconfigmysqldon   servicemysqldstart  [$?-ne0]&&{$COLOR"数据库启动失败,退出!"$END;exit;}   MYSQL_OLDPASSWORD=`awk '/A temporary password/{print $NF}' /data/mysql/mysql.log`  mysqladmin -uroot-p$MYSQL_OLDPASSWORDpassword$MYSQL_ROOT_PASSWORD &>/dev/null  action"数据库安装完成"}checkinstall_mysql

shell脚本在.sh里执行后报错,但手动复制到linux终端里是可以正常执行的。

shell脚本在.sh里执行后报错:

image-20240407075552660

  • ==但手动复制到linux终端里是可以正常执行的:==

image-20240415072450307

测试过程

  • 使用cat等命令测试故障文件(无异常)

image-20240415071541432

  • 把代码拷贝到sublime里:发现有异常,存在<0xa0>异常代码。

image-20240407075730419

解决办法

将shell代码拷贝到sublime里,手动删除,然后再次执行脚本测试。

mysql5.7.29_install.sh(正确版代码)

bash
#!/bin/bash#MySQL5.7 Download URL:https:./etc/init.d/functionsSRC_DIR=`pwd`MYSQL='mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz'COLOR='echo -e \E[01;31m'END='\E[0m'MYSQL_ROOT_PASSWORD=mageducheck(){if[$UID -ne0];thenaction"当前用户不是root,安装失败"falseexit1ficd$SRC_DIRif[!-e$MYSQL ];then$COLOR"缺少${MYSQL}文件"$END$COLOR"请将相关软件放在${SRC_DIR}目录下"$ENDexitelif[-e/usr/local/mysql ];thenaction"数据库已存在,安装失败"falseexitelsereturnfi}install_mysql(){$COLOR"开始安装MySQL数据库..."$ENDyum-y-qinstalllibaionumactl-libslibaio&>/dev/nullcd$SRC_DIRtarxf$MYSQL -C/usr/local/MYSQL_DIR=`echo $MYSQL| sed -nr 's/^(.*[0-9]).*/\1/p'`ln-s/usr/local/$MYSQL_DIR /usr/local/mysqlchown-Rroot.root/usr/local/mysql/idmysql&>/dev/null ||{useradd-s/sbin/nologin-rmysql;action"创建mysql用户";}echo'PATH=/usr/local/mysql/bin/:$PATH'>/etc/profile.d/mysql.sh./etc/profile.d/mysql.shcat>/etc/my.cnf<<-EOF[mysqld]server-id=1log-bindatadir=/data/mysqlsocket=/data/mysql/mysql.sock log-error=/data/mysql/mysql.logpid-file=/data/mysql/mysql.pid[client]socket=/data/mysql/mysql.sockEOFmkdir-p/data/mysqlchownmysql:mysql/data/mysqlmysqld--initialize--user=mysql--datadir=/data/mysqlcp/usr/local/mysql/support-files/mysql.server/etc/init.d/mysqldchkconfig--addmysqldchkconfigmysqldonservicemysqldstart[$?-ne0] &&{$COLOR"数据库启动失败,退出!"$END;exit;}MYSQL_OLDPASSWORD=`awk '/A temporary password/{print $NF}' /data/mysql/mysql.log`mysqladmin-uroot-p$MYSQL_OLDPASSWORDpassword$MYSQL_ROOT_PASSWORD &>/dev/nullaction"数据库安装完成"}checkinstall_mysql

哇哦,可以了哦:

总结经验

一些shell执行如果报错,可以按如下方式检查:

1、cat -v file查看文件是否存在异常字符 (如果存在,使用:set ff=uninx来处理异常字符)

2、将代码拷贝到sublime里,观察是否存在异常字符;

案例:脚本在用户登录时输出大量信息,了干扰非交互式 shell 环境,例如sftp服务-2024.7.28(已解决)

故障环境:

centos7.6 1810虚机

1、故障现象

未在/etc/profile.d目录下放置systyeminfo.sh脚本时,typora里可正常上传图片,ShareX也可正常通过sftp上传图片。

但是一旦该目录下有systyeminfo.sh脚本时,typora里会上传图片失败,ShareX也不能通过sftp上传图片。

这个就很奇怪了呀。。。

未在/etc/profile.d目录下放置systyeminfo.sh脚本时

image-20240728123242591

typora里可正常上传图片:

image-20240728123121820

ShareX也可正常通过sftp上传图片:

image-20240728123146577

/etc/profile.d目录下放置systyeminfo.sh脚本时

image-20240728123437393

typora里会上传图片失败:

image-20240728123357656

ShareX也不能通过sftp上传图片:

image-20240728123426739

这个是为什么呢?

???why

systeninfo脚本内容

bash
[root@docusaurus-wiki ~]#cat /tmp/systeminfo.sh #!/bin/bash# by 运维朱工# site:bash.lutixia.cn##################################### 获取IP地址和主机名IP_ADDR=$(hostname-I|cut-d''-f1)HOSTNAME=$(hostname)# CPU负载信息:cpu_load() {echo-e"\t\t\tcpu的负载情况"echo-e"\t------------------------------------------------"echo-e"\tCPU load in 1 min is:`awk  '{printf "%15s",$1}' /proc/loadavg`"echo-e"\tCPU load in 5 min is:`awk  '{printf "%15s",$2}' /proc/loadavg`"echo-e"\tCPU load in 10 min is:`awk  '{printf "%15s",$3}' /proc/loadavg`"echo}# mem基本信息:memory_info() {echo-e"\t\t\t内存的使用情况"echo-e"\t------------------------------------------------"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存总容量:",$2}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存空闲容量:",$4}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存缓存:",$6}'`"echo}# 磁盘使用量排序:disk_rank() {echo-e"\t\t\t各分区使用率"echo-e"\t------------------------------------------------"df-h-xtmpfs-xdevtmpfs|sort-nr-k5|awk'/dev/{printf "\t%-20s %10s\n",$1,$5}'echo}# 显示系统信息echoecho-e"\t\t\t系统基本信息:"echo-e"\t------------------------------------------------"echo-e"\tCurrent Time :$(date)"echo-e"\tVersion :$(cat/etc/os-release |grep-w"PRETTY_NAME"|cut-d=-f2|tr-d'"')"echo-e"\tKernel :$(uname-r)"echo-e"\tUptime :$(uptime-p)"echo-e"\tIP addr :$IP_ADDR"echo-e"\tHostname :$HOSTNAME"echo-e"\tCpu :$(lscpu|grep"Model name:"|sed's/Model name:\s*echo-e"\tMemory :$(free-h|awk'/^Mem:/ {print $3 "/" $2 }')"echo-e"\tSWAP :$(free-h|awk'/^Swap:/ {print $3 "/" $2 }')"echo-e"\tUsers Logged :$(who|wc-l) users"echocpu_loadmemory_infodisk_rank

image-20240728123636302

2、gpt

提问:

bash
systeminfo.sh#!/bin/bash# by 运维朱工# site:bash.lutixia.cn##################################### 获取IP地址和主机名IP_ADDR=$(hostname-I|cut-d''-f1)HOSTNAME=$(hostname)# CPU负载信息:cpu_load() {echo-e"\t\t\tcpu的负载情况"echo-e"\t------------------------------------------------"echo-e"\tCPU load in 1 min is:`awk  '{printf "%15s",$1}' /proc/loadavg`"echo-e"\tCPU load in 5 min is:`awk  '{printf "%15s",$2}' /proc/loadavg`"echo-e"\tCPU load in 10 min is:`awk  '{printf "%15s",$3}' /proc/loadavg`"echo}# mem基本信息:memory_info() {echo-e"\t\t\t内存的使用情况"echo-e"\t------------------------------------------------"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存总容量:",$2}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存空闲容量:",$4}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存缓存:",$6}'`"echo}# 磁盘使用量排序:disk_rank() {echo-e"\t\t\t各分区使用率"echo-e"\t------------------------------------------------"df-h-xtmpfs-xdevtmpfs|sort-nr-k5|awk'/dev/{printf "\t%-20s %10s\n",$1,$5}'echo}# 显示系统信息echoecho-e"\t\t\t系统基本信息:"echo-e"\t------------------------------------------------"echo-e"\tCurrent Time :$(date)"echo-e"\tVersion :$(cat/etc/os-release |grep-w"PRETTY_NAME"|cut-d=-f2|tr-d'"')"echo-e"\tKernel :$(uname-r)"echo-e"\tUptime :$(uptime-p)"echo-e"\tIP addr :$IP_ADDR"echo-e"\tHostname :$HOSTNAME"echo-e"\tCpu :$(lscpu|grep"Model name:"|sed's/Model name:\s*echo-e"\tMemory :$(free-h|awk'/^Mem:/ {print $3 "/" $2 }')"echo-e"\tSWAP :$(free-h|awk'/^Swap:/ {print $3 "/" $2 }')"echo-e"\tUsers Logged :$(who|wc-l) users"echocpu_loadmemory_infodisk_rank这个systeminfo.sh脚本被放置在/etc/profile.d目录下,用以登录系统后显示机器的一些配置信息。但是,放置后,我之前利用nginx提供了/images作为一个目录提供图床服务,此时无法正常利用picgo来上传图片了,并且sharex软件也无法通过sftp上传图片了。将/etc/profile.d目录下的systeminfo.sh移除后,就都正常了。请帮我看下是什么原因?是这个systeminfo.sh哪里有错吗?

回答:

你的 systeminfo.sh脚本放置在 /etc/profile.d目录下后,导致图床服务和文件上传功能无法正常工作。这种情况可能是由于脚本在每次用户登录时执行,并且在某些情况下可能产生了输出或错误,干扰了非交互式 shell 环境的工作。

一些常见的问题包括:

  1. 输出干扰:脚本在用户登录时输出大量信息,可能干扰非交互式 shell 环境,比如 sftp 和其他服务
  2. 潜在错误:脚本可能产生错误输出,这些错误信息可能干扰到其他进程或服务。

可以通过以下方式修改脚本,以减少对非交互式 shell 环境的影响:

1. 确保脚本只在交互式 shell 中运行

在脚本的开头添加条件检查,确保脚本只在交互式 shell 中运行。这可以通过检查 PS1环境变量是否存在来实现:

bash
#!/bin/bash# by 运维朱工# site:bash.lutixia.cn##################################### 检查是否为交互式 shellif[[$-!=*i*]];thenreturnfi# 获取IP地址和主机名IP_ADDR=$(hostname-I|cut-d''-f1)HOSTNAME=$(hostname)# CPU负载信息:cpu_load() {echo-e"\t\t\tcpu的负载情况"echo-e"\t------------------------------------------------"echo-e"\tCPU load in 1 min is:`awk  '{printf "%15s",$1}' /proc/loadavg`"echo-e"\tCPU load in 5 min is:`awk  '{printf "%15s",$2}' /proc/loadavg`"echo-e"\tCPU load in 10 min is:`awk  '{printf "%15s",$3}' /proc/loadavg`"echo}# mem基本信息:memory_info() {echo-e"\t\t\t内存的使用情况"echo-e"\t------------------------------------------------"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存总容量:",$2}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存空闲容量:",$4}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存缓存:",$6}'`"echo}# 磁盘使用量排序:disk_rank() {echo-e"\t\t\t各分区使用率"echo-e"\t------------------------------------------------"df-h-xtmpfs-xdevtmpfs|sort-nr-k5|awk'/dev/{printf "\t%-20s %10s\n",$1,$5}'echo}# 显示系统信息echoecho-e"\t\t\t系统基本信息:"echo-e"\t------------------------------------------------"echo-e"\tCurrent Time :$(date)"echo-e"\tVersion :$(cat/etc/os-release |grep-w"PRETTY_NAME"|cut-d=-f2|tr-d'"')"echo-e"\tKernel :$(uname-r)"echo-e"\tUptime :$(uptime-p)"echo-e"\tIP addr :$IP_ADDR"echo-e"\tHostname :$HOSTNAME"echo-e"\tCpu :$(lscpu|grep"Model name:"|sed's/Model name:\s*echo-e"\tMemory :$(free-h|awk'/^Mem:/ {print $3 "/" $2 }')"echo-e"\tSWAP :$(free-h|awk'/^Swap:/ {print $3 "/" $2 }')"echo-e"\tUsers Logged :$(who|wc-l) users"echocpu_loadmemory_infodisk_rank

2. 确保脚本无错误输出

检查脚本中的每个命令,确保没有错误输出。可以通过重定向错误输出到 /dev/null来防止错误信息干扰其他进程:

bash
# 获取IP地址和主机名IP_ADDR=$(hostname-I2>/dev/null|cut-d''-f1)HOSTNAME=$(hostname2>/dev/null)

通过上述修改,确保 systeminfo.sh只在交互式 shell 中运行,避免干扰 nginxsftp服务。这应该能够解决你的问题。如果问题依然存在,建议进一步检查 nginxsftp服务的日志,以确定具体的错误原因。

3、解决办法

更新代码

bash
cd/etc/profile.d/vimsysteminfo-v2.shchmod+xsysteminfo-v2.sh

systeminfo-v2-2024.7.28.sh

bash
#!/bin/bash# by 运维朱工# site:bash.lutixia.cn##################################### 检查是否为交互式 shellif[[$-!=*i*]];thenreturnfi# 获取IP地址和主机名IP_ADDR=$(hostname-I|cut-d''-f1)HOSTNAME=$(hostname)# CPU负载信息:cpu_load() {echo-e"\t\t\tcpu的负载情况"echo-e"\t------------------------------------------------"echo-e"\tCPU load in 1 min is:`awk  '{printf "%15s",$1}' /proc/loadavg`"echo-e"\tCPU load in 5 min is:`awk  '{printf "%15s",$2}' /proc/loadavg`"echo-e"\tCPU load in 10 min is:`awk  '{printf "%15s",$3}' /proc/loadavg`"echo}# mem基本信息:memory_info() {echo-e"\t\t\t内存的使用情况"echo-e"\t------------------------------------------------"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存总容量:",$2}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存空闲容量:",$4}'`"echo-e"\t`free -h | awk '/Mem/{printf "%-10s %s","内存缓存:",$6}'`"echo}# 磁盘使用量排序:disk_rank() {echo-e"\t\t\t各分区使用率"echo-e"\t------------------------------------------------"df-h-xtmpfs-xdevtmpfs|sort-nr-k5|awk'/dev/{printf "\t%-20s %10s\n",$1,$5}'echo}# 显示系统信息echoecho-e"\t\t\t系统基本信息:"echo-e"\t------------------------------------------------"echo-e"\tCurrent Time :$(date)"echo-e"\tVersion :$(cat/etc/os-release |grep-w"PRETTY_NAME"|cut-d=-f2|tr-d'"')"echo-e"\tKernel :$(uname-r)"echo-e"\tUptime :$(uptime-p)"echo-e"\tIP addr :$IP_ADDR"echo-e"\tHostname :$HOSTNAME"echo-e"\tCpu :$(lscpu|grep"Model name:"|sed's/Model name:\s*echo-e"\tMemory :$(free-h|awk'/^Mem:/ {print $3 "/" $2 }')"echo-e"\tSWAP :$(free-h|awk'/^Swap:/ {print $3 "/" $2 }')"echo-e"\tUsers Logged :$(who|wc-l) users"echocpu_loadmemory_infodisk_rank

4、测试效果

这次是可以正常上传图片的:

image-20240728144645287

image-20240728144713749

登录系统也是可以正常输出信息的:

image-20240728144828154