shell脚本-随笔(引号;分号;重定向)

本文介绍了Shell脚本中定义常量时引号的使用,包括单引号、双引号和不使用引号的差异。接着讨论了分号在代码块标识中的作用,以及何时需要使用分号。最后,详细阐述了重定向输出和日志,包括标准输入、输出和错误的重定向,并举例说明了各种重定向用法及其效果。

一,关于定义常量时,引号的使用

1. 单引号

使用单引号的情况下,不管里面的是否有变量或者其他的表达是都是原样子输出

2. 双引号

如果其定义变量的时候使用双引号的话,则里面的变量或者函数会通过解析,解析完成后再输出内容,而不是把双引号中的变量名以及命令原样子输出。

3. 不使用引号

用于一些简单字符数字的定义与双引号类似

使用规则解释
单引号所见即所得,即输出时会将单引号内的所有內容都原样输出,或者描述为单引号里面看到的是什么就会输出什么,这称为强引用
双引号 (默认)输出双引号内的所有内容;如果内容中有命令(要反引下)、变量、特殊转义符等,会先把变量、命令、转义字符解析出结果,然后再输出最终内容,推荐使用,这称为弱引用
无引号赋值时,如果变量内容中有空格,则会造成赋值不完整。而在输出内容时,会将含有空格的字符串视为一个整体来输出;如果内容中有命令(要反引下)、变量等,则会先把变量、命令解析出结果,然后输出最终内容;如果字符串中带有空格等特殊字符,则有可能无法完整地输出,因此需要双引号替代无引号的情况,特别是对变量赋值时改加双引号。一般连续的字符串、数字、路径等可以不加任何引号进行赋值和输输出,不过最好是用用
反引号一般用于引用命令,执行的时候命令会被执行,相当于S0,赋值和输出都要用“将命令引起来

 

二,关于分号

在Linux bash shell中,语句中的分号一般用作代码块标识

1、单行语句一般要用到分号来区分代码块

注意:语句结尾不要分号。

2、该代码若写作多行,用换行符来区分代码块,则无需用到分号

 

三,关于重定向输出和日志

关于重定向,最近踩了几个坑,mark一下。

1、首先认识,0 stdin,1 stdout,2 stderr,> 新建/覆盖文件, >> 追加文件

常见的计划任务,例如:

*/2 * * * * sh /opt/xxxx/test_S1.sh >/dev/log.txt 2>&1
*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1

对于&1, 更准确的说应该是文件描述符 1,而1标识标准输出,stdout。
对于2 ,表示标准错误,stderr。
2>&1 的意思就是将标准错误重定向到标准输出。这里标准输出已经重定向到了 /dev/log.txt。那么标准错误也会输出到/dev/log.txt

偶尔也可以把 & 在命令的最后加上,表示让程序后台执行。

有时候希望将错误的信息重新定向到输出,就是将2的结果重定向至1中就有了”2>1”这样的思路,如果按照上面的写法,系统会默认将错误的信息(STDERR)2重定向到一个名字为1的文件中,而非所想的(STDOUT)中。因此需要加&进行区分。就有了 2>&1 这样的用法

小结:

ls 2>1测试,不会报没有2文件的错误,但会输出一个空的文件1;(1代表一个文件,这里如果用>>1,则为追加1,不会覆盖1)

ls xxx 2>1测试,没有xxx这个文件的错误输出到了1中;(1代表一个文件)
ls xxx 2>&1测试,不会生成1这个文件了,不过错误跑到标准输出了;(1代表stdout)
ls xxx >out.txt 2>&1, 实际上可换成 ls xxx 1>out.txt 2>&1;重定向符号>默认是1,错误和输出都传到out.txt了。(类似于IO里,先打开输出流1,再给输出1传入数据2

 

2、ls xxx 2>&1 | tee -a out.txt

这个用法把 2>&1 放在前面,关键在于用了管道符,把1作为下一个输入传入。

| 管道

管道的作用是提供一个通道,将上一个程序的标准输出重定向到下一个程序作为下一个程序的标准输入。

通常使用管道的好处是一方面形式上简单,另一方面其执行效率要远高于使用临时文件。

这里使用管道的目的是将make程序的输出重定向到下一个程序,其最终目的是用来将输出log存入文件中。

 

tee是用来干什么的?

tee从标准输入中读取,并将读入的内容写到标准输出以及文件中。
所以这里tee命令的作用是将数据读入并写到标准输出以及out.txt中。

遇到的问题:

#!/bin/bash

sh abc.sh 2>&1 | tee -a log.txt


if [ $? -ne 0 ]

then

    echo "failed"
else
    echo "successed"

fi

最初设想是收集执行 abc.sh 时的错误日志屏幕输出记录到 log.txt 中。但因为管道符 if 语句判断的 $? 始终为 0 。因为返回值是 tee 这句的执行返回。所以为了保证 $? 准确性,只好牺牲屏幕输出,改为

#!/bin/bash

sh abc.sh >> log.txt 2>&1


if [ $? -ne 0 ]

then

    echo "failed"
else
    echo "successed"

fi

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值