linux脚本常见问题总结

linux脚本常见问题总结

    在shell脚本开发和部署的时候,遇到了一些问题,把比较简单的常见问题总结一下,警醒自己不要再犯.

一.空格导致的问题

平时使用java开发,变量和赋值运算符之间,习惯用空格隔开,但是在shell脚本里,这样做是有问题的:

错误示例1:

# 输出昨天日期
yesterday = `date -d "1 day ago" +%Y%m%d`
echo "昨天的日期是: ${yesterday}"

    执行脚本的时候会报错,提示未找到yesterday命令,也就无法正常的输出昨天的日期值

正确写法1:需要去掉等号左右两端的空格,两个都要去掉!

# 输出昨天日期
yesterday=`date -d "1 day ago" +%Y%m%d`
echo "昨天的日期是: ${yesterday}"

    既然添加空格会导致意想不到的问题出现,那是否粗暴的不写空格就完事大吉了呢?非也!

错误示例2:

# 比较两个字符串内容是否相等
str1=hello
str2=hello
if [$str1=$str2];then
echo "两个字符串内容相等!"
fi

    乍一看应该没什么问题,但是脚本执行的时候会直接报错!

注意: shell脚本里中括号前后必须加空格!
正确示例2:

# 比较两个字符串内容是否相等
str1=hello
str2=hello
if [ $str1 = $str2 ];then
echo "两个字符串内容相等!"
fi

关于空格的使用问题总结如下:

1. 等号赋值两边不能有空格
2. 命令与选项之间需要空格
3. 管道两边空格可有可无

空格使用还需要注意的一些地方:

1. 变量命名中间不允许有空格
2. 传递的参数包含空格时一定要小心谨慎!否则会有意想不到的问题出现!
(需要将引用变量用双引号引起来)
否则shell会把空格作为分隔符,将一个变量分隔成两个变量

二. 格式转换问题

     在windows下开发,写好的shell脚本,放到linux上执行,往往会因为编码格式的问题存在兼容问题

由编码格式导致的脚本报错信息通常如下:

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

解决方法 : 使用vim修改文件format,把文件编码格式改成unix

    vim 脚本名
    set ff=unix

通过vim命令也可以直接修改文件编码,已解决常见的中文乱码问题

    set fileencoding=utf-8

由于历史遗留问题,windows,unix,Mac三者之间,对于文件中所用的回车换行符,都是不一样的 为避免此问题出现,也可以将格式转换好以保证脚本的跨平台部署!

很多文本编辑器都有格式转换的功能,接下来简单介绍一下如何使用Notepad++完成格式转换,转换方式如下图所示:

在这里插入图片描述

三. 字符串相关问题

1. 字符串拼接

    java中的字符串从语法上是可以直接用 + 号来拼接的
(不过一般情况下不推荐使用这种方法, 不涉及到线程安全问题尽量使用StringBuilder进行字符串拼接)
如果简单粗暴的移植到linux上…

错误示例三

#字符串拼接
str1=hello
str2=world
str3=${str1}+${str2}
echo "${str3}"

输出结果:

hello+world

    从结果中可以看到,对于+号,在字符串拼接时,linux是直接把它当做普通的字符串处理.实际上:

对于变量或者字符串的连接,shell提供了相当简单的做法
直接放到一起或用双引号即可。

正确示例三

#字符串拼接
str1=hello
str2=world
str3=${str1}${str2}
str4="${str1}${str2}"
str5="${str1}""${str2}"
str6="hello""world"

用如上的四种方式都可以得到正确的字符串拼接~

四. 数值比较

假设我想比较两个值的大小,采用如下的处理方式: 

错误示例四

if [ 6 < 10 ];then
echo "6 小于 10"
else
echo "6 不小于 10"
fi

    输出结果会和想象的有所出入,结果如下:

6 不小于 10

同时输出的一句话还有:

没有那个文件或目录

linux是把 "<" 后面的内容当成了重定向的日志路径,在文件系统里找不到10这个文件,所以会抛出错误
同时,认为if 里面的条件不成立,所以打印出  6不小于10 这种明显错误的结论

正确示例五

if [ 6 -lt 10 ];then
echo "6 小于 10"
else
echo "6 不小于 10"
fi

用于数值比较通常有大于、小于、等于、大于等于、小于等于.

linux里面的比较格式: [ 数值1 比较符 数值2 ]   (注意左边的括号与数值1之间有一个空格,同样,数值2和右边的括号之间也有空格)

数值比较运算符对应下面几个:
-eq 	判断相等,相等返回true,否则返回false
-ne 	判断是否不相等,不相等返回true,否则返回false
-gt 	判断左边是否大于右边的值,大于则返回true,否则返回false
-lt 	判断左边是否小于右边的值,小于则返回true,否则返回false
-ge 	判断左边是否大于或等于右边的值,大于则返回true,否则返回false
-le 	判断左边是否小于右边的值,小于则返回true,否则返回false
五.使用特殊字符遇到的问题
写shell脚本,不可避免的要用到一些linux环境下的特殊字符,网上关于这些特殊字符的介绍有很多,我这里不过多介绍
这些特殊字符里,比较有意思的是$符号.
我们都知道$在linux应用的广泛性,在表示变量的时候带给我们极大的方便

可有些时候, 当我们不想用$表述特殊含义的时候,仅仅用它来表示$字符串本身,该怎么使用呢?

首先来说明一下这种场景的背景
因为我们公司使用的是mongo, 而$又是mongo的关键字,where,in,聚合查询等很多操作都离不开$符号,
但是如果在脚本里贸然使用$,往往会得到意想不到的结果 :

比如说如下语句 :
// 查询出test表格里面20190624交易商户号和结算商户号不一致的数目
db.test.find({'AC_DT':'20190624','$where' : 'this.MERC_ID != this.MERGE_MERC_ID'}).count();

在mongo客户端查询确实有这种数据的前提下,用上述语句在Linux查询出来的结果是0哦

那么,我们就该考虑到$是转义字符,不能这么简单粗暴的处理
于是,我在 $前面加上反斜线, 表示转义,修改后脚本如下:

// 查询出test表格里面20190624交易商户号和结算商户号不一致的数目
db.test.find({'AC_DT':'20190624','\$where' : 'this.MERC_ID != this.MERGE_MERC_ID'}).count();

但是出乎意料的是,这样查询出来的结果还是0

最终,我才用下述的办法解决了该问题

//在查询脚本前面添加:
where='$where'
// 之后执行查询语句,查询出test表格里面20190624交易商户号和结算商户号不一致的数目
db.test.find({'AC_DT':'20190624','$where' : 'this.MERC_ID != this.MERGE_MERC_ID'}).count();

这样就得到了正确的结果!
先给where变量赋值为字符串 w h e r e 在 后 面 使 用 ′ where 在后面使用' where使where’的方式调用where的值, 得到的就是正常的字符串$where
这样,MongoDB的查询语法完全不用做任何更改,完美的解决了这个问题!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页