打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
shell编程-基础
day01   shell 简介
什么是shell
存取权限和安全
shell简单脚本
shell特性

1. /etc/shells            去cat一下
echo   $SHELL       看看当前运行的是哪个shell

2. bash的特殊之处:
① 历史记忆功能
②  ls+两次Tab键, 就可以查看出以ls开头的所有命令
③ help 回车, 可以查看bash 下面的重要命令

3. b 一般代表块设备文件, 一般放在/dev/ 目录下面
info  chmod;   或者 man  chmod;  可以查看chmod命令的用法.

4. 文件的存取权限:
setuid (suid/guid) (chmod  u+s, g+s  file)
chmod 和 chgrp (chown  user  file / chgrp  group  file)
umask  (umask   nnn)
符号链接 (ln  [-s]  source_path    target_path)

chmod  [who]  operator  [permission]  filename
who (u, g, o ,a)
operator (+, -, =)
permission (r, w, x, s, t)

chmod   u=rwx, g+w, o+r   myfile

chmod  u+s  myfile;   //加s位, 会涉及到安全问题.
                                (这时候 其它用户会以user的身份去做一些事情)
chmod  g+s  myfile;  //其它用户会以组用户的身份去做一些事情

chown   root, itlab   myfile;

chmod  o+t   myfile; //t位 表示这个文件在运行时 会放在缓存中去执行.

注: 以上为采用符号模式修改文件权限, 也可以采用绝对模式 如: chmod  740  myfile; 

5. ls   -l  /bin  | grep  '^...s' 回车;   //查找用户具有s位的文件

chmod  u+s  myfile; 相当于--->chmod   4744  myfle;

chmod   6744  myfile; 给group增加一个S位;

chmod   7744  myfile;  给other增加一个T位;

6. 改变文件的拥有者 和 文件所处的组;
chown 和 chgrp

chown  [-R]  owner  myfile;  //当myfile是个目录是会用到-R
chown  owner.group  myfile;
chown   .group  myfile;
chgrp  [-R]  group  myfile;

7. umask 命令决定了生成一个文件默认的权限是什么:
/etc/profile ($HOME/.profile  $HOME/.bash_profile)   //修改umask的地方.

umask

示例: umask 回车;  022    //0代表前三位 即user位, 2代表group位, 2代表other位.
它决定了创建的文件是644; 创建的目录是755;

cat  /etc/profile  | grep  "umask";

8. 符号链接:
硬链接;
软连接;

ln  [-s]  source_path   target_path;
//不加s是建立硬链接, 加s是建立软连接.


1.3 节    Shell脚本

① 使用shell脚本的原因;

功能强大; 节约时间

② shell脚本基本元素;
#!/bin/bash
    - 第一行

#
    - 除了第一行之外, #表示注释

变量

流程控制语句

③ shell 脚本运行方式.

9. shell编程示例:

#!/bin/bash
#这是一个打印hello world 的shell 脚本
printchar="hello world"
echo  ${printchar};        #大括号在这种情况下是可有可无的
echo  $HOME


1.4节    Shell的特性

别名;
alias                   //查看系统中现在都有哪些别名
alias  l1='ls  -alh'

管道;
命令替换;
重定向;
后台处理;
模式匹配;
变量;

用变量来存储信息

特殊字符.

2. 这些命令一般会放在: cat  $HOME/.bashrc

3. 命令替换

myfile的内容:
parm
findfile

ls  `cat  myfile`  -al   //反引号, 把执行后的信息 作为参数传递给ls命令

4. 后台处理

一个终端可以同时运行多个程序;
nohup  command  &

如: nohup  tar  -czf   enerco.tar.gz  enerco  &

用命令: jobs  -l   //可以查看到正在后台运行的程序.

5. 管道 (|)
把一个命令的输出连接到另一个命令的输入;
ls | sort

6. 重定向 (< >)
与管道相关, 可以改变程序运行的输入来源和输出地点;
sort  < myfile.txt
sort  < myfile.txt  > myfile_dort.txt

7. 模式匹配
显示以txt为扩展名的文件或显示以a开头的文件, 这种能力就称模式匹配;
正则表达式.

8. 特殊字符
①双引号(""): 用来使shell无法认出空格, 制表符和其它大多数特殊字符.
这样"David  Medinets" 表示一个值, 而不是2个值.  同样"David  < Medinets"表示一个值.
② 单引号 (' '): 用来使shell无法认出所有特殊字符.
如: touch  'testfile file'
③ 反引号 (` `): 用来替换命令.
④ 反斜杠(\): 用来使shell无法认出其后的特殊字符, 使其后的字符失去了特殊的含义.
如 David\ Medinets 
⑤分号(;): 允许在一行上放多个命令;
& : 命令后台执行;
括号 ( ): 创建成组的命令;
大括号{ }: 创建命令快;
竖杠 ( | ): 管道表示符;
< >&: 表示重定向;
*? [ ] ! : 表示模式匹配;
$ : 变量名的开头;
# : 表示注释 (第一行除外);
空格, 制表符, 换行符: 当做空白.

--------------------------------------------------------------

第二章   shell中的变量和运算符

内容:
本地变量; 影响变量的命令; 环境变量; 引号;
变量替换; 运算符; 位置变量; 表达式替换;
标准shell变量; 运算符的优先级; 特殊变量.

2.1 变量
什么是shell变量;  本地变量; 环境变量; 变量替换(显示变量);
位置变量; 标准变量; 特殊变量; 影响变量的命令.  

2.1.1 本地变量
① 本地变量在用户现在的shell生命期的脚本中使用.
② variable-name=value
③ set 显示本地所有的变量
④ readonly  variable-name

示例: LOCALTEST="test"
echo  ${LOCALTEST}

readonly  LOCALTEST
LOCALTEST="test4"
readonly
readonly  -p


2.1.2 环境变量
① 环境变量用于所有用户进程(经常称为子进程). 
登录进程称为父进程. shell中执行的用户进程均称子进程.
不像本地变量(只用于现在的shell), 环境变量可用于所有子进程,
这包括编辑器,脚本和应用程序.
② $HOME/.bash_profile (/etc/profile :对所有用户都有效)
export
env

使用export也可以查看到环境变量有哪些.

2.1.3 变量替换
① 用变量的值替换它的名字
② echo
③ 在变量名前加$, 使用echo命令可以显示单个变量的取值.
④ 示例: testvar="this is a test"
echo  ${testvar}

echo  ${testvar:+"chinaitlab"}
echo  ${testvar1:+"chinaitlab"}

echo  ${testvar1:-"chinaitlab"}   //未设置的话 返回新的值
echo  ${testvar1:-"chinaitlab"}  //已设置的话, 则返回原来的值

echo  ${testvar:="chinaitlab"} //如果设置了, 则返回原来的值
echo  ${testvar2:="chinaitlab"} //如果未设置, 则设置并返回现在的值


2.1.4 变量清除
①unset
unset  variable-name
例如: testvar="this is a test"
echo  ${testvar}

unset   testvar    //readonly的变量不能取消它的值
echo  ${testvar}

2.1.5 位置变量
① 位置变量表示 $0, $1, ......$9
$0                      $1         $2         $3           $4            $5            $6               $7               $8            $9
脚本名字         A          B          C             D             E             F                 G  
② 向脚本中使用位置参数
③ 向系统命令传递参数

2.
#!/bin/bash
#parm.sh
 find  /home/chinaitlab/shell  -name  $1  -print


2.1.6 标准变量  (大部分都是环境变量)
① bash默认建立了一些标准环境变量, 可在 /etc/profile中定义.

EXINIT     //定义了初始化vi的一些参数

HOME      //指我们的主目录
  
IFS      //设定了 系统中每个域或字段之间的分割是啥

LOGNAME   //以哪种用户登录的

MAIL     //当前用户存储的邮箱是放在那里

MAILCHECK   //每隔多少秒去检查邮箱中是否有邮件过来

2. echo  $LOGNAME
set  | grep  "LOG"

set  | grep  "MAIL"

③ MAILPATH  //当有多个邮箱时 可以用它来指定邮箱的路径
TERM   //进入系统之后, 终端的类型是什么    
PATH  //寻找可执行文件的路径
TZ        // 表示时区
PS1     //表示登陆系统之后shell的提示符是什么
PS2       // PS2=`>  ` , 当在一行上面运行多个命令时 需要用到.
EDITOR
PWD         //表示当前目录
SHELL      //当前运行的shell是哪个
MANPATH   //系统中帮助文档存放的目录有哪些
TERMINFO   //终端类型的一些配置信息

注: set  | grep  "TERM"
set  | grep  "PATH"
set  | grep  "PS"

PS1=`[\u@\h \w]\$ `        //当前用户; 计算机名; 路径

示例: for  loop  in  `cat  myfile`
> do
> echo  $loop
> done


2.1.7 特殊变量
① $#  (传递到脚本的参数列表)
② $*  (以一个单字符串显示所有向脚本传递的参数, 与位置比变量不同,
           此选项参数可超过9个)
③ $$  (脚本运行的当前进程ID号)
④ $!   (后台运行的最后一个进程的进程ID号)
⑤ $@  (与$#相同, 但是使用时加引号, 并在引号中返回每个参数)
⑥ $-   (显示shell使用的当前选项, 与set命令功能相同)
(7) $?   (显示最后命令的退出状态, 0表示没有错误, 其他任何值表明有错误)

示例:
#!/bin/bash
#parm
echo   "这是脚本的名称: #0"
echo   "这是脚本的第1个位置参数: $1"
echo   "这是脚本的第2个位置参数: $2"
echo   "这是脚本的第3个位置参数: $3"
echo   "这是脚本的第4个位置参数: $4"
echo   "这是脚本的第5个位置参数: $5"
echo   "这是脚本的第6个位置参数: $6"
echo   "这是脚本的第7个位置参数: $7"
echo   "这是脚本的第8个位置参数: $8"
echo   "这是脚本的第9个位置参数: $9"
echo   "显示参数个数: $#"
echo   "显示脚本全部参数: $*"
echo   "显示进程ID: $$"
echo   "显示前一个命令运行后状态: $?"

2.1.8  影响变量的命令
① declare  设置或显示变量
-f   只显示函数名
-r   创建只读变量(declare和typeset)
-x  创建转出变量          // export
-i    创建整数变量
使用+替代-, 可以颠倒选项的含义
 
② export   用于创建传给子shell的变量   // 也就是创建环境变量
--  表明选项结束, 所有后续参数都是实参   //也就是不带参数的
-f   表明在"名-值" 对中的名字是函数名
-n   把全局变量转换成局部变量(即本地变量), 换句话说, 命令的变量不再传给shell
-p   显示全局变量列表

③ 影响变量的命令
readonly   用于显示或设置只读变量
--  表明选项结束;
-f   创建只读变量;

set   设置或重设各种Shell

④ shift  [n]
用于移动位置变量, 调整位置变量, 使$3的值赋予$2, $2的值赋予$1.

typeset
用于显示或设置变量;
是declare的同义词.

unset   用于取消变量的定义.
--  表明选项结束;
-f   删除只读变量, 但不能从Shell环境中删除指定的变量和函数.
     如: PATH, PS1, PS2, PPID, UID, EUID 等的设置.

示例:
#!/bin/bash
#parm
echo   "这是脚本的名称: #0"
echo   "这是脚本的第1个位置参数: $1"
echo   "这是脚本的第2个位置参数: $2"
echo   "这是脚本的第3个位置参数: $3"
echo   "这是脚本的第4个位置参数: $4"
echo   "这是脚本的第5个位置参数: $5"
echo   "这是脚本的第6个位置参数: $6"
echo   "这是脚本的第7个位置参数: $7"
echo   "这是脚本的第8个位置参数: $8"
echo   "这是脚本的第9个位置参数: $9"
echo   "显示参数个数: $#"
echo   "显示脚本全部参数: $*"
echo   "显示进程ID: $$"
echo   "显示前一个命令运行后状态: $?"
shift
echo  "这是脚本的第1个位置参数: $1"
echo  "这是脚本的第2个位置参数: $2"


2.2  引号

2.2.1 引用的必要性
变量和替换操作, 在脚本中执行变量替换时最容易犯的一个错误就是引用错误.
如: echo   ert   *
      echo    "ert   *"

2.2.2  双引号
使用双引号可引用除字符 $, `, \ 外的任意字符或字符串.
如: echo  -e  "ert, $SHELL '\n* china `echo  itlab` ' "

2.2.3 单引号
单引号与双引号类似, 不同的是shell会忽略任何引用值.换句话说, 如果屏蔽了其特殊含义,
会将引号里的所有字符 包括引号都作为一个字符串.
如: echo  -e  'ert, $SHELL * china `echo  itlab` ' 

2.2.4 反引号
反引号用于设置系统命令的输出到变量. shell将反引号中的内容作为一个系统命令, 
并执行其内容.
如: echo  "* china  `echo  itlab` "

2.2.5 反斜杠
① 如果一个字符有特殊含义, 反斜杠防止shell误解其含义, 即屏蔽其特殊含义.
② 下述字符包含有特殊意义: &  *  +  ^   $   `   "    |    ?
如: echo   *           //会列出当前目录下所有的文件名.
      echo    \*



2.3  运算符
① 运算符是对计算机发的指令.
② 运算对象
--数字, 字符 (字面值);
--变量
--表达式
③ 表达式: 运算符和运算对象的组合体.

2.3.1 运算符类型
① 按位运算符
~, <<, >>, &, |, ^
② $[  ]  表示形式  告诉shell对方括号中的表达式求值.
如: $[ 2+8 ]

#!/bin/bash
# $[ ] 表示形式举例
echo  $[ 2+8 ]

赋值运算符:
let   $count = $count + $change
let   $count + = $change
 

2.3.2 表达式替换
① $[  ] 和 $( (  ) )   两者效果一样
-习惯使用$[   ], 所有shell的求值都是用整数完成.
② $[   ]可以接受不同基数的数字
- [  base#n ]  n表示基数从2到36的任何基数.
如: echo  $[  10#8 + 1 ]       //9  即8进制的10加上1是9 
注: $与[] 中间不能有空格

-----------------------------------------------------------

第三章 shell输入与输出

内容:
echo;  文件重定向;  
read;   标准输入, 输出和错误;
cat;      管道;   文件重定向; 
tee;       合并标准输出和标准错误; 
exec;     使用文件描述符.


3.1.1 echo
① echo命令可以显示文本行或变量, 或者把字符串输入到文件.
② echo  [option]   string
-e   解析转义字符;
-n   回车不换行, linux系统默认回车换行;
---  转义字符 (\c 回车不换行, \f  表示静止, \t 跳格, \n 回车换行)

3.2.1 read
① read语句可以从键盘或文件的某一行文本中读入信息, 并将其赋给一个变量.
② read  varible1   varible2  ...
-- 如果只指定了一个变量, 那么read将会把所有的输入赋给该变量, 直到遇到第一个
   文件结束符或回车; 如果给出了多个变量, 他们按顺序分别被赋予不同的变量. 
   shell将用空格作为变量之间的分隔符.

示例: 
#!/bin/bash
#readname
echo  -n  "First  Name:"
read   firstname
echo   -n   "Last Name:"
read   lastname
echo  -e  "Your  First  Name  is :${firstname}\n"
echo  -e   "Your Last Name is :${lastname}\n"

3.3.1 cat
① cat 是一个简单而通用的命令, 可以用它来显示文件内容, 创建文件, 还可以用它来
    显示控制字符.
② cat  [option]  filename1  ...  filename2  ...
-v   显示控制字符;
--- 使用cat命令时要注意, 它不会在文件分页符处停下来; 它会一下显示整个文件. 
    如果希望每次显示一页, 可以使用more命令或把cat命令的输出通过管道传递到另外
  一个具有分页功能的命令(more, less)中。
---  man   cat    //通过帮助文档查看cat的具体用法

示例: cat  file1   file2  file3    //把3个文件的内容一起输出到屏幕上.
 cat  file1   file2  file3  > myfile123      

注: cat  -v  dos.txt   //在C语言编程是, dos下转换过来的文件 要注意把控制字符过滤掉.]


3.4.1 管道 (|)
① 可以通过管道把一个命令的输出传递给另一个命令作为输入. 管道用竖杠 | 表示.
② 格式: 命令1 | 命令2

示例: df  -k | awk  '{print  $1}' | grep  -v  "Filesystem"

df  -k                              查看磁盘空间
awk  '{print  $1}'           查找第一列
grep  -v  "Filesystem"    过滤掉Filesystem

3.5.1 tee
① tee命令把输出的一个副本输送到标准输出, 另一个副本拷贝到相应的文件中.

② tee   -a files     //-a 表示将内容追加到文件files内容之后.

- 如果希望在看到输出的同时, 也将其存入一个文件, 那么这个命令再合适不过了.
- 一般用于管道之后

示例: who | tee  -a  who.out

df  -k | awk  '{print  $1}' | grep  -v  "Filesystem" | tee partation.txt

> nullfile.txt ;    可以创建一个字节为0的文件

3.7.2文件重定向示例
command << delimiter 举例:  (会用到PS2)

cat  >>term.txt << CHINAITLAB
>Hello, there I am using a $TERM terminal
>and my username is $LOGNAME
>bye...
>CHINAITLAB           (分隔符, 作为输入结束的标志)

② 重定向标准错误
grep  "trident"  missiles   (missiles是一个文件, 在(missiles中查找trident)

grep  "trident"  missiles  2>/dev/null  (会把错误信息重定向到/dev/null 文件中, 
                                                          但是这里又不会保存任何信息, 是个无底洞)

3.8.1 结合使用标准输出和标准错误
cat  account_new.txt    \  
account_old.txt  1>accounts.out   2>accounts.err       //可以把结果和错误信息进行分类

3.9.1 合并标准输出和标准错误
① 合并标准输出和标准错误的时候, 切记shell是从左至右分析相应的命令.
② grep  "standard"  standard.txt  > grep.out   2>&1      //如果遇到错误时输出到屏幕

3.9.2 exec 命令
① exec 命令可以用来替代当前shell; 换句话说, 并没有启动子shell, 使用这一命令时
    任何现有环境都将会被清除, 并重新启动一个shell。
② exec  command
    其中的command通常是一个shell脚本.
③ 对文件描述符进行操作的时候(也只有在这时), 它不会覆盖你当前的shell。

3.10.1 文件描述符
① 3-9 文件描述符
② exec 与文件描述符的结合

示例: 
#!/bin/bash
#file_desc
exec  3<&0   0<namke.txt         //标准输入变成了3, 该命令打开了3文件描述符
read  line1                               //从3中读取第一行的信息赋给line1
read  line2                               //从3中读取第二行的信息赋给line2
exec   0<&3                            //把3文件描述符又重定向到了1, 相当于关闭3
echo   $line1
echo   $line2

-----------------------------------------------------------

第四章 控制流结构

内容:
控制结构;                until循环;  
if  then  else语句;     while循环;
break控制;                case语句;
continue控制;           for循环.

4.1.1 控制流结构
① 流控制是什么?
#!/bin/bash
#创建一个目录
make  /home/chinaitlab/shell/txt
#复制所有txt文件到  /home/chinaitlab/shell/txt/
cp   *.txt   /home/chinaitlab/shell/txt
rm  -f  *.txt

4.1.2  if语句
格式:
if        条件1        //如果条件1为真
then                      //那么
           命令1        //执行命令1
elif      条件2        //如果条件1不成立, 条件2成立
then                      //那么
            命令2       //执行命令2
else                        //如果条件1, 2均不成立
             命令3       //那么执行命令3
fi                             //完成

示例: 
#!/bin/bash
# if  test
# this  is  a  comment  line, all  comment  lines start with a #
if[ "10"  -lt  "12" ]
then
    #yes  10  is less than 12
  echo    "Yes , 10 is less than 12"
fi

注: man  test    //查看一下帮助文档.
EXPRESSION1  -a   EXPRESSION2
-a       //and
-o      //or
-eq    //equal
-ge    //greater than or equal to
-gt    // greater than
-le     //less than or equal to
-lt      //less than
=      //判断字符串是否相等
-eq    //判断两个整数是否相等
-ne    //not  equal  to
FILE1  -ef  FILE2    // FILE1 and FILE2 have the same device and inode numbers
FILE1  -nt   FILE2    //FILE1  is  newer (modification date) than  FILE2
FILE1  -ot   FILE2    //FILE1 is older than  FILE2
-b  FILE      //FILE  exists  and  is  block  special
-c  FILE      //FILE  exists and is character special
-d  FILE      //FILE  exists  and  is  a  directory
-e  FILE      //FILE   exists
-f  FILE      //FILE   exists  and is  a regular  file
-z  STRING   //the length  of  STRING  is  zero


示例1:
#!/bin/bash
# if  test2
echo  -n  "Enter your name:"      //-n 表示回车不换行
read  NAME
# did the user just hit return
if  [  "$NAME" == ""  ];  then
             echo  "You did not enter any information"
else
             echo  "Your Name is ${NAME}"
fi

示例2:
#!/bin/bash
# ifcp
if  cp  myfile.bak  myfile ;   then
           echo  "good  copy"
else
           echo  " `basename  $0` :error  could  not  copy the files "  >&2
fi


4.2.1 case 语句
case 语句为多选择语句. 可以用case语句匹配一个值与一个模式, 如果匹配成功,
执行相匹配的命令.

4.2.2 case语句格式
case 值 in
模式1)
         命令1
             ;;
 模式2)
          命令2
              ;;
esac

注: case取值后面必须为单词in, 每一模式必须以右括号结束.
取值可以为变量或常数. 匹配发现取值符合某一模式后, 其间
所有命令开始执行直至;; . 
模式匹配符* 表示任意字符,  ? 表示任意单字符 , [..]表示类或
范围中 任意字符.

示例:
#!/bin/bash
#case  select
echo  -n  "Enter  a number from 1 to 3:"
read ANS
case $ANS in
1)
   echo  "You select 1"
   ;;
2)
   echo  "You select 2"
   ;;
3)
   echo  "You select 3"
  ;;
y|Y)
    echo  "You select $ANS"
    ;;
*)
   echo  " `basename $0` : This is not between 1 and 3 " >&2
   exit;
   ;;
esac


4.3.1 for 循环
for 循环 一般格式:
for 变量名 in 列表
do
        命令1
        命令2
done

注: 当变量值在列表里, for循环即执行一次所有命令, 使用变量名访问列表中取值.
命令可为任何有效的shell命令和语句. 变量名为任何单词. in列表用法是可选的, 
如果不用它, for循环使用命令行的位置参数. in 列表可以包含替换, 字符串和文件名.

示例:
#!/bin/bash
#forlist1
for loop in 1 2 3 4 5 
do
     echo  $loop
done

示例2:
#!/bin/bash
#forlist2
for loop in "orange red blue grey"    //去掉引号就会分行打印
do
    echo  $loop
done

注: 有引号时会认为是一个元素, 去掉引号后 会认为是4个元素

4.4.1 until循环       (直到为真时, 就退出循环了. 为假时 一直执行)
until 循环一般格式为:
until 条件
do
        命令1
        命令2
        ...
done

注: 条件可为任意测试条件, 测试发生在循环末尾, 因此循环至少执行一次.

示例:
#!/bin/sh
#until_mon
#监控分区
Part="/backup"
# 得到磁盘使用的百分比
LOOK_OUT=` df | grep "$Part" | awk '{print  $5}' | sed  ' s/%//g '  `    //awk用空格来分割, 打印出第五个域
echo  $LOOK_OUT
until  [ "$LOOK_OUT"  -gt  "90" ]
do
             echo  "Filesystem  /backup is nearly full" | mail root
              LOOK_OUT=` df | grep "$Part" | awk '{print  $5}' | sed  ' s/%//g '  `
              sleep  3600
done

注: sed  ' s/%//g '      s表示替换

nohup  ./dfuntil  回车.     (让程序放在后台去运行)

4.5.1 while 循环
while 循环一般格式为:
while 命令
do
      命令1
      命令2
      ......
done

注: 在while和do之间虽然通常只使用一个命令, 但可以放几个命令,
     命令通常用作测试条件.

示例:
#!/bin/sh
#whileread
echo  "按住<ctrl>+D 退出输入."
while  echo  -n  "输入你最喜欢的电影: " ; read  FILM
do
            echo  "Yeah , ${FILM} 是一部好电影!"
done

示例2:
#!/bin/sh
#whileread
while  read  LINE
do
              echo  $LINE
done  < names.txt


4.6.1  break 和 continue 控制
① break  [n]
- 退出循环
- 如果是在一个嵌入循环里, 可以指定n 来跳出的循环个数.
② continue
- 跳过循环步

注: continue 命令类似于break命令, 只有一点重要差别, 它不会
跳出循环, 只是跳过这个循环步.

示例:
#!/bin/bash
#breakout
while   :                     //冒号表示永远为真, 这样可以永远循环下去
do 
           echo  -n  "Enter  any number [1...5] :"
           read  ANS
           case  $ANS  in
            1 | 2 | 3 | 4 | 5 )
                        echo  "You enter a number between 1 and 5."
                         ;;
             *)
                         echo  "Wrong  number , Bye."
                         break
                         ;;
                esac
done

----------------------------------------------

第五章   文本过滤

内容:
正则表达式;            sed 介绍;  
find 介绍;                 (文件)合并与分割 (sort , uniq , join , cut , paste , split);
grep 介绍;                 
awk 介绍.


5.1 正则表达式
① 一种用来描述文本模式的特殊语法;
② 由普通字符(例如字符 a 到 z) 以及特殊字符 (称为元字符, 如 / , * , ? 等) 组成.
③ 匹配的字符串
④ 文本过滤工具在某种模式下都支持正则表达式.

5.2 基本元字符集及其含义
   字符                                      含义
    ^                                 只匹配行首    (^a  表示只匹配以a开头的文本/文件)

    $                                只匹配行尾   (doc$  表示只匹配以doc结尾的文件)

    *                                 匹配0个或多个此单字符

   [ ]                               只匹配[]内字符. 可以是一个单字符, 也可以是字符序列.可以使用
                                      -表示[ ]内字符序列范围, 如用[1-5]代替[12345]
   
   \                             只用来屏蔽一个元字符的特殊含义 (如 \*, 还原了*的原本含义)

   .                               只匹配任意单字符

 pattern\{n\}              只用来匹配前面pattern出现的次数. n为次数 (如a\{3\, 匹配a出现3次的情况})

 pattern\{n,\}             含义同上, 但次数最少为n

pattern\{n,m\}            含义同上, 但pattern出现次数在n与m之间


示例:
① 句点"." 可以匹配任意单字符
...x..x..x
-rwx-r-xr-x      匹配

....XC....
3452XC763D    匹配

② ^ 只允许在一行的开始匹配字符或字符串
^d
drwxrwxrw-       匹配

^...1
3D11XC9871      匹配

③ $ 在行尾匹配字符串或字符, $放在匹配单词之后
trouble$     -- 匹配以单词trouble结尾的所有字符
^$               -- 匹配空行
^.$              -- 匹配包含一个字符的行

④ *  匹配单字符或 多字符的重复序列
匹配任意字符零次或 多次重复表达
10133*1
101331       匹配
10133921   匹配
10133As1  匹配

⑤ [ ] 匹配一个范围或集合
逗号将括弧内要匹配的不同字符串分开;
用"-"表示一个字符串范围;
[a-z] :  任意一个小写字母
[S,s] :  匹配大, 小写s

⑥ \{\} 匹配模式结果出现的次数
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\} : 匹配IP地址


(使用到正则表达式的一些命令)
5.10 find 命令  
一个查找命令;

查找具有某些特征文件的命令; (如 时间, 大小, 权限)

可遍历当前目录甚至于整个文件系统来查找某些文件或目录;

遍历大的文件系统时, 一般放在后台执行. (把结果重定向到一个文件中去)

5.11    find 命令形式
find 命令的一般形式:
find    pathname   -options     [-print   -exec   -ok]
 pathname      find命令所查找的目录路径. 例如 用/ 来表示系统根目录
- print               将匹配的文件输出到标准输出
- exec             对匹配的文件执行该参数所给出的shell命令, 相应命令的形式
                       为 'command'  { }  \ ;    注意{}和\之间的空格
-ok                  和 -exec 的作用相同, 只不过以一种更为安全的模式来执行该参数
                       所给出的shell命令, 让用户来确定是否执行.

5.11  find 命令选项
find 命令的一般形式:
-name    按照文件名查找文件;
-perm     按照文件权限来查找文件;
-user       按照文件属主来查找文件;
-group    按照文件所属的组来查找文件;
-mtime   -n   +n   按照文件的更改时间来查找文件, -n 表示文件更改时间距现在n天以内,
                             +n 表示文件更改时间距现在n天以前. find命令还有 - atime(访问时间) 和
                              - ctime (创建时间)选项, 但他们都和 - mtime 选项相似.
- size   n[c]          查找文件长度为n块的文件, 带有c时 表示文件长度以字节计.
- nogroup       查找无有效所属组的文件, 即该文件所属的组在 /etc/groups 中不存在
- nouser          查找无有效属主的文件, 即该文件的属主在 /etc/passwd 中不存在
- newer  file1   !file2    查找更改时间比文件file1新 但比文件file2旧的文件
- type              查找某一类型的文件, 诸如:
              b    块设备文件
              d     目录
              c      字符设备文件
              p     管道文件
              l       符号链接文件
              f       普通文件
- man  find     //查看一下帮助文档


5.12  find 命令举例
① 使用name选项
可以使用某种文件名模式来匹配文件, 记住要使用引号将文件名模式引起来
find    -name  "*.txt"   -print                 (默认就是当前路径)
find    ./     -name    "*.txt"    -print
find    ./     -name     "[A-Z]*"    -print    (查看以大写字母开头的所有文件)
find    /etc     -name     "host*"    -print
② 使用perm选项
find    .    -perm    755     -print
③  使用user和nouser 选项
find    `pwd`   -user    root    -print
find     `pwd`    -nouser     -print

注: 放在后台进行查找
nohup    find    /   -nouser    -print    > nouser.out   &

④ 使用group 和 nogroup 选项
find   .   /    -group    itlab     -print
find    /    -nogroup    -print

⑤ 按照更改时间查找文件
find     /var    -mtime    -5     -print     (改变时间在5天之内的打印出来)
find     /var/    -mtime    +3    -print

⑥ 查找比某个文件新或旧的文件
find    `pwd`    -newer    "myfile"    !    -newer    "myfile123"    -print

(7) 使用type选项
find    /etc     -type    d    -print
find    /etc     -type     l     -print

注: date   回车    // 查看今天的时间

(8) 使用size选项
find   .   -size   +1000000c   -print       (c 字符, 表示字节数.  +表示大于)
find   .    -size   +10     -print               (+ 表示块block)

(9) 使用depth选项
使用find 命令时, 可能希望先匹配所有的文件, 再在子目录中查找
find   /    -name    "CON.FILE"    -depth    -print

(10)  用exec 或ok 来执行 shell命令
find    .    -type    f     -exec    ls    -l     {}  \;          (先查找普通文件, 再执行后面的命令)
find    .    -name   "*.log"     -mtime     +5     -ok    rm{}  \;

注: ls  -hl   file.txt       //会显示文件大小的单位信息

(11)  xargs  (单一的进程, 可以减少系统资源的消耗)
在使用find 命令的 -exec 选项处理匹配的文件时, find 命令将所有匹配到的文件
一起传递给 exec . 不幸的是, 有些系统对能够传递给 exec 的参数长度有限制, 
这样在find命令运行几分钟之后, 就会出现溢出错误. 错误信息通常是"参数列太长"
或"参数列溢出". 这就是xargs命令的用处所在, 特别是与find 命令一起使用. 
exec 会发起多个进程, 而xargs不会多个, 只有一个.

find   ./     -perm     -7     -print    |  xargs    chmod   o-w

find   ./     -type     f    -print  |  xargs   file      (查看文件类型)

注: xargs  表示把前面命令的结果 作为参数传递给后面的命令来处理


5.13 grep介绍
① grep 是UNIX和LINUX中使用最广泛的命令之一
② 对文本文件进行模式查找
③ grep有三种变形
     Grep: 标准grep命令
     Egrep: 扩展grep, 支持基本及扩展的正则表达式
     Fgrep: 快速grep
④ grep 一般格式:
grep   [选项]    基本正则表达式    [文件]
字符串参数最好采用双引号括起来, 一是以防被误解为shell命令, 二是可以
用来查找多个单词组成的字符串.

5.13 grep命令选项
-c    只输出匹配行的计数
-i     不区分大小写    (只适用于单字符)
-h    查询多文件时不显示文件名
-H   显示文件名
-l     查询多文件时只输出包含匹配字符的文件名
-n    显示匹配行及行号
-s     不显示不存在或无匹配文本的错误信息
-v    显示不包含匹配文本的所有行

示例: 
grep    "jenny"    *.txt         //从所有的txt文件中查找含有jenny的文件
grep    "2004"     myfile
grep    -v    "2004:22"   myfile     //过滤掉2004:22
grep     "^[^210]"     myfile         // [^210] 表示以 210开头的行有哪些,
                                                     ^[^210] 即开头既不是2 也不是1 也不是0

grep    "H*P"   myfile
grep    "[5-8][6-9][0-3]"    myfile
grep    "4\{2\}"    myfile

grep   "^d"     lsout.txt     //以d开始的 即目录文件有哪些
grep   "^[^d]"   lsout.txt    //不是以d开始的 即非目录文件有哪些

5.13 grep命令类名  (通过一些类名来表示一些特定的正则表达式)

   类                       等价的正则表达式
[[:upper:]]                      [A-Z]
[[:alnum:]]                     [0-9a-zA-Z]
[[:lower:]]                       [a-z]
[[:space:]]                      空格或tab键
[[:digit:]]                         [0-9]
[[:alpha:]]                       [a-zA-Z]

grep   "5[[:digit:]][[:digit:]]"     myfile         //中间不能有空格

[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} : 匹配IP地址

grep   "php"   myfile | wc   -l              //统计有多少行


5.14  awk 介绍  --(一个工具, 一种语言. 它有自己的变量 有自己的语法结构)
① 可从文件或字符串中基于指定规则浏览和抽取信息
② 是一种自解释的编程语言
③ 三种方式调用awk:
- 命令行方式:
     awk   [-F  filed  -spearator]   'command'    input  -files
- awk脚本
    所有awk命令插入一个文件, 并使awk程序可执行, 然后用awk命令解释器
     作为脚本的首行, 以便通过键入脚本名称来调用它.
- awk 命令插入一个单独文件
  awk    -f    awk    -script   -file   input   -files
④ awk脚本由各种操作和模式组成
⑤ 模式和动作
   - 模式部分决定动作语句何时触发及触发事件. (BEGIN, END)
   - 动作对数据进行处理, 放在大括号{}内指明. (print)

⑥ 分隔符, 域和记录   (awk用来提取各个域的数据)
   - awk执行时, 其浏览域标记为 $1, $2...$n . 这种方法称为域标识. $0为所有域
   - 注意执行时不要混淆符号$和shell提示符$, 它们是不同的

注: $0就是这条记录;
shell中的$ 意思是在指明一个变量, 而awk中的$ 在指明一个域 (用分割符分割出来的一个个域);
动作通常是对域进行操作;

示例:
awk   '{print   $0}'   score.txt  | tee   score.out    //把 文件中的所有信息打印出来 (默认是以空格来分割)

awk   -F :  '{print   $1"\t" $4}'   score.txt  | tee   score.out 
                                                                             //以冒号来分割. "\t"是字符的话 必须以引号引起来

awk   -F  +0800  '{print   $1"\t" $4}'   score.txt  | tee   score.out   
                                                                             //-F  +0800   以+0800来作为分割符

awk   'BEGIN   {print  "IP     Date\n---------"} {print  $1"\t"$4} END  {print  "end-of-report"}'  score.txt

注: 所有awk的模式和操作都是放在单引号' '中, 命令都是放在大括号{}中执行;
BEGIN, END 是为了产生一些 报告头和报告尾 的信息;

5.14 awk介绍
awk 中的特殊元字符: +   ?                           // + 表示匹配任意字符;   ? 表示匹配单个字符

匹配操作符:  ~    !~                                         // ~ 表示匹配;    !~ 表示不匹配

cat   score.txt  | awk  '$0 ~ /218.79.131.96/'           //表示从记录中匹配匹配 IP是218.79.131.96的所有行
                                                                                匹配的内容放在两个双斜杠之间.

cat   score.txt  | awk  '$0  ~/218.79.131.96/'  | grep  "php" | wc  -l       //统计 是php页面 的行数
                                                                                                            //注: ~/218.79.131.96/ 之间没有空格

awk  '$0  !~/218.79.131.96/'   score.txt                //awk 中的流控制, 所有的操作都是在单引号之间 
                                                                              // 大括号内 .   awk 中域的默认分割是空格.

awk  '{if($1=="218.79.131.96")  print  $0}'   score.txt

man  awk

info   awk       //得到一些关于awk的帮助信息


5.15   sed 介绍
① sed 不与初始化文件打交道, 它操作的只是一个拷贝, 然后所有的改动如果
没有重定向到一个文件, 将输出到屏幕.

② sed 是一种重要的文本过滤工具, 使用一行命令或者使用管道与grep 与awk相结合.

③ 非交互性文本流编辑.

④ 调用sed有三种方式:
- 使用sed命令行格式为:
   sed  [选项]   sed命令   输入文件
- 使用sed脚本文件, 格式为:
   sed   [选项]   -f   sed脚本文件     输入文件.
- 不管是使用shell命令行方式或脚本文件方式, 
   如果没有指定输入文件, sed从标准输入中接受输入, 
   一般是键盘或重定向结果.
⑤ sed命令选项如下:
- n  不打印 没有匹配到的信息
- c  下一命令是编辑命令
- f   如果正在调用sed脚本文件

5.15   sed 介绍
① sed 在文件中查询文本的方式
- 使用行号, 可以是一个简单的数字, 或是一个行号范围.
- 使用正则表达式

x                                  x为一行号
x, y                             表示行号范围从x到y
/pattern/                      查询包含模式的行
/pattern/pattern/         查询包含两个模式的行
pattern/, x                   在给定行号上查询包含模式的行
x, /pattern/                  通过行号和模式查询匹配行
x, y!                             查询不包含指定行号x和y的行

② 基本sed编辑命令
p                打印匹配行
=                显示文件行号
a\                在定位行号后追加新文本信息
i\                 在定位行号后插入新文本信息
d                 删除定位行
c\                用新文本替换定位文本
s                  使用替换模式替换相应模式
r                  从另一个文件中读文本
w                 写文本到一个文件

q                  第一个模式匹配完成后退出或立即退出
l                   显示与八进制ASCII代码等价的控制字符
{}                 在定位行执行的命令组
n                   从另一个文件中读取文本下一行, 并附加在下一行
g                   将模式2粘贴到 /pattern  n/
y                    传送字符

   
5.15 示例:
sed     '2p'     score.txt                             //打印出文件中第二行的信息 (不匹配的也会打印)

sed   -n   '2p'   score.txt                        //打印出文件中第二行的信息 (-n 表示不匹配的  不打印)

sed    -n    '1,4p'    score.txtb                //打印出文件中的1-4行

sed    -n     '/los/p'     myfile.txt            //从文件myfile.txt中模式匹配到los 就打印出来

sed     -n     '4,/los/'    myfile.txt         //从第4行开始, 匹配到los就结束

sed     -n     '/^$/='     myfile               //打印出文件中 空行的行号

sed     -n   -e    '/^$/p'    -e    '/^$/='     myfile      //即打印出空白行 又打印出行号

sed     -n    '/chinaitlab/a\shenzhen'      myfile.txt       //a 表示在文件中chinaitlab后面添加什么样的字符, 
                                                                                      //老版本的会出现运行时错误. 应该分成两行来写:
                                                                                     //sed     -n    '/chinaitlab/a  \
                                                                                         shenzhen'      myfile.txt 

sed     -n    '/chinaitlab/i\shenzhen'      myfile.txt        //同上, 但是会插入在chinaitlab的前面
                                                                         //sed     -n    '/chinaitlab/i\shenzhen'      myfile.txt >myfileout.txt
                                                                         //这样可以把信息保留下来
sed     -n     '/chinaitlab/c\chinaitlab  shenzhen'      myfile.txt
                                                                         //表示把chinaitlab替换为chinaitlab  shenzhen

sed      '1,2d'    myfile.txt                       //把第1,2行 全部删除

sed      's/chinaitlab/chinaitlab  shenzhen/g'    myfile.txt   //s 代表替换, g表示如果有多个会全部进行替换

sed    -n    's/chinaitlab/& hello /p'   myfile.txt     //匹配上chinaitlab后 会加上 hello , 并打印出来

sed    -n    's/chinaitlab/hello &/p'   myfile.txt     //在匹配字符chinaitlab之前插入字符hello 并打印

sed    'lr   ctrl.txt'     myfile.txt

sed    '/china/q'    myfile.txt                    //匹配到china 马上退出

sed    -n    '/china/l'     myfile.txt             

info   sed   和   man    sed


5.16  合并与分割
① sort    [options]    files                 //按照不同的域来进行排序, 分割

许多不同的域按不同的顺序分类;
-c   测试文件是否已经分类
-m  合并两个分类文件
-u    删除所有复制行
-o    存储sort结果的输出文件名
-t     域分隔符, 用非空格或tab键分割域
+n    n为域号, 使用此域号开始分类
n指定分类是域上的数字分类项
-r      比较求逆

man    sort

示例:
sort     -c     myfile            //检查这个文件是否排序

sort     -u     myfile           //排序之后再合并. 行与行之间 有重复的话 要进行合并 再打印输出

sort     -r       myfile         //以相反的顺序进行排序

sort     -t"/"    +2     myfile    //-t"/"  表示分隔符.  以第2个域来进行排序

sort     -t"/"    +2n    myfile      //以第2个域 的数字大小 来进行排序

注: 域的计数 是从0开始的 0,1,2,3........


5.16  合并与分割
① uniq   [option]    files
从一个文本文件中去除或禁止重复行;
-u    只显示不重复行;
-d     只显示有重复数据行,每种重复行只显示其中一行;
-c     打印每一重复行出现次数    (不在临近的两行是不会进行统计的)
-f     n  为数字, 前n个域被忽略

man     uniq

示例:
uniq    -c    myfile.txt

uniq    -d     myfile.txt

uniq    -f     2    myfile.txt

uniq     -d      myfile.txt

sort    myfile.txt   |  uniq    -c             //这样才能统计的到 不相邻的重复行
 
awk   '{print  $1}'    myfile | sort | uniq   -c       //统计每个IP访问我页面的次数

grep  "php"  myfile | awk   '{print  $1}' | sort | uniq   -c    //每个IP访问我php页面的次数


5.16  合并与分割
① join   [options]   file1   file2
用来将来自两个分类文本文件的行连在一起;
-an, n 为一数字, 用于连接时从文件n中显示不匹配行;
-o  n.m ,连接域, n为文件号, m为域号;
-j  n  m, n为文件号, m为域号. 使用其他域做连接域;
t    域分割符. 用来设置非空格或tab键的域分隔符

示例:
join   -a1   -a2   address.txt   town

join   -o   2.2,1.1    address.txt   town

join   -j1   1   -j2   1   address.txt   town

5.16  合并与分割
① split用来将大文件分割成小文件
② split命令一般格式:
split   -output_file  -size   input  -filename   output  -filename

-b  n, 每个分割文件的大小n (k,m)
-C  n,每个分割文件一行最多n字节数;
-l   n, 每个分割文件的行数
-n, 同-l   n.
split  -10  ls_out.txt   split         //把文件分割成每个10行 以前缀是split的文件
                                                  //ls  -l   split* | wc  -l

man   split


5.16  合并与分割

① cut用来从标准输入或文本文件中剪切列或域

man   cut

② paste 按行将不同文件行信息放在一起

man   paste


cat  ls_out.txt  | wc  -l     //统计文件的行数

----------------------------------------------------------------------------

第六章   shell函数

内容:
定义函数;          函数文件;
函数调用;          载入和删除函数;
参数传递;          函数返回状态.


6.1 函数定义
① shell允许将一组命令集或语句形成一个可用块, 这些块称为shell函数.
② 定义函数的格式为:
函数名( )
{
命令1
.........
}

function   函数名( )
{
......
}

③ 函数可以放在同一个文件中作为一段代码, 也可以放在只包含函数
的单独文件中.
#!/bin/bash
#hellofun
function  hello( )
{
echo  "Hello, today is `date`"
return  1
}

6.1 函数的调用
#!/bin/bash
#func
function  hello( )
{
echo  "Hello, today is `date`"
}
echo "now going to the function hello"
hello
echo "back from the function"

//注: 写上函数名即可 进行函数调用

6.2 参数传递
① 向函数传递参数就像在脚本中使用位置变量 $1, $2 ...... $9 
#!/bin/bash
#func
function  hello( )
{
echo  "Hello, $1 today is `date`"
}
echo "now going to the function hello"
hello chinaitlab 
echo "back from the function"

6.3 函数文件

文件1:
#!/bin/bash
#func
#Source  function
.  hellofun                   //表示载入一个文件, 这个文件可以是脚本 也可以是函数
echo  "now going to the function hello"
hello
echo  "back from the function"

文件2:
#!/bin/bash
#hellofun
function  hello( )
{
echo  "Hello, today is `date`"
return 1
}

//注: 可以去查看一下 more  /etc/rc.d/init.d/network
more  /etc/rc.d/init.d/functions


怎样查看一个函数已经载入(调入)到脚本中:

6.4 检查载入函数和删除函数
① 查看载入函数
---  set

② 删除函数
--- unset

示例:
#!/bin/bash
#func
#Source  function
.  hellofun                   //表示载入一个文件, 这个文件可以是脚本 也可以是函数
set
echo  "now going to the function hello"
hello
echo  "back from the function"

6.6 函数返回状态值

文件1:
#!/bin/bash
#hellofunction
function  hello( )
{
echo  "Hello, today is `date`"
return  0                      //它返回的是状态值, 而不是得到一个值
}

文件2:
#!/bin/bash
#func
echo  "now going to the function hello"
hello
echo  $?                  //返回的状态值是 用$?  这个特殊变量来表示的
echo  "back  from the function"

----------------------------------------------------------------------

第七章   脚本中的参数传递

内容:
shift命令;            //改变参数的位置变量的值, 传递不同的值给相应的位置变量, 
                             //达到影响位置变量的目的.
                             //可以让位置变量的个数 多于9个
getopts .

7.1 shift   n       //n 表示向左移多少位
① 每次将参数位置向左偏移n位.
#!/bin/bash
#opt2
usage( )
{
            //basename  $0 : 表示打印出这个脚本程序的名称. filenames: 表示文件名
echo  "usage:`basename  $0`  filenames"       
}
totalline=0
if[$#  -lt  2]; then             //$# : 表示参数的个数, 即位置变量的个数
              usage
fi
while  [$#  -ne  0]           //当脚本的参数的个数不等于0的时候
do
           line=`cat  $1 | wc  -l`
           echo   "$1 : ${line}"
           totalline=$[$totalline+$line]
           shift                      //位置变量左移一位, 如把$2的值赋给$1
done
echo   "------"
echo   "total:${totalline}"

7.2 getopts
① 获得多个命令行参数
#!/bin/bash
ALL=false
HELP=false
FILE=false
VERBOSE=false
while  getopts  ahfvc:  OPTION                  //从字符集ahfvc中 依次读出每个字符 赋给变量OPTION
                                                                     //ahfvc:  说明冒号前面的那个参数是带有值的参数
do
                     case  $OPTION   in
                     a)
                              ALL=true
                              echo  "ALL  IS  $ALL"
                              ;;
                     h)
                             HELP=true
                             echo  "HELP  is  $HELP"
                             ;;
                     f)
                            FILE=true
                            echo   "FILE  is  $FILE"
                            ;;
                     v)
                           VERBOSE=true
                            echo  "VERBOSE  is  $VERBOSE"
                            ;;
                      c)
                            c=$OPTARG
                            echo  "c  value  is  $c"
                            ;;
                       \?)                                      //匹配时 遇到异常情况会到这里
                             echo  "`basename  $0`  -[a  h  f  v]   -[c  value]  file"
                             ;;
                        esac
done


//注:  ./optgets   -a  -h  -c  ff





本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
shell编程规范及变量
Linux eval命令
shell学习系列(四).输入输出
Linux常用命令(非常详细!)
《shell编程指南》读书笔记(二)——通配符,标准输入,输出及重定向
shell export 作用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服