linux shell 学习心得

第一章:shell 基础
umask  -- 查看当前用户创建文件或文件夹时的默认权限
eg
[test@szbirdora 1]$umask
0002
[test@szbirdora 1]$ls -lh
-rw-rw-r--    test test  myfile   
drwxrwxr-x    test test 1

上面的例子中我们看到由test 默认创建的文件myfile 和文件夹1 的权限分别为664775.而通过umask查到的默认权限为002.所以可以推断出umask的计算算法为:
umask                 file                     directory
                                                   7
                                                    6
                                                   5
                                                   4
                                                    3
5      1          2
6      0          1 
7       0            0

连接ln
硬连接 ln sourcefile targetfile                 连接后的target 文件大小和source 文件一样
软连接 ln -s sourcefile targetfile              类似于windows 的快捷方式

shellscript基本结构
#
/bin/bash
                         --------bash shell开头必须部分
# description
                         --------注释部分(可有可无,为了阅读方便最好加以说明)
variable name=value
            ---------变量部分,声明变量,赋值
control segment
                   ---------流程控制结构,如判断、循环、顺序
eg.
helloworld.sh
#! /bin/bash
# This is a helloworld shell script
printchar = "hello world"
echo $printchar

[test@szbirdora 1]$shhelloworld.sh
hello world


shell特性
别名         alias                 eg.alias ll =ls-l
管道          a| b                  a 命令的输出作为b 命令的输入eg. ls |sort  ls列举的项排序
命令替换  a` b`               b 命令的输出作为a 命令的输入 eg.    ls `catmyfile`列举出cat myfile 的输出项
后台运行  nohup command&   可通过jobs -l查看后台运行的脚本
重定向       >,<                     可以改变程序运行的输出来源和输入来源
变量                                      可以用$varname来调用变量
特殊字符
                                        `用来替换命令
                   /用来使shell 无法认出其后的特殊字符,使其失去特殊含义
                   允许一行放多个命令
                   ()创建成组的命令  ??
                   {}创建命令块      ??    

第二章:变量和运算符

本地变量:在用户现在的shell 生命期的脚本中使用。设置变量various_name=value.可用set 来查看。用readonly 可以使变量只读
环境变量:用于当前用户下所有用户进程(不限于现在的shell )。
                     设置变量:exportvarious_name=valueenv查看
                     readonly可以使变量只读。
变量替换   
echo ${variable name}
                  显示实际值到variable name
echo ${variablename:+value}    如果设置了variable name ,则显示其值,否则为空
echo ${variablename:?value}    如果未设置variable name ,则显现用户定义错误信息value
echo ${variable name:-value}
     如果未设置,则显示其值
echo ${variable name:=value}
     如果未设置,则设置其值,并显示
清除变量                                    unset variable name
位置变量
位置变量表示$0,$1,$2...$9
$0 ---- 脚本名字
$1
----根据参数位置表示参数1
eg.
#! /bin/bash
#parm.sh
echo "This is script name : $0"
echo "This is parameter 1: $1"
echo "This is parameter 2: $2"
[test@szbirdora 1]$sh parm.sh a b
This is script name : parm.sh
This is parameter 1: a
This is parameter 2: b

向系统中传递位置变量
#!/bin/bash
#parm.sh
find /u01/test/1 -name $1 -print
[test@szbirdora 1]$ sh parm.sh myfile
/u01/test/1/myfile

标准变量                              bash默认建立了一些标准环境变量,可在/etc/profile 中定义
EXINIT
HOME
IFS
LOGNAME
                                      --当前登录用户名
MAIL
MAILPATH
PATH
TERM
                                              --终端信息
TZ
                                                  --时区
PS1
                                                --登录提示,如[test@szbirdora 1]$
[test@szbirdora 1]$ echo $PS1
[/u@/h /W]/$
                                   --/u -user --/h -host --/W -document
PS2                                                --一命令多行,换行提示,>
PWD
                                               --当前目录
MAILCHECK                                   --每隔多少秒检查是否有新邮件
[test@szbirdora 1]$ echo$MAILCHECK
60
SHELL
MANPATH
                                      --帮助文档位置
TERMINFO
                                    --终端信息
特殊变量
$#          传递到脚本的参数个数
$*          以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9
$$          脚本运行的当前进程ID
$!          后台运行的最后一个进程的进程ID
$@         传递到脚本的参数列表,并在引号中返回每个参数
$-          显示shell 使用的当前选项,与set 命令功能相同
$?         显示最后命令的退出状态,0 表示没有错误,其他表示有错误
eg.
#!/bin/bash
#parm
echo "this is shellname: $0"
echo "this is parm1 :
   $1"
echo "this is parm2 :
   $2"
echo "show parm number : $#"
echo "show parm list :
  $*"
echo "show process id:
  $$"
echo "show precomm stat: $?"
[test@szbirdora1]$ sh parm.sh a b
this is shellname: parm.sh
this is parm1 :
   a
this is parm2 :
   b
show parm number : 2
show parm list :
   a b
show process id:
   24544
show precomm stat: 0
影响变量的命令
declare
设置或显示变量
     -f    只显示函数名
      -r   创建只读变量
     -x    创建转出变量
      -i   创建整数变量
     使用+ 替代- ,可以颠倒选项的含义
export
     -p  显示全部全局变量
shift[n]
   移动位置变量,调整位置变量,使$3 赋予$2, 使$2赋予$1    n前移n
typeset
    declare 同义

注意: 双引号不能解析$,/,` 三个字符,所以在双引号中可以引用变量、转义字符、替换变量
单引号可以解析,所以单引号中引用变量等无效

[test@szbirdora 1]$ echo"$test"
test
[test@szbirdora 1]$ echo '$test'
$test

运算符类型
按位运算符
~    取反
<<   左移运算符
>>   右移运算符
&    
|     
^     异或
$[ ]   表示形式告诉shell 对方括号中表达式求值$[a+b]
2.
逻辑运算符
&&
||
>,<,=,!=
3.
赋值运算符
let variablename1 +=variablename1+ varablename2

第三章 shell 的输入和输出
1. echo   echo [option] string
           -e
解析转移字符
          -n
回车不换行,linux系统默认回车换行
           
转移字符 /c /t /f /n
#!/bin/bash
#echo
echo -e "this echo's 3 newlne/n/n/n"
echo "OK"
echo
echo "this is echo's 3 ewline/n/n/n"
echo "this log file have all beendone">mylogfile.txt
[test@szbirdora ~]$ sh echod.sh
this echo's 3 newlne

OK

thisis echo's 3 ewline/n/n/n
上面可以看到有-e 则可以解析转移字符,没有不能解析。echo 空输出为空

2. read 可以从键盘或文件的某一行文本中读入信息,并将其赋给一个变量
read variable1 variable2
eg.
#!/bin/bash
#readname
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo "this name is $firstname $lastname"

3. cat       显示文件的内容,创建内容,还可以显示控制字符
           cat[options]filename1 filename2
                  
-v  显示控制字符(Windows 文件)
            cat命令不会分页显示,要分页可以采用moreless

4. 管道|

5. tee     把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中, 一般与管道合用
             
tee[options] files
             -a在文件中追加
eg.
[test@szbirdora 1]$ echo |tee myfile

[test@szbirdora 1]$ cat myfile

myfile 文件置空

6. 文件重定向
command>filename                                       ---
覆盖输出
command>>filename                                     ---
追加输出
command>filename>&1                                ---
把标准输出和标准错误重定向
command<<delimiter                                    ---
输入直到delimiter分解符
command<filename                                       ----
输入文件内容到命令
command<-
                                                    --- 关闭标准输入
>nullfile.txt                                                      ---
创建字节为0的文件
command1<filename>command3              ---
按从左到右顺序执行
eg.
说明:myfile 为空间
[test@szbirdora 1]$df -lh>myfile
[test@szbirdora 1]$ cat myfile
Filesystem           Size Used Avail Use% Mounted on
/dev/sda1             20G 3.3G   16G 18% /
none                 2.0G    0 2.0G   0% /dev/shm
/dev/sda2             79G  17G   59G 23% /u01
/dev/sda4             28G 3.9G   22G 15% /u02
[test@szbirdora 1]$
df-lh>myfile
[test@szbirdora 1]$ cat myfile
Filesystem           Size Used Avail Use% Mounted on
/dev/sda1             20G 3.3G   16G 18% /
none                 2.0G    0 2.0G   0% /dev/shm
/dev/sda2             79G  17G   59G 23% /u01
/dev/sda4             28G 3.9G   22G 15% /u02
[test@szbirdora 1]$
df-lh>>myfile
[test@szbirdora 1]$ cat myfile
Filesystem           Size Used Avail Use% Mounted on
/dev/sda1             20G 3.3G   16G 18% /
none                 2.0G    0 2.0G   0% /dev/shm
/dev/sda2             79G  17G   59G 23% /u01
/dev/sda4             28G 3.9G   22G 15% /u02
Filesystem           Size Used Avail Use% Mounted on
/dev/sda1             20G 3.3G   16G 18% /
none                 2.0G    0 2.0G   0% /dev/shm
/dev/sda2             79G  17G   59G 23% /u01
/dev/sda4             28G 3.9G   22G 15% /u02
[test@szbirdora 1]$
cat>>myfile<<exit
> China
> Hubei
> Suizhou
> exit
[test@szbirdora 1]$ cat myfile
China
Hubei
Suizhou

7 . exec        可以用来替代当前shell 。现有任何环境变量都会清除

第四章控制流结构
1.if语句
if 条件 1
then
    
命令 1
elif
条件2
then
    
命令 2
else
    
命令 3
fi
------------------
if
条件
then
命令
fi
eg
#!/bin/bash
#if test
#this is a comment line
if [ "10" -lt "12" ];then
#yes 10 is less than 12
echo "yes,10 is less than 12"
else
echo "no"
fi

注意: if 语句必须以 fi 终止
   "10"
前一个 空格 “12” 后也有一个 空格 。这个条件都是通过 test 命令来指定。条件表达为 test expression 或者 [expression]

条件表达式中的比较函数
man test
NAME
      test - check file types and compare values

SYNOPSIS
      test EXPRESSION
      [ EXPRESSION ]
      [ OPTION

DESCRIPTION
      Exit with the status determined by EXPRESSION.

      --help display this help and exit

      --version
             output version information and exit

      EXPRESSION is true or false and sets exit status. It is oneof:

      ( EXPRESSION )
             EXPRESSION is true

      ! EXPRESSION
             EXPRESSION is false

      EXPRESSION1 -a EXPRESSION2
             both EXPRESSION1 and EXPRESSION2 are true

      EXPRESSION1 -o EXPRESSION2
             either EXPRESSION1 or EXPRESSION2 is true

      [-n] STRING
             the length of STRING is nonzero

      -z STRING
             the length of STRING is zero

      STRING1 = STRING2
             the strings are equal

      STRING1 != STRING2
              the strings are not equal

      INTEGER1 -eq INTEGER2
             INTEGER1 is equal to INTEGER2

      INTEGER1 -ge INTEGER2
             INTEGER1 is greater than or equal to INTEGER2

      INTEGER1 -gt INTEGER2
             INTEGER1 is greater than INTEGER2

      INTEGER1 -le INTEGER2
             INTEGER1 is less than or equal to INTEGER2

      INTEGER1 -lt INTEGER2
             INTEGER1 is less than INTEGER2

      INTEGER1 -ne INTEGER2
             INTEGER1 is not equal to INTEGER2

      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
      -g FILE
             FILE exists and is set-group-ID

      -h FILE
             FILE exists and is a symbolic link (same as -L)

      -G FILE
             FILE exists and is owned by the effective group ID

      -k FILE
             FILE exists and has its sticky bit set

      -L FILE
             FILE exists and is a symbolic link (same as -h)

      -O FILE
             FILE exists and is owned by the effective user ID

      -p FILE
             FILE exists and is a named pipe

      -r FILE
             FILE exists and is readable

      -s FILE
             FILE exists and has a size greater than zero

      -S FILE
             FILE exists and is a socket

      -t [FD]
             file descriptor FD (stdout by default) is opened on aterminal

      -u FILE
             FILE exists and its set-user-ID bit is set

      -w FILE
             FILE exists and is writable

      -x FILE
            FILE exists and is executable

eg.
#!/bin/bash
#if test
#this is a comment line
echo "Enter your filename:"
read myfile
if [ -e $myfile ]
then
   if [ -s $myfile ];then
    echo"$myfile exist and size greater than zero"
   else
    echo"$myfile exist but size is zero"
   fi
else
echo "file no exist"
fi
[test@szbirdora 1]$ sh iftest.sh
Enter your filename:
11
11 exist but size is zero

2.case 语句
case
语句为多选择语句。
case in
模式1
   
命令1
   ;;
模式2)
   
命令2
    ;;
esac
eg.
#!/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"
;;
*)
echo "`basename $0`:this is not between 1 and3">&2
exit;
;;
esac

3.for 循环
for
循环一般格式:
for 变量名in 列表 ( 列表以空格作为分割)
do
  
命令1
  
命令2
done

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

4.until 循环
until 条件
do
  
命令1
  
命令2
   ...
done

条件测试发生在循环末尾,所以循环至少可以执行一次。

5.
while
循环
while
命令 (可以是一个命令也可以是多个,做条件测试)
do
     
命令1
     
命令2
     ...
done
注意:如果从文件中读入变量<filename 要放到done

6.break continue 控制
break 跳出,continue 跳过

第五章文本过滤

1.
正则表达式

一种用来描述文本模式的特殊语法,由普通字符以及特殊字符(元字符)组成
^    ----
只匹配行首
$    ----
只匹配行尾
*    ----
匹配0 个或多个此单字符
[]   ----
只匹配[] 内字符,可以使用- 表示序列范围[1-5]
/    ----
屏蔽一个元字符的特殊含义
.    ----
匹配任意单字符
pattern/{n/}
只用来匹配前面pattern出现的次数,n 为次数
pattern/{n
/}只用来匹配前面pattern出现的次数,至少为n
pattern/{n
m/} 只用来匹配前面pattern 出现的次数,次数在n-m 之间

eg
A/{3/}B   AAAB
A/{3,/}B AAAB AAAAB ...
A/{3,5/}B AAAB AAAAB AAAAAB

2.find命令    ---- 查找文件和目录
findpathname -options [-print -exec -ok]
pathname --
查找的目录路径. .-- 表示当前目录,/ 表示根目录
-print
输出
-exec
对匹配的文件执行该参数所给出的shell 命令,相应命令形式'command'{}/;'   注意{}/; 之间的空格
-ok   
-exec相同,不过执行命令前会有提示
options  

-name
-perm
-user
-group
-mtime -n +n (atime,-ctime)
修改时间(访问时间,创建时间)
-size n[c]
-type
查找某一类型的文件
eg.
[test@szbirdora 1]$ find ./ -mtime+5
./helloworld.sh
./nohup.out
查看./目录(当前)下修改时间超过5天的文件

3.grep
介绍
grep -c
输出匹配行计数
grep -i
不区分大小写
grep -h
查询多文件时不显示文件名
grep -H
显示文件名
grep -l
查询多文件时只输出包含匹配字符的文件名
grep -n
显示匹配行及行号
grep -s
不显示不存在或不匹配文本的错误信息
grep -v
显示不包含匹配文本的所有行(过滤文本)

eg.
[test@szbirdora 1]$ grep -n 's.a' myfile
2:/dev/sda1             20G 3.3G   16G 18% /
4:/dev/sda2             79G  18G   58G 23% /u01
5:/dev/sda4             28G 3.9G   22G 15% /u02
[test@szbirdora 1]$ grep -n '2$' myfile
5:/dev/sda4             28G 3.9G   22G 15%/u02
grep -options ' 正则表达式'filename

4.sed 介绍
sed
不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件将输出到屏幕
sed
是一种重要的文本过滤工具,使用一行命令或使用管道与grepawk相结合。
sed
调用:
1.
命令
sed [options] ' 正则表达式sedcommand'input-files
2.script : sed [options] -fsedscript input-files

sed在文本中查询文本的方式
   -
行号,可以是简单数字,或一个行号范围
   -
使用正则表达式
x ----
行号
x,y ----
行号范围从xy
x,y! ---
不包含行号xy

sed命令选项:
-n
不打印
-c
下一个命令是编辑命令
-f
如果正在调用sed脚本文件

基本sed 命令
p
打印匹配行
=
显示文本行号
a/
在定位行号后附加新文本信息
i/
在定位行号前插入新文本信息
d
删除定位行
c/
用新文本替换定位文本
s
使用替换模式替换相应模式
r
从另一个文件中读文本
w
写文本到一个文件
q
第一个模式匹配完成后退去
l
显示与八进制ascii代码等价的控制字符
{}
在定位行执行命令组
n
从一个文件中读文本下一行,并附加在下一行
g
将模式2粘贴到/pattern n/
y
传送字符

eg.
[test@szbirdora 1]$ sed -n '2p' myfile
c

打印myfile2
[test@szbirdora 1]$ sed -n '2,4p' myfile
c
f
b

打印第二行到第四行
[test@szbirdora 1]$ sed -n '/a/p' myfile
a

打印匹配a 的行

[test@szbirdora 1]$ sed -n '2,/2/p'myfile
c
f
b
1
2

打印第二行到匹配'2' 的行

s命令替换
[test@szbirdora 1]$ sed 's/b/a/p' myfile
a
a
a
c
d
e
替换ba

多点编辑 -e
eg.myfile 包含a-e
[test@szbirdora 1]$ sed -e '2d' -e 's/c/d/' myfile11
a
d
d
e

sed命令r ---从文件中读取选定的行,读入输入文件中,显示在匹配的行后面
eg.
[test@szbirdora 1]$ cat 11
*******************Alaska***************
[test@szbirdora 1]$ sed '/a/r 11' myfile
a
*******************Alaska***************
b
c
d
e

写入命令: 将输入文件中的匹配行写入到指定文件中
eg.
[test@szbirdora 1]$ cat 11
b
[test@szbirdora 1]$ sed -n '/a/w 11' myfile
[test@szbirdora 1]$ cat 11
a

追加:a  将文本追加到匹配行的后面。sed 要求在a 后加/,不止一行的以/ 连接
eg.
[test@szbirdora 1]$ sed '/b/a-------------china---------'myfile
a
b
****************hello*************-------------china---------
c
d
e

插入命令: 将文本插入到匹配行的前面。sed要求在a 后加/, 不止一行的以/ 连接
eg.
[test@szbirdora 1]$ sed '/b/i/
> THE CHARACTER B IS BEST/
> *******************************' myfile
a
THE CHARACTER B IS BEST
*******************************
b
c
d
e

下一个:n 从一个文件中读文本下一行,并附加在下一行

退出命令 q打印多少行后退出
eg.
[test@szbirdora 1]$ sed '3q' myfile
a alert
b best
c cook

sed script:
sed -f scriptfile myfile

5.awk
介绍
awk
可从文件或字符串值基于指定规则浏览和抽取信息
awk
三种调用方式:
1.
命令行方式
awk [-F field-sperator]'pattern{active}'input-files
awk [-F field-sperator]'command' input-files
awk
脚本
所有awk 命令插入一个文件,并使awk 程序可执行,然后用awk 命令解析器作为脚本的首行,以便通过键入脚本名称来调用。
awk
命令插入一个单独文件
awk -f awk-script-file input-files

awk脚本由模式和动作组成
分隔符、域、记录

注意这里的$1,$2 是域与位置变量$1,$2 不一样。$0 文件中的所有记录

eg
awk '{print $0}' myfile
awk 'BEGIN {print "IP DATE ----"}{print $1"/t"$4}END{print "end-of-report"}
[test@szbirdora 1]$ df |awk '$1!~"dev"'|grep -v Filesystem
none                  1992400         1992400   0% /dev/shm
[test@szbirdora 1]$ df |awk '{if ($1=="/dev/sda1") print $0}'
/dev/sda1            20641788   3367972 16225176 18%/

[test@szbirdora shelltest]$ cat employee
TomJones      4424    5/12/66543354
MaryAdams     5346    11/4/6328765
SallyChang    1654    7/22/54650000
BillyBlack    1683    9/23/44336500
[test@szbirdora shelltest]$ awk '/[Aa]dams/'employee
MaryAdams     5346    11/4/6328765
[test@szbirdora shelltest]$ sed -n '/[Aa]dams/p'employee
MaryAdams     5346    11/4/6328765

[test@szbirdora shelltest]$ grep '[Aa]dams'employee
MaryAdams     5346    11/4/6328765
三种命令方式下,使用模式匹配查询

[test@szbirdora shelltest]$ awk '{print $1}'employee
Tom
Mary
Sally
Billy

打印文件第一列

[test@szbirdora shelltest]$ awk '/Sally/{print$1"/t"$2}' employee
Sally   Chang
打印匹配Sally 的行的第一列和第二列

[test@szbirdora shelltest]$ df |awk'$4>20884623'
Filesystem          1K-blocks     Used Available Use% Mounted on
/dev/sda2            82567220 17488436 60884616 23% /u01
/dev/sda4            28494620   4589172 22457992 17%/u02
打印df 输出第四列大于×× 的行

格式输出:
打印函数
[test@szbirdora shelltest]$ date
Mon Mar 10 15:15:47 CST 2008
[test@szbirdora shelltest]$ date |awk '{print "Month:" $2"/nYear:"$6}'
Month:Mar
Year:2008
[test@szbirdora shelltest]$ awk '/Sally/{print "/t/tHave a niceday,"$1"/t"$2}' employee
               Have a nice day,Sally  Chang

printf函数
[test@szbirdora shelltest]$ echo "LINUX"|awk'{printf "|%-10s|/n",$1}'
|LINUX    |
[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf"|s|/n",$1}'
   LINUX|


~匹配符
[test@szbirdora shelltest]$ awk '$1~/Tom/{print$1,$2}' employee
Tom Jones

awk给表达式赋值
关系运算符:
           
小于   
           
大于
==          
等于
!=           
不等于
>=          
大于等于
<=          
小于等于
            
匹配
!~           
不匹配
eg.
[test@szbirdora shelltest]$ cat employee
TomJones      4424    5/12/66543354
MaryAdams     5346    11/4/6328765
SallyChang    1654    7/22/54650000
BillyBlack    1683    9/23/44336500
[test@szbirdora shelltest]$
awk '$2~/Adams/' employee
MaryAdams     5346    11/4/6328765

条件表达式:
condition  expression1?expression2:expression3
eg.
awk '{max=($1>$2) ? $1:$2;printmax}' filename

运算符
+
-*/,%,^,&&,||,!

[test@szbirdora shelltest]$ cat /etc/passwd |awk-F: '/
NF!=7{/
printf("line %d does not have 7 fields:%s/n",NR,$0)}/
$1!~/[A-Za-z0-9]/{printf("line %d,nonalphanumberic userid:%s/n",NR,$0)}/
$2=="*"{printf("line %d,no password:%s/n",NR,$0)}'

awk编程
递增操作符 x++++x
递减操作符 x----x

BEGIN
模块
BEGIN
模块后面紧跟着动作块,在读入文件前执行。通常被用来改变内建变量的值,如:FS/RS/OFS, 初始化变量的值和打印输出标题。
[test@szbirdora shelltest]$ awk 'BEGIN{print"HELLO WORLD"}'
HELLO WORLD
[test@szbirdora shelltest]$ awk 'BEGIN{print"---------LIST---------"}{print}END{print "------END--------"}'donors
---------LIST---------
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50
Archie McNichol:(206) 548-1348:250:100:175
Jody Savage:(206) 548-1278:15:188:150
Guy Quigley:(916) 343-6410:250:100:175
Dan Savage:(406) 298-7744:450:300:275
Nancy McNeil:(206) 548-1278:250:80:75
John Goldenrod:(916) 348-4278:250:100:175
Chet Main:(510) 548-5258:50:95:135
Tom Savage:(408) 926-3456:250:168:200
Elizabeth Stachelin:(916) 440-1763:175:75:300
------END--------

重定向和管道
输出重定向
awk
输出重定向到一个文件需要使用输出重定向符,输出文件名需要用双引号括起来。
[test@szbirdora shelltest]$awk -F: '{print $1,$2>"note"}'donors
[test@szbirdora shelltest]$ cat note
Mike Harrington (510) 548-1278
Christian Dobbins (408) 538-2358
Susan Dalsass (206) 654-6279
Archie McNichol (206) 548-1348
Jody Savage (206) 548-1278
Guy Quigley (916) 343-6410
Dan Savage (406) 298-7744
Nancy McNeil (206) 548-1278
John Goldenrod (916) 348-4278
Chet Main (510) 548-5258
Tom Savage (408) 926-3456
Elizabeth Stachelin (916) 440-1763


输入重定向
getline
函数
[test@szbirdora shelltest]$ awk 'BEGIN{"date+%Y"|getline d;print d}'
2008

[test@szbirdora shelltest]$
awk -F"[ :]" 'BEGIN{printf "What is yourname?";/
getline name<"/dev/tty"}/
$1~ name{print "Found/t" name "/ton line",NR"."}/
END{print "see ya," name "."}' donors

What is your name?Jody
Found  Jody    on line5.
see ya,Jody.

[test@szbirdora shelltest]$ awk'BEGIN{while(getline<"/etc/passwd">0)lc++;printlc}'
36
从文件中输入,如果得到一个记录,getline 函数就返回1 ,如果文件已经到了末尾,则返回0 ,如果文件名错误则返回-1.

管道:
awk
命令打开一个管道后要打开下一个管道需要关闭前一个管道,管道符右边可以使用“” 关闭管道。在同一时间只有一个管道存在
[test@szbirdora shelltest]$ awk '{print$1,$2|"sort -r +1 -2 +0 -1"}' names
tony tram
john smith
dan savage
john oldenrod
barbara nguyen
elizabeth lone
susan goldberg
george goldberg
eliza goldberg
alice cheba
|后用"" 关闭管道

system
函数
system
"LINUXcommand"
system("cat" $1)
system("clear")

条件语句
1.if
(){}
2.if(){}
else{}
3.if(){}
else if(){}
else if(){}
else{}
[test@szbirdora shelltest]$ awk -F: '{if($3>250){printf "%-2ss/n",$1,"-----------goodpartman"}else{print $1}}' donors

循环语句
[test@szbirdora shelltest]$ awk -F:'{i=1;while(i<=NF){print NF,$i;i++}}' donors
循环控制语句breakcontinue

程序控制语句
next
从输入文件中读取下一行,然后从头开始执行awk 脚本
{if($1~/Peter/){next}
else{print}}

exit结束awk 语句,但不会结束END 模块的处理。

数组:
awk'{name[x++]=$1;for(i=0;i<NR;i++){print i,name[i]}}'donors

(P177)---2008.3.11

awk
内建函数
sub
(正则表达式,替换字符[$n]---n 匹配正则表达式的字符串将被替换。
[test@szbirdora shelltest]$ awk'{sub(/Tom/,"Jack",$1);print}' employee
Jack Jones 4424 5/12/66 543354
MaryAdams     5346    11/4/6328765
SallyChang    1654    7/22/54650000
BillyBlack    1683    9/23/44336500
Jack He 3000 8/22/44 320000

index函数index (字符串,子字符串)子字符串在字符串中的位置
[test@szbirdora shelltest]$ awk'BEGIN{a=index("hello","llo");print a}'
3

length函数lengthstring ) 字符串的长度
[test@szbirdora shelltest]$ awk'BEGIN{a=length("hello world");print a}'
11

substr函数substr (字符串,开始位置[ ,子字符串长度]
[test@szbirdora shelltest]$ awk'BEGIN{a=substr("hello world",7);print a}'
world
[test@szbirdora shelltest]$ awk 'BEGIN{a=substr("helloworld",7,3);print a}'
wor


match(string,
正则表达式) 找出字符串中第一个匹配正则表达式的位置, 其内建变量RSTART 为匹配开始位置,RLENGTH 为匹配开始后字符数
[test@szbirdora shelltest]$ awk'{a=match($0,/Jon/);if (a!=0){print NR,a}}' employee
1 5
[test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){printNR,a,RSTART,RLENGTH}}' employee
1 5 5 3

touppertolower 函数
[test@szbirdora shelltest]$ awk'BEGIN{a=toupper("hello");print a}'
HELLO

split函数splitstring,array,fieldseperator
[test@szbirdora shelltest]$ awk 'BEGIN{"date"|getlined;split(d,date);print date[2]}'
Mar

时间函数
systime
() ----1970年1月1到当前忽略闰年得出的秒数。
strftime(
格式描述,时间戳)
[test@szbirdora shelltest]$ awk'BEGIN{d=strftime("%T",systime());print d}'
13:08:09
[test@szbirdora shelltest]$ awk'BEGIN{d=strftime("%D",systime());print d}'
03/12/08
[test@szbirdora shelltest]$ awk'BEGIN{d=strftime("%Y",systime());print d}'
2008

6.sort
介绍

sort
    -c
测试文件是否已经排序
    -m
合并两个排序文件
    -u
删除所有复制行
    -o
存储sort结果的输出文件名
    -t
域分隔符;用非空格或tab键分割域
    +n n
为域号,使用此域号开始排序   (注意0 是第一列)
    -r
逆序排序
    n
指定排序是域上的数字排序项
[test@szbirdora 1]$ df -lh|grep -v'Filesystem'|sort +1
none                 2.0G    0 2.0G   0% /dev/shm
/dev/sda1             20G 3.3G   16G 18% /
/dev/sda4             28G 3.9G   22G 15% /u02
/dev/sda2             79G  17G   59G 23% /u01

uniq [option]files从一个文本文件中去除或禁止重复行
    -u
只显示不重复行
    -d
只显示有重复数据行,每重复行只显示其中一行
    -c
打印每一重复行出现次数
    -f n
为数字,前n个域被忽略

注意要先排序

7.split cut join分割和合并文件命令
[test@szbirdora 1]$ split -l 2 myfilesplit  (每两行分割为一个以split 名称开头的文件)
[test@szbirdora 1]$ ls
case.sh df.out helloworld.sh iftest.sh myfile nohup.outnullfile.txt parm.sh splitaa splitab splitac splitad splitae
[test@szbirdora 1]$ cat splitaa
Filesystem           Size Used Avail Use% Mounted on
/dev/sda1             20G 3.3G   16G 18% /

第六章 shell 函数

1.
定义函数
funcation name()
{
   command1
   ....
}

函数名()
   {
   command1
   ...
   }
eg.

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

2. 函数调用
#!/bin/bash
#hellofun
function hello()
{
echo "hello,today is `date`"
return 1
}
echo "now going to the function hello"
hello
echo "back from the function"

所以调用函数只需要在脚本中使用函数名就可以了。

3. 参数传递
像函数传递参数就像在脚本中使用位置变量$1,$2...$9

4. 函数文件
函数可以文件保存。在调用时使用". 函数文件名"(.+ 空格+ 函数文件名)
如:
hellofun.sh
#!/bin/bash
#hellofun
function hello()
{
echo "hello,today is `date`"
return 1
}

func.sh
#!/bin/bash
#func
. hellofun.sh
echo "now going to the function hello"
echo "Enter yourname:"
read name
hello $name
echo "back from the function"

[test@szbirdora 1]$ sh func.sh
now going to the function hello
Enter yourname:
hh
hello,hh today is Thu Mar 6 15:59:38 CST 2008
back from the function

5. 检查载入函数 set
删除载入函数 unset 函数名

6. 函数返回状态值return 0return 1

7. 脚本参数的传递
shift
命令
shift n
每次将参数位置向左偏移n

#!/bin/bash
#opt2
usage()
{
echo "usage:`basename $0` filename"
}
totalline=0
if [ $# -lt 2 ];then
    usage
fi
while [$# -ne 0]
do
    line=`cat$1|wc -l`
    echo "$1 :${line}"
   totalline=$[$totalline+$line]
   shift                                $# -1
done
echo "-----"
echo "total:${totalline}"

[test@szbirdora 1]$ sh opt2.sh myfile df.out
myfile : 10
df.out : 4
-----
total:14


8.getopts
命令
获得多个命令行参数
getopts ahfvc OPTION   --
ahfvc一个一个读出赋值给OPTION.如果参数带有:则把变量赋值给:前的参数--:只能放在末尾。
该命令可以做获得命令的参数
#!/bin/bash
#optgets
ALL=false
HELP=false
FILE=false
while getopts ahf OPTION
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"
     ;;
    /?)
     echo "`basename $0` -[a h f] file"
     ;;
    esac
done

[test@szbirdora 1]$ sh optgets.sh -a -h -m
ALL is true
HELP is true
optgets.sh: illegal option -- m
optgets.sh -[a h f] file

getopts
表达式:
while getopts p1p2p3... var   do
    case varin
    ..)
    ....
   esac
done
如果在参数后面还需要跟自己的参数,则需要在参数后加:
如果在参数前面加:表示不想将错误输出
getopts
函数自带两个跟踪参数的变量:optindoptarg
optind
初始值为1,在optgets处理完一次命令行参数后加1
optarg
包含合法参数的值,即带:的参数后跟的参数值

前七章的部分知识在前面的linuxshell学习笔记中已经结合进去了。所以笔记从第八章开始。而且这本书的目录编排也是这样,第八章才开始正式涉及shell编程。
有了前面的学习,下面只记载一些在学习的过程中又忘了了一些知识点。所以记录是零散的。

1.
shopt bash2.0以上新的命令,功能和set类似。
给变量赋值时等号两边不可留空格。
环境变量一般使用大写。

2.
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 传递到脚本的参数列表,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态,0表示没有错误,其他表示有错误

3.
echo 命令中使用" "无法直接识别转义字符,必须使用选项 -e,但可以使用$和`引用变量和命令替换。
$[] 告诉shell对方括号中表达式求值 $[a+b],如$[1+8]

4.
tee
把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中
tee -afile      -----a表示在文件末尾追加,不要-a则覆盖
该命令一般与管道合用

5.
command>filename>&1---把标准输出和标准错误重定向
command<<delimiter---输入直到delimiter分解符
eg:
sqlplus / as sysdba <<EOF
show parameters
exit
EOF

6.命令替换有两种方式,老的korn风格的`linux command`和新的bash风格$(linux command)

7.定义数组
declare -a arry=(a1 a2 a3 ...)
echo ${a[n]}

8.read使用
read -aarryname    ---读入为数组
read -pprompt     ----输出提示,并把提示后的输入存到REPLY内建变量中
[test@szbirdora 1]$ read -p "Enter your name:"
Enter your name:jack
[test@szbirdora 1]$ echo $REPLY
jack

[test@szbirdora 1]$ read -a name
jack tom susan
[test@szbirdora 1]$ echo ${name[2]}
susan
[test@szbirdora 1]$ echo ${name[0]}
jack

9.多进制整型变量表示
declare -i number
number=base#number_in_the_base
如:
declare -i number
number=2#101
number=16#A9

10.条件语句if thenfi中if后的表达式可以是条件表达式(布尔表达式)或一组命令,如果是布尔表达式则表达式为真执行then后的语句,如果是命令组,则命令组状态($?)为0执行then后面的语句。但如果是Cshell则if后只能跟布尔表达式。


11.here文档和case建立菜单:
eg.
echo "Select a terminal type:"
cat <<EOF
1) linux
2)xterm
3)sun
EOF
read choice
case $choice in
1)TERM=linux
   export TERM
   ;;
2)TERM=xterm
   export TERM
;;
3)TERM=sun
   export TERM
;;
*) echo "please select correct chioce,ths!"
;;
esac
echo "TERM is $TERM"

12.循环比较:
for variable inwordlist;do    ---从文件或列表中给定的值循环
whilecommand;do      ----当command的返回值为0时做循环
untilcommand;do       ----当command的返回值不为0时作循环

select循环菜单
用select建立菜单,需要用PS3来提示用户输入,输入保存在REPLY内建变量中,REPLY的值与内建菜单关联。在构建菜单过程中可以使用COLUMNS和LINES两个变量,COLUMNS决定菜单的列宽度,LINES决定可显示的行数。select和case命令联用可以有效的构造循环菜单。
eg
#!/bin/bash
#Author: hijack
#Usage:Menu
t=0
j=0
d=0
PS3="Please choose one of the three boys or quit:"
select choice in Tom Jack David Quit
do
case $choice in
Tom)
t=$t+1
if (($t==5));then
echo "Tom win"
break
fi
;;
Jack)
j=$j+1
if (($j==5));then
echo "Jack win"
break
fi
;;
David)
d=$d+1
if (($d==5));then
echo "David win"
break
fi
;;
Quit) exit 0;;
*) echo "$REPLY is invalide choice"1>&2
   echo "Try again!"
;;
esac

done

[test@szbirdora 1]$ sh menu
1) Tom
2) Jack
3) David
4) Quit
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:2
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Tom win
  12.set 设置位置变量,shift移动位置变量。
set tom jack david -----$1 tom $2 jack $3 david
echo $*
tom jack david
shift2                    -----移动两个位置,$1,$2删除
echo $*
david
eg:
#!/bin/bash
#Name:shift
#Author : Hijack
#Usage:shift test
#Date:080320
while (($#>0))
do
    echo"$*"
    shift
done

[test@szbirdora 1]$ ./shift 1 2 3 4 5 6 7
1 2 3 4 5 6 7
2 3 4 5 6 7
3 4 5 6 7
4 5 6 7
5 6 7
6 7
7

13。 break n   ---n代表退出第几层循环,默认退出一层。continue n 类似
#!/bin/bash
#Name   : Mulloop
#Author : Hijack
#Usage : break test
declare -i x=0
declare -i y=0
while true
do
while (( x<20 ))
do
   x=$x+1
   echo $x
   if (( $x==10 ));then
    echo"if"
    break
   fi
done
echo "loop end"
y=$y+1
if (($y>5));then
   break
fi
done

[test@szbirdora 1]$ sh mulloop
1
2
3
4
5
6
7
8
9
10
if
loop end
11
12
13
14
15
16
17
18
19
20
loop end
loop end
loop end
loop end
loop end

#!/bin/bash
#Name   : Mulloop
#Author : Hijack
#Usage : break test
declare -i x=0
declare -i y=0
while true
do
while (( x<20 ))
do
   x=$x+1
   echo $x
   if (( $x==10 ));then
    echo"if"
    break2
   fi
done
echo "loop end"
y=$y+1
if (($y>5));then
   break
fi
done

[test@szbirdora 1]$ sh mulloop
1
2
3
4
5
6
7
8
9
10
if

14.循环的IO重定向
使用">","|"等重定向符实现循环的IO重定向
如 while ;do
     done >temp$$

    for in
    do
    done|sort
eg
给文件的每行加一个行号,写入文件中
#!/bin/bash
#Name    :loopred
#Author : Hijack
#Usage   : add linenum to thefile
#Program : read line to loop from file,add linenum,output totempfile,mv tempfile to file
declare -i count=0
declare -i total=0
total=`sed -n "$=" $1`
cat $1 | while read line
do
   (($count==0))&& echo -e "Processingfile $1...../n"> /dev/tty
   count=$count+1
    echo -e"$count/t$line"
   (($count==$total))&& echo "Processfinish,total line number is $count" > /dev/tty
done >temp$$
mv temp$$ $1

[test@szbirdora 1]$ sh loopred testmv
Processing file testmv.....

Process finish,total line number is 19
[test@szbirdora 1]$ vi testmv

     /u01/test
     /u01/test/1
     /u01/test/1/11
     /u01/test/1/forlist.sh
     /u01/test/1/optgets.sh
     /u01/test/1/whiletest.sh
     /u01/test/1/func.sh
     /u01/test/1/helloworld.sh
     /u01/test/1/df.out
10     /u01/test/1/nullfile.txt
11     /u01/test/1/iftest.sh
12     /u01/test/1/myfile
13     /u01/test/1/opt2.sh
14     /u01/test/1/0
15     /u01/test/1/case.sh
16     /u01/test/1/nohup.out
17     /u01/test/1/hellfun.sh
18     /u01/test/1/parm.sh
19     /u01/test/1/test

15。在done后面加&使循环在后台运行,程序继续执行。

16.在函数内可以使用local定义本地变量,local variable。


17.陷阱信号 trap --当一个信号发出传递给进程时,进程进行相关操作,信号包括中断等
    trap ‘command;command’signal-num                         #trap设置时执行命令
    trap “command;command”signal-num                        #信号到达时执行命令
eg:
[root@linux2 ~]# trap "echo -e 'helloworld/n';ls -lh" 2
[root@linux2 ~]# helloworld

total 100K
-rw-r--r-- 1 root root 1.4K Nov 14 16:53 anaconda-ks.cfg
drwxr-xr-x 2 root root 4.0K Nov 23 13:11 Desktop
-rw-r--r-- 1 root root 53K Nov 14 16:53 install.log
-rw-r--r-- 1 root root 4.9K Nov 14 16:53 install.log.syslog
drwxr-xr-x 2 root root 4.0K Nov 22 13:03 vmware


附:
shell 字符串处理汇总(查找,替换等等)
Shell中的数组

开源书籍: Shell 编程范例系列

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shell脚本成分 开头和注释: shell脚本的开头,用来解释shell程序,包括:#!/bin/bash、#!/bin/csh、#!/bin/tcsh、#!/bin/pdksh,一般用#!/bin/bash。。 shell脚本中的注释,以#开头的句子表示注释。 变量: 变量的赋值和引用 在shell编程中变量没有类型,简称弱类型编程语言,不需要声明,在引用这个变量时会创建它(在变量名前加$符号引用变量的值)。在定义变量时,若String中包含空格、制表符、换行符,需用单(双)引号,双引号内允许变量替换,而单引号内就不可以。 shell变量的作用域 可以用export内置命令将局部变量设置为全局变量。 位置变量 用于向shell脚本传递信息。参数相关数目传入脚本,此数目任意多,但只有前9个可以被访问,使用shift命令可以改变限制。其中,$0:脚本名字。 特定变量参数 $#:传递到脚本的参数个数;$*:以一个单字符串显示所有项脚本传递的参数。与位置变量不通,此选项参数可超过9个;$$:脚本运行的当前进程ID号;&!:后台运行的最后一个进程的进程ID号;$@:与$#相同,但是使用时加引号,并在引号中返回每个参数;$-:显示shell使用的当前选项,与set命令功能相同;$?:显示最后命令的退出状态(0表示没有错误,其他任何值表明有错误。)。 变量的规则 1.变量与变量内容以一个等号『=』来连结,如下所示『myname=VBird』 2.等号两边不能直接接空格符,如下所示为错误:『myname = VBird』或『myname=VBird Tsai』 3.变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:『2myname=VBird』 "4.变量内容若有空格符可使用双引号『""』或单引号『'』将变量内容结合起来,但 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:『var=""lang is $LANG""』则『echo $var』可得『lang is en_US』 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』" 5.可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, \, 空格符, '等)变成一般字符; "6.在一串命令中,还需要藉由其他的命令提供的信息,可以使用反单引号『`命令`』或 『$(命令)』 特别注意:那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号! 例如想要取得核心版本的配置:『version=$(uname -r)』再『echo $version』可得『2.6.18-128.el5』" "7.若该变量为扩增变量内容时,则可用 ""$变量名称"" 或 ${变量} 累加内容,如下所示: 『PATH=""$PATH"":/home/bin』" 8.若该变量需要在其他子程序运行,则需要以 export 来使变量变成环境变量:『export PATH』 9.通常大写字符为系统默认变量,自行配置变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ; 10.取消变量的方法为使用 unset :『unset 变量名称』例如取消 myname 的配置:『unset myname』

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值