Shell 简介
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
基本上Shell分两大类:
一:图形界面Shell(Graphical User Interface shell 即 GUI shell)
例如:
1、应用最为广泛的Windows Explorer (微软的windows系列操作系统)
2、广为人知的Linux shell,其中linux shell 包括X window manager,以及功能更强大的CDE、GNOME、KDE、 XFCE。
二:命令行式shell(Command Line Interface shell ,即CLI shell)
例如:
1、bash / sh / ksh / csh(Unix/linux 系统)
2、cmd.exe/ 命令提示字符(Windows NT 系统)
一、终端打印
echo是用于终端打印的基本命令。
1.显示普通字符串:
echo "It is a test"
这里的双引号完全可以省略,以下命令与上面实例效果一致:
echo It is a test
echo ‘It is a test’
2.显示转义字符
echo "\"It is a test\""
结果将是:
"It is a test"
3.显示变量
#!/bin/sh
read name
echo "$name It is a test"
输出结果:
OK #标准输入
OK It is a test #输出
4.显示换行
echo -e "OK! \n" # -e 开启转义
echo "It it a test"
输出结果:
OK!
It it a test
5、echo输出的字符串总结
能否引用变量 | 能否引用转移符 | 能否引用文本格式符 | |
---|---|---|---|
单引号 | 否 | 否 | 否 |
双引号 | 能 | 能 | 能 |
无引号 | 能 | 能 | 否 |
6、printf命令
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
执行脚本,输出结果如下所示:
姓名 性别 体重kg
郭靖 男 66.12
%d %s %c %f 格式替代符详解:
d: Decimal 十进制整数 -- 对应位置参数必须是十进制整数,否则报错!
s: String 字符串 -- 对应位置参数必须是字符串或者字符型,否则报错!
c: Char 字符 -- 对应位置参数必须是字符串或者字符型,否则报错!
f: Float 浮点 -- 对应位置参数必须是数字型,否则报错!
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。
二、单引号、双引号、反引号区别
一、单引号(‘’)
str='this is a string'
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)
二、双引号(“”)
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
三、反引号(``)
命令替换是指shell能够将一个命令的标准输出插在一个命令行中任何位置。
shell中有两种方法作命令替换:把shell命令用反引号或者$(...)结构括起来,
其中,$(...)格式受到POSIX标准支持,也利于嵌套。
echo The date and time is `date`
echo The date and time is $(date)
三、变量与环境变量
export命令用来设置环境变量。至此之后,从当前shell脚本执行的任何应用程序都会继承这个变量。我们可以按照自己的需要,在执行的应用程序或者shell脚本中导出特定的变量。在默认情况下,有很多标准环境变量可供shell使用。
1、PATH
PATH就是标准环境变量其中之一。查看变量PATH包含:
echo $PATH
如果需要在PATH中添加一条新路径,可以使用:
export PATH="$PATH:/home/user/bin"
2、LD_LIBRARY_PATH
LD_LIBRARY_PATH也是Linux环境变量名之一,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径。
假设我们要将myapp安装到/opt/myapp,它的二进制文件在bin目录中,库文件在lib目录中。
需要在LD_LIBRARY_PATH中添加一条新路径,可以使用:
export LD_LIBRARY_PATH=/opt/myapp/lib;$LD_LIBRARY_PATH
3、获得字符串长度 可以用下面的方法获得变量值的长度:
var=12345678901234567890
echo ${#var}
4、识别当前所使用的shell 可以用下面的方法获知当前使用的是哪种shell:
echo $SHELL
echo $0
5、检查是否为超级用户
UID是一个重要的环境变量,可以用于检查当前脚本是以超级用户还是以普通用户的身份运行的。
echo $UID(root用户的UID是0)
四、Shell 进行数学运算
在Bash shell环境中,可以利用let、(( ))和[]执行基本的算术操作。而在进行高级操作时, expr和bc这两个工具也会非常有用。
1、以下这些方法只能用于整数运算,而不支持浮点数。举例:
#!/bin/bash
no1=4;
no2=5;
let result=no1+no2 //let命令可以直接执行基本的算术操作
echo $result
result1=$[ no1+no2 ] //操作符[]的使用方法和let命令类似
echo $result1
result2=$((no1 +50 )) //使用(())时,变量名之前需要加上$
echo $result2
result3=`expr 3 + 4`
echo $result3
result4=$(expr $no1 + 5) //expr同样可以用于基本算术操作
echo $result4
2、 bc是一个用于数学运算的高级工具,这个精密计算器包含了大量的选项。我们可以借助它执行浮点数运算并应用一些高级函数:
#!/bin/bash
echo "4 * 0.56" |bc
no=54
result=`echo "$no *1.5" |bc`
echo $result
echo "scale=2;39/8" | bc //设定小数精度
no1=100
echo "obase=2;$no1" |bc //转换2进制
no2=1100100
echo "obase=10;ibase=2;$no2" |bc //转换10进制
echo "sqrt(100)" | bc //计算平方根
echo "10^10" |bc //计算平方
五、重定向及文件描述符
重定向一般通过在命令间插入特定的符号来实现。如下所示:
(1) 用下面的方法可以将输出文本重定向或保存到一个文件中:
$ echo "This is a sample text 1" > temp.txt
这种方法通过截断文件的方式,将输出文本存储到文件temp.txt中,也就是说在把 echo命令的输出写入文件之前,temp.txt中的内容首先会被清空。
(2) 将文本追加到目标文件中,看下面的例子:
$ echo "This is sample text 2" >> temp.txt
(3) 查看文件内容:
$ cat temp.txt
This is sample text 1
This is sample text 2
文件描述符是与文件输入、输出相关联的整数。它们用来跟踪已打开的文件。最常见的文件描述符是stdin、stdout和stderr。
我们甚至可以将某个文件描述符的内容重定向到另一个文 件描述符中。下面给出一些对文件描述符进行操作和重定向的例子。
文件描述符是与某个打开的文件或数据流相关联的整数。文件描述符0、1以及2是系统预留的。
0 —— stdin(标准输入)
1 —— stdout(标准输出)
2 —— stderr(标准错误)
下面的命令会将stderr文本打印到屏幕上,而不是文件中(而且因为并没有stdout 的输出,所以out.txt没有内容):
ls + > out.txt
ls: cannot access +: No such file or directory
下面的命令中,我们将stderr重定向到out.txt:
ls + 2> out.txt #正常运行
你可以将stderr单独重定向到一个文件,将stdout重定向到另一个文件:
cmd 2>stderr.txt 1>stdout.txt
还可以利用下面这个更好的方法将stderr转换成stdout,使得stderr和stdout 都被重定向到同一个文件中:
cmd 2>&1 output.txt
或者这样:
cmd &> output.txt
(4)将脚本内部的文本块进行重定向
有时候,我们需要对文本块(多行文本)进行重定向,就像对标准输入做的那样。考虑一个特殊情况:源文本就位于shell脚本中。一个实用的例子是向log文件中写入头部数据,可以按照下面的方法完成:
#!/bin/bash
cat<<EOF>log.txt
LOG FILE HEADER
This is a test log file
Function: System statistics
EOF
在cat <<EOF>log.txt与下一个EOF行之间的所有文本行都会被当做stdin数据。log.txt文件的内容打印如下:
LOG FILE HEADER
This is a test log file
Function: System statistics
六、数组
数组是shell脚本非常重要的组成部分,它借助索引将多个独立的数据存储为一个集合。普通数组只能使用整数作为数组索引。
Bash也支持关联数组,它可以使用字符串作为数组索引。
在很多情况下,采用字符串式索引更容易理解,这时候关联数组就派上用场了。在这里,我们会看到普通数组和关联数组的用法。
(1)定义数组的方法有很多种。可以在单行中使用一列值来定义一个数组:
array_var=(1 2 3 4 5 6) #这些值将会存储在以0为起始索引的连续位置上
另外,还可以将数组定义成一组“索引-值”:
array_var[0]="test1"
array_var[1]="test2"
array_var[2]=“test3"
(2) 打印出特定索引的数组元素内容:
echo ${array_var[0]}
结果:test1
index=2
echo ${array_var[$index]}
结果:test3
(3) 以清单形式打印出数组中的所有值:
echo ${array_var[*]}
结果:test1 test2 test3
也可以这样使用:
echo ${array_var[@]}
结果:test1 test2 test3
(4) 打印数组长度(即数组中元素的个数):
echo ${#array_var[*]}
结果: 3
七、使用别名
alias 的基本使用方法为:
alias 新的命令='原命令 -选项/参数’
直接输入 alias 命令会列出当前系统中所有已经定义的命令别名。
(1) 基本使用,例如:
alias l=‘ls -lsh’
将重新定义ls命令,现在只需输入l就可以列目录了。
(2) alias命令的作用只是暂时的。一旦关闭当前终端,所有设置过的别名就失效了。为了使别名设置一直保持作用,可以将它放入~/.bashrc文件中。因为每当一个新的shell进程生成时,都会执行 ~/.bashrc中的命令:
echo 'alias l=“ls -lsh”’>> ~/.bashrc
(3) 如果需要删除别名,只用将其对应的语句(如果有的话)从 ~/.bashrc中删除, 或者使用unalias命令。
八、获取终端信息
编写命令行shell脚本时,总是免不了大量处理当前终端的相关信息,比如行数、列数、光标、位置、密码字段等。这则攻略将帮助你学习如何采集和处理终端设置。
获取终端的行数和列数: tput cols 、 tput lines
打印出当前终端名: tput longname
将光标移动到坐标(100,100)处: tput cup 100 100
设置终端背景色: tput setab n (其中:n可以在0到7之间取值)
设置文本前景色: tput setaf n (其中:n可以在0到7之间取值)
设置文本样式为粗体: tput bold
设置下划线的起止: tput smul 、tput rmul
删除从当前光标位置到行尾的所有内容: tput ed
九、获取、设置日期和延时
纪元时被定义为从世界标准时间1970年1月1日0时0分0秒起至当前时刻的总秒数,不包括闰秒。当计算两个日期或两段时间的差值时,纪元时很有用处。你可以得出两个特定时间戳的纪元时间,并计算出两者之间的差值,由此就能知道两个日期之间相隔了多少秒。我们能够以多种格式打印日期,也可以在命令行中设置日期。
(1) 读取日期:
$ date
Tue Mar 13 23:24:16 PDT 2018
(2) 打印纪元时:
$ date +%s
1521008675
(3) 从给定格式的日期串中得出对应的纪元时:--date用于提供日期串作为输入
date --date "Thu Nov 18 08:07:21 IST 2018" +%s
(4)将日期串作为输入能够用来获知给定的日期是星期几。
date --date "Mar 14 2018" +%A
(5)按照你的选择打印出对应格式的日期。
date "+%d %B %Y”
(6)我们需要检查一组命令所花费的时间,可以使用以下代码:
#!/bin/bash
start=$(date +%s)
ls;
pwd;
sleep 3
end=$(date +%s)
diff=$(( end - start))
echo Time taken to execute commands is $diff seconds.
(7)编写以循环方式运行的监视脚本时,设置时间间隔是必不可少的。让我们来看看如何生成延时。
#!/bin/bash
echo -n Count:
tput sc //tput sc存储光标位置
count=0; //变量count初始化为0,随后每循环一次便增加1
while true;
do
if [ $count -lt 4 ]; //-lt 小于
then
let count++;
sleep 1;
tput rc //恢复光标位置的命令
tput ed //清除从当前光标位置到行尾之间的所有内容,使得旧的count值清除并写入新值
echo -n $count;
else exit 0;
fi
done
以上,未完待续~~