设为首页 收藏本站
查看: 1585|回复: 0

linux shell学习笔记(一)

[复制链接]
YunVN网友  发表于 2018-8-18 11:55:19 |阅读模式
  【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 即可以实现颜色的转义
  例子
DSC0000.jpg

  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中进行修改)
DSC0001.jpg

  【通过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 ~]$



  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-553415-1-1.html 上篇帖子: bash shell中的环境变量 下篇帖子: shell编程学习之awk
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表