一.一些小知识
  1.elinks文本浏览器
    wget下载工具
    lftp 基于字符界面的ftp工具
    lftpget 支持ftp,http,shttp的下载工具

二.管理用户
   1.本地用户相关信息存储在/etc/目录下
      passwd
      shadow
      group
      gshadow
 
    2.用户:分三类(系统识别用户,是根据UID来识别的)
      管理员:UID,0
      系统用户:UID,1-499
      普通用户:UID,>500
  
      用16bit来存储用户的ID号,rang:0-65535
  
    3.组:分三类
      私有组:
      公共组:
      系统组:
    用户:基本组,附加组 ----->用户一般可以有两个组

    4./etc/shells 文本中存放着可用的shell
 
    5.useradd
      -u 指定UID
      -g 指定GID
      -G 指定附加组
      -s 指定shell
      -d 指定家目录
      -M 不为用户创建家目录
      -m 强行创建家目录,与-k一块使用
      -c 写入注释信息
      -r 添加系统用户 uid(1-499)

   6.chsh user1  --->改变用户的shell
   7.usermod
     -u 改变UID
     -g 改变GID
     -a 加用户到附加组
     -G 该附加组,与-a一块使用
      eg:-Ga表示附加一个组,不会清除以前的附加组
       usermod -a -G group2 jack ----->将group2加入group2附加组
     -s 改shell
     -d 与-m一块用,eg:-dm表示,改变文件的同时,件它以前的文件也移过去。
     -l login_name  该用户的名字
     -c 修改注释信息
     -e 修改过期时间,格式:年月日
     -f 修改活动期限的(就是密码过期的宽限时间)
 
   8.md5(单向加密的,不可逆的,定长输出,特征码,雪崩效应,),salt(添加随机数的,以防输入密码相同时的,导

致两个人的密码相同)
     md5,128位
     sha1,160位(哈希算法,速度慢些)
 
  eg:john,12345该用户通过md5算法算后,再通过salt随机加入一些随机数,然后才放在/etc/passwd的文件中
 
     用户下次输入密码进入系统之登陆时,是通过md5再次计算一下,加上随机数与我们存储的比较一下,

   9.echo '123456' | passwd --stdin john  ------>这是一种非交互式创建密码的

   10.groupadd  添加组的
         -g GID
         -r ID(1-499)添加系统组的
         -n 改变组名的
   11.gpasswd   给组加密码的
    
   12.newgrp   ------>临时切换密码
      exit  ---->退出切换的组

三.文件里的小知识
  1./etc/shadow
   jack:!!:14968:0:99999:7::: 
   用户名:加密的密码:密码上次修改的时间(距1970.1.1的天数):密码最短使用期限:密码最长使用期限:警告时间:::
  2.passwd -x  ---->可以指定最长使用时间  

四.有关脚本定义选项的关键字getopts的信息(在我的小脚本文档里的第24有一定的应用)
  1.首先查看getopts的帮助信息
  2.getopts有三个内置变量,分别是:OPTIND,OPTARG,OPTERR
  3.解释这三个选项的用法:
    假如有一条命令: ./my.sh -a -b -c -d sss -e myfile  下面对这条命令解释
    OPTIND就索引,即指针:当我们读取第一个选项-a是,OPTIND就指向-a,当处理完了-a以后,就指向-b,依次下去
    OPTARG:当OPTIND指向到-d是,OPTARG就会调用-d的参数sss,
   
    问题是,我们写的小脚本,./my.sh怎么识别-a,-b等后面的选项呢?
    其实,我们的小脚本是靠变量来识别后面的选项的,就是将-a识别为$1,-b识别为$2,-c识别为$3,依次下去
    因为我们的脚本不能识别我们的选项是参数,还是选项,是靠getopts来区别的,所以我们的脚本依然将选项识别 

  为变量。

    按照上面的说,我们的文件myfile也被识别为变量了,这就不好了,就需要引用另一个命令shift了
    shift就是弹出$的,轮替的。下面的脚本给予演示:
    eg:#!/bin/bash
       #
       echo $1
       shift
       echo $1
     eg:# ./f.txt 1 d    //我们会发现这个小脚本会输出1和d,这就是我们所不接的地方了,原因就是shift的作用

   了,当第一个引用完之后,shift就将第一个踢掉,然后就引用第二个$1了。

    这时候,我们上面的./my.sh -a -b -c -d sss -e myfile 掉用就可以解释清楚了,我们命令里的选项都用$1来轮

   调了,

    现在又有一个大问题,当$1读到myfile时,shift就会将其踢掉,这是我们不愿看到的,怎么解决这个问题呢?
    以防OPTIND指到谁,就踢谁,我们定义为[OPTIND-1]来避免踢掉myfile,下面我们写一个小脚本,来解释:
   
   下面是我们的小脚本的改进过程和记录:
#!/bin/bash
#
let I=1     #计时器的变量
while read LINE; do    #read每一次只读一行
 echo "$I $LINE"
 let I++
done < $1    #$1就是让脚本后面跟一个参数


改进成:用一个变量来控制显示行号
#!/bin/bash
#
let LINENUM=1   #这个变量是来控制显示行号的
let I=1     #计时器的变量
while read LINE; do    #read每一次只读一行
 if [ $LINENUM -eq 1 ]; then
   echo "$I $LINE"
   let I++
 else
   echo "$LINE"
 fi
done < $1    #$1就是让脚本后面跟一个参数


改进:怎么用一个选项来控制显示行号
#!/bin/bash
#
let LINENUM=0   #这个变量是来控制显示行号的,初始值为0

while getopts ":n" SWITCH; do
  case $SWITCH in
  n)
   let LINENUM=1 ;;     #这里是用-n来给脚本控制行号的变量赋值
  \?)
    echo "Unkown options"
    exit 1 ;;
   esac
done                 #这上面的都是为了定义-n选项的

shift $[$OPTIND-1]   #这就是踢除-n选项,让$1指针指向后面跟的文件

let I=1              #计时器的变量
while read LINE; do    #read每一次只读一行
 if [ $LINENUM -eq 1 ]; then
   echo "$I $LINE"
   let I++
 else
   echo "$LINE"
 fi
done < $1    #$1就是让脚本后面跟一个参数


改进:让脚本完善一点,当用户输入错的选项时,提示用户可以用那些选项:
#!/bin/bash
#
let LINENUM=0   #这个变量是来控制显示行号的k

while getopts ":n" SWITCH; do
  case $SWITCH in
  n)
   let LINENUM=1 ;;
  \?)
    echo "Unkown options,Usage:`basename $0` [-n] filename"  #这里就是改进的地方
    exit 1 ;;
   esac
done                 #这上面的都是为了定义-n选项的

shift $[$OPTIND-1]   #这就是剔除-n选项,让$1指针指向后面跟的文件
let I=1              #计时器的变量
while read LINE; do    #read每一次只读一行
 if [ $LINENUM -eq 1 ]; then
   echo "$I $LINE"
   let I++
 else
   echo "$LINE"
 fi
done < $1            #$1就是让脚本后面跟一个参数


******************************************************************************
这里有一个重要的知识点:
就是echo "Unkown options,`basename $0` [-n] filename"这一句话的解释
1.$0就指是脚本本身
2.basename就是取出我们路径的基名
  eg:#A=/etc/pam.d/login
     #basename $A
     这会输出:login    ----->这就是取基名
*******************************************************************************


改进:把错误的显示信息用函数来实现,目的是方便多次调用
#!/bin/bash
#
let LINENUM=0   #这个变量是来控制显示行号的

usage() {
    echo "Unkown options,Usage:`basename $0` [-n] filename"
}

while getopts ":n" SWITCH; do
  case $SWITCH in
  n)

   let LINENUM=1 ;;
  \?)usage
    exit 1 ;;
   esac
done                 #这上面的都是为了定义-n选项的

shift $[$OPTIND-1]   #这就是剔除-n选项,让$1指针指向后面跟的文件
let I=1              #计时器的变量
while read LINE; do    #read每一次只读一行
 if [ $LINENUM -eq 1 ]; then
   echo "$I $LINE"
   let I++
 else
   echo "$LINE"
 fi
done < $1            #$1就是让脚本后面跟一个参数

 

****************************************************************************************************
这里有一个重要的知识:
eg:#echo ${B:=3} 
   输出是:3
   #echo $B
   输出是:3
   #B=10
   #echo ${B=3}
   输出是:10
这就清楚了:${B:=3}的意思就是,给变量$B赋予一个默认值3,当给变量$B一个值10是,就会输出10,而不是默认值3,

****************************************************************************************************

4.改进newscripts脚本,让这个脚本自动追加变量的
#!/bin/bash
while getopts ":a:d:" SWITCH ; do
 case $SWITCH in
  a) AUTHOR=$OPTARG ;;
  d) DESC=$OPTARG ;;
  \?) echo "Unkown options."
     exit 1 ;;
 esac
done

shift $[$OPTIND-1] #只要用到$1,就必须用shift来剔除选项a,d等选项

if ! grep "^#!" $1;then
cat >> $1 << EOF
#!/bin/bash
#Author:${AUTHOR:=Jerry}
#Date & Time:`date +"%F %T"`
#Description: ${DESC}

EOF
fi
 vim +5 $1
chmod u+x $1

五.有关getopts的小知识理解和总结
 1.getopts 可以帮助我们识别凡是从我们脚本内传递过来的,以 - 开头的,都认为是选项,但是它一次只能识别一个

,因此,我们要用到while循环来遍历所有在脚本中给定的选项,因此,我们需要先声明我们有哪些选项,eg:"abc",不

支持长格式。

 2.free 命令 ---->用来显示物理内存及交换内存的使用情况的
    -m  以M为单位显示我们磁盘的使用情况

 3.free -m | grep "Mem" | awk '{print $2}'  ----->这是为了取出total的值
   解释:awk和cut差不多,只是awk是以空格来切割的,print是显示切割之后的第几段的
 4.下面的一个小脚本是用来显示磁盘的相应利用率的
#!/bin/bash
#Author:Jerry
#Date & Time:2011-02-23 15:35:36
#Description:

usage() {
  echo "Wrong Option."
  echo "Usage:`basename $0` [-t] [-u] [-f]"
}

while getopts ":tuf" SWITCH; do
  case $SWITCH in
   t)echo "The Total is:`free -m | grep "Mem" | awk '{print $2}'`" ;;
   u)echo "The Used is:`free -m | grep "Mem" | awk '{print $3}'`" ;;
   f)echo "The Free is:`free -m | grep "Mem" | awk '{print $4}'`" ;;
   \?)usage exit 1 ;;
   esac
done

六.写一个自动添加用户的小脚本和与其相关的知识
 1.我们建的用户,会在/home目录中建自己的家目录,该目录里有许多隐藏文件,这些隐藏文件时从/etc/skel 目录中

复制过来的
 
 2.我们想创建一个用户,必须在/etc/passwd和/etc/shadow里面添加一行
  如下:
  /etc/passwd
  oracle:x:2000:2000::/home/oracle:/bin/bash
  UID最好是最后面的一个用户的UID加1,GID要事先存在
  # cut -d: -f3 /etc/passwd | grep -v "65534" | sort -n | tail -1  --->显示最大的UID号,sort -n是安数值

排序,grep -v是取反,匹配相反的值

  /etc/shadow
  oracle:!!:14768:0:99999:7:::

  cp -r /etc/skel /home/oracle  ---->制作家目录
  chown -R oracle:oracle /home/oracle
  chmod -R go=--- /home/oracle

  echo "123456" | passwd --stdin oracle

 下面就是上面分析之后添加用户的小脚本,相当于useradd的作用
#!/bin/bash
#Author:Jerry
#Date & Time:2011-02-23 16:15:51
#Description:
NUID=$[`cut -d: -f3 /etc/passwd | grep -v "65534" |sort -n |tail -1`+1]
NGID=$[`cut -d: -f3 /etc/group | grep -v "65534" |sort -n |tail -1`+1]
TODAY=$[`date +"%s"` /86400]

if ! cut -d: -f1 /etc/group |grep "^$1" &>/dev/null; then
 echo "$1:x:$NGID:" >> /etc/group
else
 echo "The GROUP $1 exists."
 exit 1
fi                    #这段代码主要是添加用户组的

if ! cut -d: -f1 /etc/passwd | grep "^$1" &> /dev/null; then
 echo "$1:x:$NUID:$NGID::/home/$1:/bin/bash" >> /etc/passwd
 echo "$1:!!:$TODAY:0:99999:7:::" >> /etc/shadow
else
 echo "The user $1 exists."
 exit 1
fi                  #这段代码主要是添加用户的

#home directory
cp -r /etc/skel /home/$1
chown -R $1:$1 /home/$1
chmod -R go=--- /home/$1

#echo '123456' | passwd -stdin $1 &> /dev/null

这是上面改进后的小脚本,可以指定UID的小脚本
#!/bin/bash
#Author:Jerry
#Date & Time:2011-02-23 16:15:51
#Description:
NUID=$[`cut -d: -f3 /etc/passwd | grep -v "65534" |sort -n |tail -1`+1]
NGID=$[`cut -d: -f3 /etc/group | grep -v "65534" |sort -n |tail -1`+1]
TODAY=$[`date +"%s"` /86400]

usage () {
 echo -e "\033[31mUsage:\033[0m `basename $0`[-u UID] username"        #-e是用来识别反斜杠的,即033之前

的转义字符
}

while getopts ":u:" SWITCH ; do
  case $SWITCH in
    u)
     NEWUID=$OPTARG
     cut -d: -f3 /etc/passwd | grep "^$NEWUID" &> /dev/null && echo "UID exits." && exit 1 #这是>判断UID

是否存在
     ;;
    \?)usage
    exit 1 ;;
    esac
done       #这段代码是为了使用-u选项,来为用户指定UID的。

shift $[$OPTIND-1]

if ! cut -d: -f1 /etc/group |grep "^$1" &>/dev/null; then
 echo "$1:x:$NGID:" >> /etc/group
else
 echo "The GROUP $1 exists."
 exit 1
fi                    #这段代码主要是添加用户组的

if ! cut -d: -f1 /etc/passwd | grep "^$1" &> /dev/null; then
 echo "$1:x:${NEWUID:=$NUID}:$NGID::/home/$1:/bin/bash" >> /etc/passwd
 echo "$1:!!:$TODAY:0:99999:7:::" >> /etc/shadow
else
 echo "The user $1 exists."
 exit 1
fi                  #这段代码主要是添加用户的

#home directory
cp -r /etc/skel /home/$1
chown -R $1:$1 /home/$1
chmod -R go=--- /home/$1

#echo '123456' | passwd -stdin $1 &> /dev/null

七.监视用户登录的相关知识:
  1./var/log/       ----->这个目录是默认的日志文件存放目录
     下面的两个文件时二进制文件
     /var/log/wtmp  --->存储的是曾经过去的一段时间内,成功登录到系统的用户账号,包括时间,源ip地址
     last  --->就是查看曾经成功登录到系统用户的信息命令
     last -n 10  --->表示只想查看最近的10次记录
    
     /var/log/btmp  --->存储的是曾经过去的一段时间内,谁曾经试图登录系统,但失败了的
     lastb  ---->查看错误的登录,表示试图登录,但没登录上来的用户信息
     lastb -n 10

     lastlog  --->显示系统上每一个用户最近登陆的信息
     lastlog -u root ---->指定查看系统上用户的登录信息

   2.# watch -n 1 last -n 10   --->watch -n 1是指每隔一秒钟,都会执行 last -n 10 这条命令
  
八.有关umask的相关知识
  1.目录的默认权限是777减umask
    文件的默认权限是666减umask
    文件的默认权限没有执行权限,当我们的文件权限666减umsk值时,有了执行权限,系统会自动为我们的权限加1
    eg:666-023=644
    目录不受此限制
  2.root的默认umask值是022
   普通用户的umask是002
  3.umsk 023  ---->设置当前登陆和当前shell有效,登出就会失效
  4.当我们用umask命令时,就会显示出0022,后面三位是umask,第一位是SUID,SGID,STICKY
 
********************************************************************************************************
   SUID:当一个文件设置了SUID为,那么,以后当不是这个文件属主的用户,可以以这个文件属主的身份运行这个文

件了
   SGID:就是以属组的身份运行这个文件
   STICKY:粘滞位,作用是:当一个public directory有了STICKY位,那么,任何用户都可以写,但只能删除自己写的

文件,不能删除别人写的文件了。

  下面说一说他们的位置
  SUID:放置在u(用户)的x位上,当x位上本来就有执行权限,那么就显示为s(小写),如果本来没有,就显示为S(大写

)
  SGID:同SUID一样,一点不变,知识在o(属组)的权限上设置的
     设置了GID后,任何用户在该目录建的的文件都是该目录的属组来显示的
  STICKY:放置在o(其它)的x位上,如果以前有执行权限,就为t,没有就为T

 eg:# chmod u+s my
    # chmod g+s my
    # chmod o+t my
    # chmod 4755 mydir --->改的是UID
    # chmod 2755 mydir --->改的是GID
    # chmod 1755 mydir --->改的是STICKY
*******************************************************************************************************

九.有关信号捕捉的知识
  1.trap 'command' signal  --->这是模型
   eg:trap 'echo "haha,I am  still here."' SIGINT  --->SIGINT就是ctrl+c的命令信号
  2.下面的是一个小脚本,就是执行定义ctrl+c的信号方法,而不执行以前ctrl+c
eg:
#!/bin/bash
trap 'echo "haha"' SIGINT
read A
这个脚本就是我们按ctrl+c不会退出,而是输出haha,就是因为信号被trap截获了。


十.有关数组的知识
  1.属组:array,就是连续的一段内存空间,只有一个名字,由多个单元组成的,每个单元可以存储不同的值
   name[number]可以引用不同的存储单元
   eg:#ARRAY=(a b c d)   ---->声明数组
      #echo ${ARRAY[0]}  --->输出数组单元

   eg:A[2]=6
      A[10]=100
      echo ${A[*]}  --->输出所有被赋值的属组元素
      echo ${#A[*]} --->显示数组中非空元素的个数
   2.$RANDOM   --->这是系统内置的自动生成16位的随机数
     echo $[$RANDOM%/4]   --->取模

   3.取随机数的脚本
#!/bin/bash
#Author:Jerry
#Date & Time:2011-02-24 07:13:25
#Description:
grp1=(a b c d)
grp2=(e f g h i)

INDEX=$[$RANDOM%4]
echo ${grp2[$INDEX]}

for I in {1..20};do
echo $[$RANDOM%4]
done