文档章节

Shell基础一

秋风醉了
 秋风醉了
发布于 2017/03/29 19:09
字数 2169
阅读 40
收藏 3

Shell基础一

将命令输出赋值给变量

从命令输出中提取信息,并将其赋值给变量。有两种方法可以将命令输出赋值给变量:

  1. 反引号字符(`)
  2. $()格式
#!/bin/bash
var1=`date`
echo $var1

var2=`date +%y%m%d`
echo $var2

var3=$(date +%y%m%d)
echo $var3

 

重定向输入输出和管道

输出重定向

command > outputfile

命令输出会被保存到指定的文件中,

➜  ~ who > logs/who.txt
➜  ~ cat logs/who.txt
xinxingegeya console  Mar 27 21:54
xinxingegeya ttys000  Mar 27 21:54
xinxingegeya ttys001  Mar 27 21:54
xinxingegeya ttys002  Mar 27 22:16
xinxingegeya ttys004  Mar 27 22:33
xinxingegeya ttys005  Mar 27 22:43
➜  ~ date >> logs/who.txt
➜  ~ cat logs/who.txt
xinxingegeya console  Mar 27 21:54
xinxingegeya ttys000  Mar 27 21:54
xinxingegeya ttys001  Mar 27 21:54
xinxingegeya ttys002  Mar 27 22:16
xinxingegeya ttys004  Mar 27 22:33
xinxingegeya ttys005  Mar 27 22:43
2017年 3月27日 星期一 22时48分43秒 CST
➜  ~

注意 使用>> 表示追加输出到已有的文件中。

输入重定向

command < inputfile

输入重定向指的是将文件的内容重定向到命令。

➜  ~ wc < logs/who.txt
       7      35     264

比如统计文件who.txt的行数,字数,还有字节数。

内联输入重定向

➜  ~ wc << marker
heredoc> asdfsadfasfdasdf
heredoc> marker
       1       1      17
➜  ~

marker作为一个标记,当输入marker标记时,表示输入数据完成,执行wc命令。

管道

使用重定向来实现将一个命令的输出作为另一个命令的输入时,可以这样做,

➜  ~ who > logs/test.txt
➜  ~ wc < logs/test.txt
       6      30     216
➜  ~

但有一种更好的方式来完成

➜  ~ who | wc
       6      30     216
➜  ~

这就是管道的作用,管道将一个命令的输出重定向到另一个命令中:

command1 | comand2

 

在脚本中重定向输出

Linux有三个特殊的文件描述符会处理脚本的输入和输出。

STDIN:代表shell的标准输入。对终端界面来说,标准输入是键盘。

STDOUT:代表shell的标准输出,在终端界面上,标准输出就是终端显示器。shell的所有输出(包括shell中运行的程序和脚本)会被定向到标准输出中。

STDERR:shell通过特殊的STDERR文件描述符来处理错误消息。shell或shell中运行的程序和脚本出错时生成的错误消息都会发送到这个位置。默认情况下,STDERR和STDOUT文件描述符指向同样的地方。

如何重定向错误

➜  ~ ls -al badfile > logs/test01
ls: badfile: No such file or directory
➜  ~ cat logs/test01
➜  ~ ls -al badfile 2> logs/test01
➜  ~ cat logs/test01
ls: badfile: No such file or directory
➜  ~

使用 2> 将命令的错误消息重定向到了文件test01。但 2> 只重定向错误消息,而非正常的数据输出。如下所示,

➜  ~ ls -al IDE badfile 2> logs/test01
IDE:
total 32
drwxr-xr-x  22 xinxingegeya  staff    748  3 17 10:42 .
drwxr-xr-x+ 86 xinxingegeya  staff   2924  3 28 19:13 ..
drwxr-xr-x   4 xinxingegeya  staff    136  3 18 00:17 rocketmq
drwxr-xr-x@  6 xinxingegeya  staff    204 12  5 19:15 scala-2.12.1
drwxr-xr-x   4 xinxingegeya  staff    136  4 14  2016 supervisor
drwxr-xr-x   7 xinxingegeya  staff    238  3  2  2016 zookeeper
➜  ~ cat logs/test01
ls: badfile: No such file or directory

如何重定向错误消息和正常的数据输出,使用 &> 符号,如下所示,

➜  ~ ls -al IDE badfile &> logs/test01
➜  ~ cat logs/test01
ls: badfile: No such file or directory
IDE:
total 32
drwxr-xr-x  22 xinxingegeya  staff    748  3 17 10:42 .
drwxr-xr-x+ 86 xinxingegeya  staff   2924  3 28 19:17 ..
drwxr-xr-x   4 xinxingegeya  staff    136  6 23  2016 nginx
drwxr-xr-x  14 xinxingegeya  staff    476  6 29  2016 redis
drwxr-xr-x@ 22 xinxingegeya  staff    748  6 29  2016 redis-3.0.5
drwxr-xr-x   4 xinxingegeya  staff    136  3 18 00:17 rocketmq
drwxr-xr-x@  6 xinxingegeya  staff    204 12  5 19:15 scala-2.12.1
drwxr-xr-x   4 xinxingegeya  staff    136  4 14  2016 supervisor
drwxr-xr-x   7 xinxingegeya  staff    238  3  2  2016 zookeeper
➜  ~

在脚本中重定向输出

#!/bin/bash

#重定向到 STDERR
echo "this is an error" >&2
#正常输出到 STDOUT
echo "this is an normal output"

在这个脚本中,将文本消息重定向到STDERR文件描述符,但必须在文件描述符的数字之前加一个&。

运行这个脚本文件,echo输出的信息都会打印到控制台,但可以把脚本重定向到STDERR的输出信息重定向到文件中,而正常的文件输出则还会打印到控制台

➜  resources git:(master) ✗ ./test01.sh 2> hello 
this is an normal output

如果脚本中有大量的数据需要重定向,那重定向每个echo语句就会很繁琐,那么就可以使用exec命令告诉shell脚本执行期间重定向某个特定文件描述符

#!/bin/bash
#重定向 STDOUT 到文件 testout
exec 1>testout
#重定向 STDERR 到文件 testout_err
exec 2>testout_err

#重定向到 STDERR
echo "this is an error" >&2
#正常输出到 STDOUT
echo "this is an normal output"

执行结果如下,

➜  resources git:(master) ✗ ./test01.sh 
➜  resources git:(master) ✗ ll 
total 24
-rwxr--r--  1 xinxingegeya  staff   152B Mar 29 18:54 test01.sh
-rw-r--r--  1 xinxingegeya  staff    25B Mar 29 18:54 testout
-rw-r--r--  1 xinxingegeya  staff    17B Mar 29 18:54 testout_err
➜  resources git:(master) ✗ cat testout
this is an normal output
➜  resources git:(master) ✗ cat test_err
cat: test_err: No such file or directory
➜  resources git:(master) ✗ 

 

重定向输出的更多用法

从上文我们知道 &> 的作用是合并STDOUT和STDERR的输出,还有一种写法和 &> 作用一样,

➜  ~ ls -al IDE badfile > my.out0
ls: badfile: No such file or directory
➜  ~
➜  ~ ls -al IDE badfile &> my.out2
➜  ~
➜  ~ ls -al IDE badfile >& my.out3
➜  ~
➜  ~ ls -al IDE badfile > my.out4 2>&1
➜  ~

(1)ls -al IDE badfile > my.out0

只重定向了正常的数据输出

(2)ls -al IDE badfile &> my.out2

使用 &> 符号重定向错误消息和正常的数据输出

(3)ls -al IDE badfile >& my.out3

>& 符号和 &> 是等价的,作用一样

(4)ls -al IDE badfile > my.out4 2>&1

> my.out4 2>&1 和 (2)(3)的效果是一样的;也就是说先将ls -al IDE badfile 命令的STDOUT输出重定向到文件 my.out4 ,然后再将STDERR重定向到STDOUT,由于前一个重定向把STDOUT重定向的文件,所以STDERR的输出也最终被重定向到了文件。

注意:2>&1代表将stderr重定向到文件描述符为1的文件(即/dev/stdout)中

➜  ~ ls -al IDE badfile 2>&1 > my.out5
ls: badfile: No such file or directory
➜  ~

这种写法 ls -al IDE badfile 2>&1 > my.out5 和 ls -al IDE badfile > my.out4 2>&1 这种写法只是顺序的不同,但作用是不一样的,为什么呢?先将要输出到stderr的内容重定向到stdout,此时会产生一个stdout的拷贝,作为程序的stderr,而程序原本要输出到stdout的内容,依然是对接在stdout原身上的,因此第二步重定向stdout,对stdout的拷贝不产生任何影响。

http://www.gnu.org/software/bash/manual/bashref.html#Redirections

Note that the order of redirections is significant. For example, the command

ls > dirlist 2>&1  directs both standard output (file descriptor 1) and

standard error (file descriptor 2) to the file dirlist, while the

command ls 2>&1 > dirlist  directs only the standard output to file dirlist,

because the standard error was made a copy of the standard output

before the standard output was redirected to dirlist.

 

执行数学运算

在shell脚本中使用expr命令,

#!/bin/bash
var1=1
var2=2
var3=3
# 操作数和操作符之间必须有空格
var4=$(expr $var1 + $var2 + $var3)
echo $var4

使用方括号来执行数学运算。bash shell为了保持和Bourne shell 的兼容而包含了expr命令。在bash中,再将一个数学元算结果赋给某个变量时,可以用美元符号和方括号 $[ operation ]  将数学表达式包围起来

#!/bin/bash
var1=12
var2=23
var3=$[$var1 + $var2]
echo $var3

在脚本中执行浮点运算

有几种解决方案能够克服bash中数学运算的整数限制。最常见的方案是用内建的bash计算器,叫做bc。

➜  ~ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
12 / 5
2

scale=2

12 / 5
2.40

首先要设置 scale 的值,默认是0;

在脚本中使用bc,基本命令格式如下,

variable=$(echo "options; expression" | bc)

第一部分options允许你设置变量。如果不止一个变量,可以用分号将其分开。expression参数定义了通过bc执行的数学表达式。

#!/bin/bash
var1=$(echo "scale=2; 12 / 5" | bc)
echo $var1

bc 使用内联输入重定向

#!/bin/bash
var1=12.1
var2=12.2
var3=12.3
var4=12.4

var5=$(bc << EOF
scale = 2
a1 = $var1 + $var2
b1 = $var3 * $var4
a1 + b1
EOF
)

echo $var5

 

脚本的退出

shell 中运行的每个命令都使用退出状态码(exit status)告诉shell 它已经运行完毕。退出状态码是一个0 ~ 255 的整数值,在命令结束运行时由命令传给shell。可以使用 $? 来获取上个已执行命令的退出状态码。

➜  ~ vim /etc/hosts
➜  ~ echo $?
0
➜  ~ ./hello
zsh: no such file or directory: ./hello
➜  ~ echo $?
127

0 表示 正常退出,127 表示没有找到命令。

默认情况下,shell脚本会以脚本中最后一个命令的退出状态码退出,同时可以使用exit 命令指定一个退出状态码

#!/bin/bash
today=$(date +%y%m%d)
echo $today
exit 0

========END========

© 著作权归作者所有

秋风醉了
粉丝 252
博文 532
码字总数 405694
作品 0
朝阳
程序员
私信 提问
《Linux基础知识及命令》系列分享专栏

《Linux基础知识及命令》系列分享专栏 本专题详细为大家讲解了Linux入门基础知识,思路清晰,简单易懂。本专题非常适合刚刚学习Linux的小白来学习,通过学习该专题会让你由入门达到中级的水平...

kaixin_code
2018/12/01
68
0
shell基础八:文本过滤工具(grep)

shell基础1:文件安全与权限 http://bbs.chinaunix.net/forum/viewtopic.php?t=434579&highlight=wingger 附:Linux的用户和用户组管理 http://bbs.chinaunix.net/forum/viewtopic.php?t=438......

zt371
2009/05/06
769
0
subprocess包主要功能是执行外部的命令和程序 (子进程)

这里的内容以Linux进程基础和Linux文本流为基础。subprocess包主要功能是执行外部的命令和程序。比如说,我需要使用wget下载文件。我在Python中调用wget程序。从这个意义上来说,subprocess的...

飞儿飞
2016/12/09
53
0
详细介绍Linux shell脚本基础学习(一)

Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头、注释、变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提。 1. L...

魏邪乎
2014/02/13
32
0
Python标准库06 子进程 (subprocess包)

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 谢谢Tolbkni Kao帮我纠正错误 这里的内容以Linux进程基础和Linux文本流为基础。subprocess包主要功能是...

张旭0512
2014/05/27
135
0

没有更多内容

加载失败,请刷新页面

加载更多

友元函数强制转换

友元函数强制转换 p522

天王盖地虎626
昨天
5
0
js中实现页面跳转(返回前一页、后一页)

本文转载于:专业的前端网站➸js中实现页面跳转(返回前一页、后一页) 一:JS 重载页面,本地刷新,返回上一页 复制代码代码如下: <a href="javascript:history.go(-1)">返回上一页</a> <a h...

前端老手
昨天
4
0
JAVA 利用时间戳来判断TOKEN是否过期

import java.time.Instant;import java.time.LocalDateTime;import java.time.ZoneId;import java.time.ZoneOffset;import java.time.format.DateTimeFormatter;/** * @descri......

huangkejie
昨天
4
0
分页查询

一、配置 /*** @author beth* @data 2019-10-14 20:01*/@Configurationpublic class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor(){ ......

一个yuanbeth
昨天
6
0
在LINQPad中使用Ignite.NET

LINQPad是进行.NET开发的一款优秀工具,非常有利于Ignite.NET API的快速入门。 入门 下载LINQPad:linqpad.net/Download.aspx,注意要选择64位操作系统的AnyCPU版本; 安装Ignite.NET的NuGet...

李玉珏
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部