本章Blog相关Linux知识点


编程语言,是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令。

    强类型语言(静态类型语言)是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#

    弱类型语言(动态类型语言)是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如PHP/Python/Perl/SQL/Shell等。

程序执行逻辑,bash脚本,面向对象的过程中,

    顺序执行:默认法则,逐条执行各语句;

    选择执行:分支,条件判断,符合条件的分支予以执行

    循环执行:将统一段代码反复执行有限次,故循环必须有退出条件,否则将陷入死循环。

程序代码——控制语句和表达式组成

    bash循环控制语句 for ,until ,while

    bash判断控制语句 if , case

列表生成方法:for ,通过使用一个变量去遍历给定列表中的元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环。

    直接给出列表   如:for I in /etc/passwd /etc/issue /etc/redhat-release; do

    使用文件名通配的机制生成列表   for I in /var/log/* ;do

    可以使用{start..end}、`seq [start] [step] [end]` 生成数字序列  例: `seq 1 $lineCount`   或    `seq 1 2 100`

    使用命令生成  ,for userName in `cut -d: -f1 /etc/passwd` ;do

注:若命令用作条件,需引用命令状态结果(即执行成功与否),而非命令的输出结果,因此无需做命令引用 ;反之,若需命令结果 ,需要做命令引用


Linux  bash 特性一:命令展开


 ~ :指定用户的家目录

{Value1,Value2} :展开为多个条目

例:# mkdir -p  /x/{a/{m,n},b}    在/x 目录下创建目录/x/a , /x/b , /x/a/m , /x/a/n 目录

例:# mkdir -pv /tmp/mylinux/{usr/local/{bin,sbin},etc/{sysconfig,init.d},bin,sbin}         通过mkdir命令创建/tmp/mylinux/usr/local/bin , /tmp/mylinux/usr/local/sbin , /tmp/mylinux/etc/sysconfig , /tmp/mylinux/etc/init.d , /tmp/mylinux/bin ,/tmp/mylinux/sbin目录


Linux bash 特性二 :符号引用


符号的作用:

    `` (反引号,tab 上面的键):命令引用,引用命令的执行结果 。命令引用的另外一种符号 $( 命令)

    '' (单引号):强引用 ,变量替换不会进行 。被单引号用括住的内容,将被视为单一字串。即使引号内的存在代表变量的$符号,仅作$符号使用。

    ""(双引号):弱引用 ,能够执行变量替换。它防止通配符扩展,但允许变量扩展 。

例:# mkdir  `date +%Y-%m-%d-%H-%M-%S`     命令引用,创建以当前日期为文件名的 文件

例:# wishdir=itwish   echo '$wishdir'     得出结果$wishdir   单引号,结果为字符串

例:# wishdir=itwish   echo "$wishdir"     得出结果itwish   双引号,结果为变量替换

命令历史:bash保存的过去曾执行的命令列表

当前shell进程的命令历史保存在缓冲区;缓冲区的命令会在shell进程退出时,保存至文件.bash_history 中 ;使用上下箭头按键可翻看此前曾执行的命令

# history  命令历史

    -c :清空history 列表

    -d n :清空历史中指定的第n行命令

    -a :追加回话的命令至历史文件中

history 快捷方式:

    !n:执行命令历史中第n行命令

    !! :执行上一次命令

    !-n :执行命令历史中倒数第n行命令

    !string :执行命令历史中最近一次以string 开头的命令

    !$ :引用上一条命令的最后一个参数 ,(Esc键 + . )

命令历史中相关的环境变量:

    HISTSIZE :命令历史中可以保存的命令个数

    HISTFILE :命令历史保存文件

    HISTFILESIZE :命令历史保存文件中可以保存命令的个数

    HISTCONTROL :控制命令历史的生成 (ignoredups代表忽略记录重复的命令;ignorespace代表以空格开头的命令不记录;ignoreboth 代表同时具备以上两种特性)


Linu bash 特性三:bash 中的变量


变量类型:

    本地变量,只对当前Shell进程有效,对其子shell 及其他shell都无效

  • 定义变量:# [set] Var_Name="Value"    注:在定义变量时,=左右不能有空格

  • 引用变量:${Var_Name} 或 $Var_Name

  • 撤销变量: # unset Var_name

    局部变量,进队进程中的某一个函数片段有效,仅对局部代码有效

  • 定义变量: # local Var_Name="Value"   注:在定义变量时,=左右不能有空格

    环境变量,用来描述bash的工作特性,用于保存当前会话的属性信息。对当前Shell进程及其子shell进程都有效

  • 定义变量;# export  Var_Name="Value"   注:在定义变量时,=左右不能有空格

    位置变量,$1 ... $n 分别代表不同的参数

    特殊变量

  • $0:脚本名称自身

  • $?:上一次命令的执行状态。状态使用数字表示,0表示执行成功,1-255表示执行失败

  • $*,$@ : 引用所有的位置参数

显示环境变量: # export   ,# env  ,# printenv  ,# set  (显示当前进程中的所有变量,包括本地变量及环境变量)

输出变量:# echo $变量 或 # echo ${变量名}

例:# NAME="itwish" echo ${NAME}  ,得出结果itwish  

read 交互式脚本  ,命令格式

    -t :超时时间

    -p :提示

    -n :变量数量

例: # read -t 5 -p “Enter a num: " Num    ,输入一个数字,保存到变量Num中,超时时间为5s

给予变量以默认值:

VarName=${VarName,-n} ,如果VarName不空 ,则其值不变 ;否则,VarName 会使用n作为其值

例:#!/bin/bash

       read -t 5 -p "Enter a num:" num1

       num1=$ {num1:-0}

       echo $num1

bash中的配置文件,用来保存配置信息

    profile类文件:为交互式登录的用户提供配置信息;功能:设定环境变量,如运行命令或脚本

    /etc/profile    全局配置

    /etc/profile.d/*.sh 全局配置

    ~/.bash_profile  个人配置,仅对该目录用户有效

    bashrc 类文件:为非交互式登录的用户提供配置;功能:设定本地变量 ,如设置命令别名

    /etc/bashrc 全局配置

    ~/.bashrc   个人配置

用户登录类型:

    交互式登录:直接通过终端输入用户信息登录,如# su  - UserName 或 # su -l UserName;读取配置文件的顺序为:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

    非交互式登录:如 # su UserName ;读取配置文件顺序为 :~/.bashrc --> /etc/bashrc ---> /etc/profile.d/*.sh

使新增配置的生效方式:

    通知sehll 重读配置文件的命令 # source (.) FILE

    重新登录


Linu Bash 特性四:命令别名及文件通配符globbing


alias 定义别名,命令格式:

# alias [-p] [name[=value] ...] 

# alias :显示当前shell中定义的所有别名

# unalias :取消定义别名 

# \command :在命令前加反斜线,表明使用命令本身

例:# alias cdnet='cd /etc/sysconfig'   定义cdnet 命令代表了cd /etc/sysconfig 功能

文件通配符的作用是为了匹配相关文件,与之前blog提及的正则表达式(功能:匹配文件中的字符串)相区分 。

    * :代表任意长度的任意字符 ,而正则表达式中*的含义为匹配前面的字符任意次

    ? :代表任意单个字符 ,与正则表达式中.的含义相同。

    [ ] :匹配范围内的任意字符   ,例:[Ss] 代表匹配S或s内的任意单个字符

    [0-9] 或 [[:digit:]] :任意单个0-9的数字

    [a-z] 或 [[:lower:]] :任意单个a-z 小写字母

    [A-Z]或[[:upper:]] :任意单个A-Z大写字母

    [[:alpha:]] :任意单个大小写字母

    [[:alnum:]] :任意单个带大小写字母或数字

    [[:space:]] :任意单个空白符

    [[:punct:]] :任意单个特殊字符

    [^] :指定范围外的任意单个字符

例:# cp -r   /var/1*[0-9]*[:lower:] /tmp    ,复制/var/ 目录下所有以1开头,以一个小写字母结尾,且中间出现一位数字的文件或目录至/tmp 下

例:# cp -r /var/[^[:alpha:]][[:alnum:]]?  /tmp/,复制/var目录下以非字母开头,后面跟了一个字母或数字,且最后跟单个字符的文件或目录至 /tmp下

Linu Bash 特性五:bash 快捷键及命令补全


Ctrl + l :清屏,相当于clear

Ctrl + a:光标跳至命令首部

Ctrl + e:光标跳至命令结尾

Ctrl + c:取消或终止命令执行

Ctrl + u:删除命令行首至光标所在处的所有内容

Ctrl + k:删除光标所在位置至命令行尾的所有内容

Ctrl + z:将当前的命令放置后台执行

命令补全功能:

    PATH :是一组由分号分开的路径,使用TAB按键进行补全

路径补全

    在给出的打头路径下补全;如果没有则为当前。使用TAB按键进行补全


Linu Bash 特性六:管道与重定向


管道机制

    | : 一条命令的输出结果作为另一条命令的输入

重定向

输入重定向 < , <<

    < : 输入重定向

    << EOF :此处创建文件,常用语在脚本中创建文件或生成菜单

    例:#!/bin/bash

            cat << EOF

            a) :show user info

            b) :show disk info

            c):show cpu info

            EOF

输出重定向 > , >>

    > : 覆盖输出

    >> :追加输出,# set -c :禁止使用覆盖重定向至已经存在的文件 ,# set +c :关闭上述特性

    >> /dev/null :位桶 , 一般用于命令结果覆盖输出 ,例  # ls /etc/ >> /dev/null  echo $?

错误重定向 2> , 2 >>

    2> :错误覆盖输出

    2>>:错误追加输出

同时重定向标准输出及错误输出

    Command &> /path :代表成功输出和错误输出到同一制定文件/path


Linu Bash 特性七:算数运算


declare  定义变量

    -i  :定义×××变量

    -x :定义环境变量,类似于 #export

例:# declare -i sum=0 ,定义sum变量为×××变量,且值为0

操作符:

    + ,- ,* ,/ , %

    += ,-= ,*= ,/= , %=

    ++ ,--  例: let sum ++ , let I--

运算格式:

 let VarNum=$num1+$num2  或 let VarNum=$num1+`命令`

 VarNum=$[$num1+$num2]

 VarNum=$(($num1+$num2))

 VarNum=`expr $num1 + $num2`


Linu Bash特性八:条件判断


判定后续操作的前提条件是否满足,条件判断常用判断类型:

bash条件判断:

    test EXPRESSION

    [  EXPRESSION ]  ,两端有空白

    [[ EXPRESSION ]] ,两端有空白

整数测试:

    num1 OPRAND num2

    -gt:大于 [ $num1 -gt $num2 ]

    -lt :小于

    -ge:大于或等于

    -le:小于或等于

    -ne:不等于

    -eq:等于

字符测试:

    > :大于

    < :小于

    == :等值比较 ,变量加双引号,且注意空白符。例: [ "$StringA"  == "$stringB"  ]

    =~ :左侧是字符串(或变量),右侧是一个模式 。判定左侧的字符串能否被右侧的模式所匹配 ;通常只在[[  ]] 中使用模式中可以使用行首、行尾锚定符 ,但模式不要加引号 

    -n  $stringVar :判定字符串是否不空 ,不空为真 ,空则为假  例:[ -n "$stringA"]  ,判断stringA是否为不空 ,不空为真

    -z  $stringVar :判定字符串是否为空 ,空为真  ,不空为假   例:[ -z "$stringA"]  ,判断stringA是否为空 ,空为真

例:[[ "$stringA" =~ ot ]] ,判断stringA 字符串是否包含ot ,包含为真

例:[[ `grep "^$userName\>" /etc/passwd |cut -d: -f7` =~ sh$ ]]    判断变量userName 中的shell 是否以sh结尾                

文件测试:

    -e  File :测试文件是否存在

    -a  File:测试文件是否存在

    -f   File :测试是否为普通文件

    -d  File :测试是否为目录文件

    -b  File :测试文件是否存在并且为块设备

    -c   File :测试文件是否存在并且为字符设备

    -r   File : 测试其有效用户是否对此文件有读权限

    -w  File:测试文件是否存在 且测试其有效用户是否对此文件有写权限  

    -x   File :  测试文件是否存在 且测试其有效用户是否对此文件有执行权限

    -s   File:测试文件是否存在并且不空   

例: [ -e  $fileName ] || mkdir $fileName    若文件不存在,则创建目录

组合条件测试:

    与: && ,条件1 && 条件2  ,即如果条件1满足,执行条件2

      条件1位假,则最终结果一定为假,因此条件2将不执行

      条件1位真,则最终结果取决于后面的条件,条件2必须执行。

    或: || ,有真为真 ,如果条件1不满足,则执行条件2

       条件1位真,则最终结果一定为真,因此条件2将不执行

       条件1位假,则最终结果取决于后面的条件,条件2必须执行。

    非: ! , 非真为假,非假为真

例: # id $userName &> /dev/null && echo "$userName exit ." || echo "$userName is not exit"    如果$userName 用户存在,则输出“exit”,否则输出‘not exit’


Linu Bash 编程练习1


1、 写一个脚本,计算100以内所有整数的和

#!/bin/bash
declare -i sum=0
for I in {1..100};do
   let sum+=$I
   let I++
done
echo "1 to 100 sum is $sum"

2、写一个脚本,计算100以内所有奇数的和 及所有偶数的和
方法1:

#!/bin/bash
declare -i sum1=0
declare -i sum2=0
for I in `seq 1 2 100`;do
   let sum1+=$I
   let I+=2
done
echo "1 to 100 jishu sum is $sum1"
for I in `seq 0 2 100`;do    表示从0开始,以2 为跨度,直至100
    let sum2+=$I
    let I+=2
done
echo "1 to 100 oushu sum is $sum2"

方法2:

#!/bin/bash
declare -i sum1=0
declare -i sum2=0
for I in {1..100};do
    if [ $[$I%2] -eq 0 ];then   通过取模是否为0判断是奇数还是偶数,注意$[$I%2]
       let sum1+=$I
    else
       let sum2+=$I
    fi
done
echo "the O sum is $sum1"
echo "the sum is $sum2"

3、计算所有计算机内用户的ID之和
方法1:

#!/bin/bash
declare idsum=0
NO=`wc -l /etc/passwd |cut -d' ' -f1`
for I in `seq 1 $NO`;do
   J=`cut -d: -f3 /etc/passwd |head -$I |tail -1`
   idsum=$[$idsum+$J]
done
echo "id sum is $idsum"

方法2:

#!/bin/bash
declare idsum=0
for I in `cut -d: -f3 /etc/passwd`;do       列表循环
    idsum=$[$idsum+$I]
done
echo "id sum is $idsum"

 
4、计算/etc/rc.d/rc.sysinit、 /etc/init.d/functions 和 /etc/issue 三个文件的字符数之和

#!/bin/bash
declare -i charSum=0
for fileName in {/etc/rc.d/rc.sysinit,/etc/init.d/functions,/etc/issue};do
     let J=`wc -c $fileName |cut -d' ' -f1`
     charSum=$[$charSum+$J]  或 let charSum=$charSum+`wc -c $fileName |cut -d' ' -f1`
done
echo "The CharSum is $charSum"

5、新建用户tmpuser1~tmpuser10 ,并计算他们的id之和

#!/bin/bash
declare -i idSum=0
for I in {1..10};do
  useradd tmpuser$I;
  let J=`id -u tmpuser$I`
  idSum=$[$idSum+$J]   或 let idSum=$idSum+`id -u tmpuser$I`
done
echo "The User idSum is $idSum"

6、判断文件中是否有空白行

#!/bin/bash
Read -p "Enter a File Path: "fileName
if  grep "^$"  $fileName &>/dev/null ; then
       lineCount=`grep "^$" $fileName` |wc -l
       echo "$fileName have $lineCount space lines"
fi

7、判断两个数随大随小

#!/bin/bash
if [ $# -lt 2 ] ;then       #表示脚本参数不能少于2个,中括号内格式需要两端留空格
     echo "Usage : j.sh num1  num2"
     exit 7
fi
if [ $1 -gt $2 ];then
    echo "the max num is $1"
else
     echo "the max num is $2"
fi


Linu Bash 编程练习2


1、写一个脚本实现以下功能
 让用户通过键盘输入一个用户名;如果用户存在,就显示其用户名和UID;否则就显示用户不存在 ‘

#!/bin/bash
read -t 5 -p "Input a userName:" userName
userName=${userName:-root}    设定为默认值
if id $userName &> /dev/null;then
   echo "$userName name is $userName ;UID is `id -u $userName`"
else
   echo "$userName is not exit."
fi

 
2、让用户通过键盘输入一个用户名,如果用户不存在就退出;如果用户的UID大于或等于500,就显示它是普通用户,否则就说明这是管理员或系统用户

#!/bin/bash
read -p "Input a userName:" userName
id $userName &>/dev/null
if [ `echo $?` -ne 0 ];then     或者  if ! id $userName &> /dev/null ;then   判断用户不存在
   echo "$userName is not exits"
   exit 100
else
   if [ `id -u $userName` -ge 500 ];then
       echo "$userName is useradmin"
   else
       echo "$userName is rootadmin"
   fi
fi

3、让用户通过键盘输入一个用户名,如果用户不存在就退出,如果其UID等于其GID,就所它是一个“good guy” ,否则就是“bad guy”

#!/bin/bash
read -p "Input a userName:" userName
id $userName &>/dev/null
if [ `echo $?` -ne 0 ];then                       #判断用户是否为不存在
   echo "$userName is not exits"
   exit 100
else
   if [ `id -u $userName` -eq `id -g $userName` ];then
      echo "$userName is good guy"
   else
       echo "$userName is bad guy"
   fi
fi

4、写一个脚本 ,添加10个用户stu1 -stu10 ,但要先判断用户是否存在 ,如果存在,就用红色显示其已存在 ;否则就添加此用户 ,最后显示一共添加了几个用户

#!/bin/bash
#
declare -i sum=0
for I in {1..10};do
 if id stu$I &>/dev/null;then    #用户存在为真
    echo -e "\033[31mstu$I is exits.\033[0m"
 else
    useradd stu$I && echo "\033[32mstu$I \033[0m add sucessful."
    let sum++
 fi
done
echo "useradd $sum users"

5、判定有用户是否拥有可登陆shell              

#!/bin/bash
#
for userName in `cut -d: -f1 /etc/passwd` ;do
  if [[ `grep "^$userName\>" /etc/passwd |cut -d: -f7` =~ sh$ ]];then
    echo "login user $userName"
  else
    echo "Nologin user $userName"
  fi
done

 
6、让用户交互式输入一个用户名,先判断用户是否存在,不存在 ,则以7为退出吗;判断用户的shell是否为/bin/bash ,如果是 ,则显示为 “bash User” 退出吗为0 ,否则显示“Not bash User ” ,退出吗为1

#!/bin/bash
#
read -p "Enter a username: " userName
if ! id $userName &> /dev/null;then
    echo "The user not exit."
    exit 7
fi
userShell=`grep "^$userName\>" /etc/passwd | cut -d: -f7`     不要忘记锚定词尾\> 
if [[ "$userShell" == "/bin/bash" ]];then
   echo "Bash User"
   retrunValue=0
else
   echo "Not Bash User"
   returnValue=1
fi
exit $returnValue


7、编写一个脚本显示如下菜单:,
  cpu)show cpu info
  mem) show memory info
  quit) quit
  Enter your option:
如果用户选择cpu ,则显示文件/proc/cpuinfo 的信息
如果选择mem ,则显示文件/proc/meminfo的信息
如果选择quit ,则推出,且退出码为5
如果用户选择其他字符,则显示未知选项,请重新输入脚本,退出码为6

#!/bin/bash
#
cat << EOF
cpu)show cpu info;
mem)show memory info;
quit)quit
EOF
read -p "Enter your choice:" Choice
Choice=`$Choice | tr 'A-Z' 'a-z'`   ,把大写字母转化为小写字母
if [[ "$Choice" == "cpu" ]];then   ,注意字符加双引号 ,且注意空格
   cat /proc/cpuinfo
elif [[ "$Choice" == "mem" ]];then
  cat /proc/meminfo
elif [[ "$Choice" == "quit" ]];then
  returnValue=5
else
  echo "Unknown options ,please run shell"
  retrunValue=6
fi
[  -z  $retrunValue ]  &&  returnVlaue=0   ,如果returnValue 未赋值 ,则returnValue =0 
exit $retrunValue


本章blog知识点汇总


bash特性之命令扩展 {,}

bash特性之符号引用及历史命令:` `  ,‘’ ,“”  ,history

bash特性之变量:变量赋值 ,变量输出, 本地变量,环境变量,局部变量 ,变量配置文件   

bash特性之命令别名及文件通配符 :# alias  #unalias

bash特性之快捷键及补全功能: 使用tab  补全命令或路径 ,Ctrl + 不同的字母组合不同的含义

bash特性之管道与重定向 :  | 管道符  ,&> /dev/null  输出重定向(包含正确及错误信息)  

bash特性之算数运算 : ++ ,+= ,let sum=$sum+$I

bash特性之条件判断: 循环语句 for ,while ,until ;判断语句 if ,case  格式