linux shell学习笔记(一)

【shell简介】

所有的命令都是在shell终端输入并且执行。打开终端就会出现一个提示符。其形式通常有两种:

[root@localhost ~]#

或者

[hcc@localhost ~]$

其实$表示普通用户,#表示超级用户(root user)。超级用户是linux系统中权限最高的用户。


shell脚本通常是以"#!"(shebang)其实的文本文件,如下所示:

#!/bin/bash

linux环境下的任何脚本语言,都是以这样一个被称为shebang的特殊行为起始的。/bin/bash是Bash的路径。关于shebang的解释:#发音为sharp,!发音为bang,因此shebang合起来就表示了#!


linux执行脚本有两种方式:一种是将脚本作为sh的命令行参数,另一种是将脚本作为具有执行权限的可执行文件。

#将脚本作为sh的命令行参数(注意:这种方式脚本的shebang标示符无效

sh script.sh

#将脚本作为具有执行权限的可执行文件

chmod a+x script.sh  #如果该脚本没有执行权限,需要赋予执行权限
./script.sh   #直接运行该脚本,假设脚本在当前目录

如果是以可执行文件的方式来执行脚本的话,shell程序首先会读取脚本的首行,即shebang标示符。如果首行是 #!/bin/bash,那么内部会以如下的命令行来执行该脚本

/bin/bash script.sh


在bash中,每个命令都是通过分号或者换行符来进行分割的

cmd1;cmd2

相当于两条命令

cmd1
cmd2

【终端打印】

1、使用echo完成终端打印

默认情况下,echo会在每次调用后添加一个换行符

[hcc@localhost ~]$ echo "Hello World"
Hello World
[hcc@localhost ~]$

如果不想换行,可以使用-n阻止echo换行

[hcc@localhost ~]$ echo -n "Hello World"
Hello World[hcc@localhost ~]$

echo命令后面的字符串可以有三种形式,分别是:带双引号的字符串、带单引号的字符串、不带符号的字符串。三者之间的区别如下:

(1)带双引号的字符串,不能直接输出!号,如下例

[hcc@localhost ~]$ echo "Hello World!"
-bash: !": event not found
[hcc@localhost ~]$

在双引号的字符串中一定要输出!号,有两种办法:

#使用转义字符(缺点:转义字符也打印出来了,不推荐

[hcc@localhost ~]$ echo "Hello World\!"
Hello World\!
[hcc@localhost ~]$

#首先执行set +H命令,在使用echo打印(推荐

[hcc@localhost ~]$ set +H
[hcc@localhost ~]$ echo "Hello World!"
Hello World!
[hcc@localhost ~]$

(2)带单引号的字符串,不能识别变量,内容只作为一个字符串输出

#使用单引号,原样的将字符串内容进行输出

[hcc@localhost ~]$ echo ‘$PATH‘
$PATH
[hcc@localhost ~]$

(3)不带任何标识的字符串

不带任何标识的字符串,在遇到;号时,命令会被拆分,如下例

[hcc@localhost ~]$ echo $PATH;hello
/usr/lib/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hcc/bin
-bash: hello: command not found
[hcc@localhost ~]$

通过例子可以看到,shell将;号后面的hello当成了第二条命令。

2、echo的转义输出

#使用-e能够完成echo的转义输出

\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;

例子:

[root@localhost ~]# echo -e "1\t2\t3\t"
1       2       3
[root@localhost ~]#

3、echo打印彩色输出

在终端打印彩色非常的好玩,我们可以使用转义序列来实现。

每种颜色对应的颜色码:

重置=0,
黑色=30,
红色=31,
绿色=32,
***=33,
蓝色=34,
洋红=35,
青色=36,
白色=37。
黑色背景=40,
红色背景=41,
绿色背景=42,
***背景=43,
蓝色背景=44,
洋红背景=45,
青色背景=46,
白色背景=47

使用 \e[颜色码m 即可以实现颜色的转义

例子

技术分享

4、printf进行格式化输出

printf使用的参数和C语言中printf使用的参数一模一样。

默认情况,printf不像echo一样在末尾自动添加换行符,因此需要换行的话,需要加上\n

例子:

[hcc@localhost ~]$ vim printf.sh
#!/bin/bash
#文件名 printf.sh
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 hucc 96.50
printf "%-5s %-10s %-4.2f\n" 2 zhsl 97.50
printf "%-5s %-10s %-4.2f\n" 3 luzh 98.50

执行该脚本:

[hcc@localhost ~]$ chmod a+x printf.sh                              
[hcc@localhost ~]$ ./printf.sh 
No    Name       Mark
1     hucc       96.50
2     zhsl       97.50
3     luzh       98.50
[hcc@localhost ~]$

解释:%-5s指明了一个占5个字符的字符串,-表示左对齐,如果不指定-那么默认是右对齐方式的。

5、打印总结

打印总的来说很简单,但是非常常用,属于必须掌握的知识点。

【玩转变量以及环境变量】

在bash中,每一个变量的值的类型都是字符串,无论你给的变量有没有用单引号或者双引号,值都是以字符串的形式进行存储的。

有一些特殊的变量会被shell环境和操作系统用来存储一些特别的值,这类变量就被称为环境变量。

1、查看某个进程的环境变量

#显示瞬间行程 (process) 的动态

[root@localhost ~]# ps
  PID TTY          TIME CMD
28414 pts/0    00:00:00 bash
28433 pts/0    00:00:00 ps
[root@localhost ~]#

#查看某个进程的环境变量

[root@localhost ~]# cat /proc/28414/environ 
USER=rootLOGNAME=rootHOME=/rootPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binMAIL=/var/mail/rootSHELL=/bin/bashSSH_CLIENT=192.168.99.100 52296 22SSH_CONNECTION=192.168.99.100 52296 192.168.99.11 22SSH_TTY=/dev/pts/0TERM=linuxSELINUX_ROLE_REQUESTED=SELINUX_LEVEL_REQUESTED=SELINUX_USE_CURRENT_RANGE=[root@localhost ~]#

环境变量之间默认是已\0进行分隔的,可读行不是特别好,我们可以用tr命令将\0替换成\n

[root@localhost ~]# cat /proc/28414/environ |tr "\0" "\n"
USER=root
LOGNAME=root
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAIL=/var/mail/root
SHELL=/bin/bash
SSH_CLIENT=192.168.99.100 52296 22
SSH_CONNECTION=192.168.99.100 52296 192.168.99.11 22
SSH_TTY=/dev/pts/0
TERM=linux
SELINUX_ROLE_REQUESTED=
SELINUX_LEVEL_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
[root@localhost ~]#

2、实战演练

一个变量可以通过以下方式进行复制,注意=号左右都没有空格

name=value   # =号左右都没有空格

例子:

[root@localhost ~]# name=hucc
[root@localhost ~]# echo $name
hucc
[root@localhost ~]#

环境变量是未在当前进程中定义,而从父进程继承而来的变量。

例如在安装jdk的时候我们需要指定JAVA_HOME和PATH两个环境变量

export JAVA_HOME=/usr/local/src/jdk1.7.0_55
export PATH=$PATH:$JAVA_HOME/bin

export命令用于设置环境变量

3、补充内容

(1)获得字符串长度

例子:

[root@localhost ~]# num=0123456789
[root@localhost ~]# echo ${#num}
10
[root@localhost ~]#

(2)识别当前的shell版本

[root@localhost ~]# echo $SHELL
/bin/bash
[root@localhost ~]# echo $0
-bash
[root@localhost ~]#

(3)检查是否为超级用户

[root@localhost ~]# vim isRoot.sh 
#!/bin/bash
#文件名:isRoot.sh
if [ $UID -ne 0 ];then
echo "不是超级管理员,请以超级管理员的身份进行登录"
else
echo "欢迎你,超级管理员"
fi

执行该脚本:

[root@localhost ~]# chmod a+x isRoot.sh 
[root@localhost ~]# ./isRoot.sh 
欢迎你,超级管理员
[root@localhost ~]#

(4)修改Bash提示字符串

#默认的shell提示脚本是在/etc/bashrc文件中定义的

[root@localhost ~]# cat /etc/bashrc | grep PS1
if [ "$PS1" ]; then
  [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
  # if [ "$PS1" ]; then
  #   PS1="[\u@\h:\l \W]\\$ "
            if [ "$PS1" ]; then
[root@localhost ~]#

修改提示字符串(只是用变量覆盖了,并没有修改环境变量,如果想要修改环境,可以到/etc/profile中进行修改

技术分享


【通过shell进行数学运算】

1、使用let进行数学运算(只能计算整数,推荐使用

例子:

[root@localhost ~]# num1=4
[root@localhost ~]# num2=5
[root@localhost ~]# result=num1+num2   #没有使用let,直接识别是字符串
[root@localhost ~]# echo $result 
num1+num2
[root@localhost ~]# let result=num1+num2   #let可以执行算数操作,并且不用加上$
[root@localhost ~]# echo $result 
9
[root@localhost ~]# let num1++  #let可以进行自增操作
[root@localhost ~]# echo $num1
5
[root@localhost ~]# let num2--  #let可以进行自减操作
[root@localhost ~]# echo $num2
4
[root@localhost ~]# let num1+=num2   #let的简写算术操作
[root@localhost ~]# echo $num1
9
[root@localhost ~]#

通过例子可以看到,let命令可以直接执行基本的算数操作,并且使用let时,变量名之间不再需要加上$

2、使用[]和(())进行算术操作(只能计算整数)

操作符[]和(())跟使用let命令类似,但是需要加上$标示符,例如

[root@localhost ~]# no1=4
[root@localhost ~]# no2=5
[root@localhost ~]# result=$[no1+no2]   #使用[]操作符
[root@localhost ~]# echo $result 
9
[root@localhost ~]# result=$((no1-no2)) #使用(())操作符
[root@localhost ~]# echo $result 
-1
[root@localhost ~]#

3、使用expr进行算术操作(只能计算整数)

expr使用起来也差不多,也需要加上$标示符,例如

[root@localhost ~]# no1=4
[root@localhost ~]# result=$(expr $no1 + 4)
[root@localhost ~]# echo $result 
8
[root@localhost ~]#

4、使用bc命令进行复杂的算术运算,比如浮点数的运算以及使用高级函数

(1)设定小数的精度

例子:

[root@localhost ~]# echo "8/3"|bc          #如果不设定精度,默认计算是整数
2
[root@localhost ~]# echo "scale=2;8/3"|bc  #可以在具体操作前用scale设定精度,用;号隔开
2.66
[root@localhost ~]#

(2)进制转换

例子:

[root@localhost ~]# no=90
[root@localhost ~]# echo "obase=2;$no"|bc 
1011010
[root@localhost ~]# echo "obase=16;$no"|bc
5A
[root@localhost ~]#

(3)计算平方根

例子:

[root@localhost ~]# echo "scale=2;sqrt(30)"|bc
5.47
[root@localhost ~]#


【玩转文件描述符和重定向】

1、预备知识

文件描述符

0---stdin
1---stdout
2---stderr

重定向

> 将输出重定向到文件,会把文件的内容清空。
>> 将输出重定向到文件,追加到末尾,不会把文件的内容清空。

2、实战演练

例子:

[hcc@localhost ~]$ echo "Tom" > out.txt     #将输出重定向到文件
[hcc@localhost ~]$ cat out.txt 
Tom
[hcc@localhost ~]$ echo "Jerry" > out.txt   #会将文件之前的内容清空
[hcc@localhost ~]$ cat out.txt
Jerry
[hcc@localhost ~]$ echo "Jim" >> out.txt    #不会将文件之前的内容清空
[hcc@localhost ~]$ cat out.txt 
Jerry
Jim
[hcc@localhost ~]$

重定向操作符默认使用标准输出。也就是说 >相当于1>   >>相当于1>>


对于错误信息的处理

[hcc@localhost ~]$ ls +
ls: 无法访问+: 没有那个文件或目录
[hcc@localhost ~]$ echo $?            #当一个命令执行错误时,会返回一个非0的状态,这个状态可以从$?变量中获取
2
[hcc@localhost ~]$

下面的例子不会将错误信息打印到文本中,而是会打印到命令窗口:

[hcc@localhost ~]$ ls + > out.txt
ls: 无法访问+: 没有那个文件或目录        #在命令窗口打印了
[hcc@localhost ~]$ cat out.txt
[hcc@localhost ~]$                       #在文件中没有内容,说明没有重定向到文件中

如何将错误信息重定向到文件中:

[hcc@localhost ~]$ ls + 2> out.txt       #在命令窗口没有打印出错误信息
[hcc@localhost ~]$ cat out.txt           #在文件中有错误信息,说明将错误信息重定向到文件中了
ls: 无法访问+: 没有那个文件或目录
[hcc@localhost ~]$

将错误信息和成功信息分别重定向到分别的文件中

[hcc@localhost ~]$ ls + 1>>out.txt 2>>err.txt    #将成功信息重定向out.txt 将错误信息重定向到err.txt
[hcc@localhost ~]$ ls 1>>out.txt 2>>err.txt      #将成功信息重定向out.txt 将错误信息重定向到err.txt
[hcc@localhost ~]$ cat out.txt 
err.txt
out.txt
printf.sh
[hcc@localhost ~]$ cat err.txt 
ls: 无法访问+: 没有那个文件或目录
[hcc@localhost ~]$

总结:其实道理很简单,无论是成功信息还是失败信息,如果没有重定向则默认在命令窗口输出,1>或者>只能重定向成功的信息到文件,2>只能重定向错误的信息到文件。


【数组和关联数组】

1、预备知识

数组是shell脚本中非常重要的组成部分,它借助索引将多个独立的数据存储为一个集合。

Bash支持普通数组和关联数组。普通数组只能使用整数作为数组的索引(个人感觉相当于java中的数组),关联数组可以使用字符串作为数组的索引(感觉相当于java中的map,确切的说应该是Properties类)。

2、实战演练

(1)普通数组

普通数组的常用操作:

[hcc@localhost ~]$ a1=("apple" "banana" "orange" "pear")  #直接定义普通数组
[hcc@localhost ~]$ a2[0]="Tom"      #通过索引-值的方式定义数组
[hcc@localhost ~]$ a2[1]="Jerry"    #通过索引-值的方式定义数组
[hcc@localhost ~]$ a2[2]="Kitty"    #通过索引-值的方式定义数组
[hcc@localhost ~]$ a2[3]="Jack"     #通过索引-值的方式定义数组
[hcc@localhost ~]$ echo ${a1[0]}    #通过索引获取数组的值
apple
[hcc@localhost ~]$ echo ${a2[*]}    #打印整个数组
Tom Jerry Kitty Jack
[hcc@localhost ~]$ echo ${a1[@]}    #打印整个数组
apple banana orange pear
[hcc@localhost ~]$ echo ${#a1[*]}   #打印数组的长度
4
[hcc@localhost ~]$

(2)关联数组

关联数组的常用操作:

[hcc@localhost ~]$ declare -A array    #关联数组需要声明
[hcc@localhost ~]$ array=([name]="hucc" [age]="23" [address]="五道口") #直接定义    
[hcc@localhost ~]$ array[salary]="8000"   #通过索引-值的方式添加数组的内容
[hcc@localhost ~]$ echo ${array[name]}    #通过索引获取数组的值
hucc
[hcc@localhost ~]$ echo ${!array[*]}      #打印数组所有的索引,同样适用于普通数组
name age address salary
[hcc@localhost ~]$ echo ${array[*]}       #打印数组所有的值
hucc 23 五道口 8000
[hcc@localhost ~]$














本文出自 “陌途” 博客,请务必保留此出处http://flycc258.blog.51cto.com/8624126/1615275

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。