Linux shell的一些小结

最近在做大数据分析的项目,需要编写shell脚本。之前写shell脚本的次数比较少,处于一种了解的状态。但是经过这个月反复修改编写shell脚本下来,对shell也算是入门了吧。所以特意把自己的一些觉得好的习惯写下来,也方便以后复制(* ̄︶ ̄)。


脚本与目录分离

有这种想法是因为,写完shell之后需要部署生成环境的集群。在本地集群是在用户目录下开发,但是生成环境下的部署目录又是另外一个用户目录,这就造成了部署时总是需要修改目录,移植性差,不胜其烦。
鉴于这种原因,我想了个“笨办法”,在脚本中用pwd命令获取到当前的路径。

now_path=`pwd`
echo ${now_path}

实际上这个获取的不是脚本所在的目录,假设在根目录下输入绝对路径执行,那么pwd获取的就是根目录了!为了保险起见,通常会在前面加上一个

cd '/path'

就相当设置了一个全局变量,其实还是没有实现脚本于路径的分离。

正确的做法:

CURR_DIR=$(cd `dirname $0`; pwd)
echo ${CURR_DIR}

这样无论是在哪里执行脚本,获取的都是脚本所在路径。因为$0参数是脚本名称。dirname可以去除文件名的非目录部分,得到的就是“.”,也就是current_directory。所以再cd,pwd就可以获取脚本所在的路径了。

脚本的错误日志

刚开始因为考虑到脚本的可阅读行和程序排查问题方便,会在脚本中重定向一些 文字到固定的目录文件中。但是几次都发现错误信息是不会重定向到我所在的文件的。日志中只有我print出来的内容。

1、单纯使用的是后台命令运行的情况

./script.sh &

有错误发生会显示在终端上,普通的INFO信息则会输出到我设置的固定的日志文件中。如果终端关闭了,那错误就无从查其。

2、使用nohup重定向+后台运行的情况

nohup ./script.sh &

这样执行就会把错误日志输出到nohup.out文件中了,可以解决错误日志丢失的问题。但是如果一个脚本经常重复执行,只有一个nohup.out文件是比较难查找问题的(因为我的INFO信息日志都是按脚本名,按日期分文件打印的)。

3、shell的标准输出、入和错误输出

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件(菜鸟教程):

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息

    我想要的错误日志其实就是shell的错误输出流,知道了这个就方便了。在我的实际中,业务都是需要不同脚本的配置才能实现的,因此,在总脚本中执行其他分脚本并把分脚本的错误输出和标准输出都重定向到总脚本的日志中就好了

startAll.sh

#!/bin/sh
CURR_DIR=$(cd `dirname $0`; pwd)
today=$(date +'%Y%m%d')
LOG_FILE=${now_path}/logs/${0}_${today}.txt
mkdir -p ${now_path}/logs
touch ${log_file}
#---
echo 'start first script'>>${LOG_FILE}
./first.sh >>${LOG_FILE} 2>$1
echo 'start second script'>>${LOG_FILE}
./second.sh >>${LOG_FILE} 2>$1
echo 'all script had finished.'>>${LOG_FILE}

这样就能把错误和信息日志输出到日志文件中了。

提供脚本运行说明

一开始我是把脚本的运行说明写成注释放到脚本中的,但是后来由于业务需要,脚本需要加密,所以,为了方便,需要把说明写在脚本中。这里的是参考了INFOQ公众号的一篇文章写好shell脚本的13个技巧(文章链接可能失效)。里面讲的技巧中,有些技巧感觉有些没有太大的必要使用。它提供的–help技巧代码中有点小错误。改进后变成了下面的样子:

if [ ${#@} -eq 1 ] && [ "${@#"--help"}" = "" ]; then
printf -- '====== Help ======\n';
printf -- '|运行说明:\n';
printf -- '|第一个参数输入4G数据源表名(没有经过删减字段版的),第二个参数输入时间(yyyymmdd)\n';
printf -- '|示例: ./flow_first_step.sh t_mult_s1u_http_p 20180606\n'
exit 0;
fi;

当然,把运行说明写成usage函数也是可以的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值