精华内容
下载资源
问答
  • shell

    2019-03-24 17:11:04
    shell编程: 编译器,解释器 编程语言:机器语言、汇编语言、高级语言 静态语言:编译型语言强类型...面向过程shell,C面向对象:JAVA,Python,Perl,C++ 变量:内存空间,命名 内存:编址的存储单元 进程: 变量...

    shell编程:

    编译器,解释器

    编程语言:机器语言、汇编语言、高级语言

    静态语言:编译型语言
    强类型(变量)
    事先转换成可执行格式
    C、C++、JAVA、C#

    动态语言:解释型语言,on the fly
    弱类型
    边解释边执行
    PHP、SHELL、Python、Perl、lua

    面向过程:shell,C
    面向对象:JAVA,Python,Perl,C++

    变量:内存空间,命名

    内存:编址的存储单元

    进程:

    变量类型:事件确定数据的存储格式和长度
    字符
    数值
    整型
    浮点型

    逻辑:1+1>2
    逻辑运算:与、或、非、异或
    1:真
    0:假

    与:
    1 & 0 = 0
    0 & 1 = 0
    0 & 0 = 0
    1 & 1 = 1

    或:

    非:
    !真=假
    !假=真

    异或:
    相同为1,不同为0

    短路逻辑运算:
    与:只要一个为假,结果一定为假
    或:只要一个为真,结果一定为真

    整型:8bit:256
    0-255,溢出

    shell:弱类型编程语言

    强:变量在使用前,必须事先声明,甚至还需要初始化;
    弱:变量用时声明,甚至不区分类型

    显式:
    11+c=

    变量赋值:VAR_NAME=VALUE

    bash变量类型:
    环境变量
    本地变量(局部变量)
    位置变量
    特殊变量

    本地变量:
    set VARNAME=VALUE:作用域整个bash进程

    局部变量:
    local VARNAME=VALUE:作用域为当前代码段

    环境变量:作用域为当前shell进程及其子进程
    export VARNAME=VALUE
    VARNAME=VALUE
    export VARNAME
    "导出"

    位置变量:
    $1,$2,...

    特殊变量:
    $?:上一个命令的执行状态返回值:

    程序执行,可能有两类返回值:
    程序执行结果
    程序状态返回代码(0-255)
    0:正确执行
    1-255:错误执行,1,2,127系统预留

    输出重定向:

    2>
    2>>
    &>

    撤销变量:
    unset VARNAME

    查看当前shell中变量:
    set

    查看当前shell中的环境变量:
    printenv
    env
    export

    export PATH=$PATH:/usr/local/apache/bin

    脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序

    shebang:魔数
    #! /bin/bash

    注释行,不执行

    /dev/null:软件设备,bit bucket,数据黑洞

    脚本在执行时会启动一个子shell进程:
    命令行中启动的脚本会继承当前shell环境变量
    系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量

    引用变量:${VARNANE},括号有时可以省略

    编程能力:
    脚本编程

    练习:写一个脚本,完成以下任务
    1、添加5个用户,user1,...,user5
    2、每个用户的密码同用户名,而且要去,添加密码完成后不显示passwd命令的执行结果信息
    3、每个用户添加完成后,都要显示某某用户已经成功添加

    练习:写一个脚本,完成以下任务
    1、使用一个变量保存一个用户名;
    2、删除此变量中的用户,且一并删除其家目录;
    3、显示"用户删除完成"类的信息

    条件判断:
    如果用户不存在
    添加用户,给密码并显示添加成功
    否则
    显示已经存在,不用添加

    bash中如何实现条件判断
    条件测试类型:
    整数测试
    字符测试
    文件测试

    条件测试的表达式:
    [ expression ]
    [[ expression ]]
    test expression

    整数比较:
    -eq:测试整个整数是否相等:比如$A -eq $B
    -ne:测试两个整数是否不等:不等,为真:相等,为假
    -gt:测试一个数是否大于另一个数:大于,为真,否则,为假
    -lt:测试一个数是否小于另一个数:小于,为真,否则,为假
    -ge:大于或等于
    -le:小于或等于

    命令间的逻辑关系:
    逻辑与:&&
    第一个条件为假时,第二条件不用再判断,最终结果已经有;
    第一个条件为真时,第二条件必须得判断
    逻辑或:||

    如果用户user6不存在,就添加用户user6
    ! id user6 && useradd user6
    id user6 || useradd user6

    如果/etc/inittab文件的行数大于100,就显示好大的文件:
    [ wc -l /etc/inittab | cut -d' ' -f1 -gt 100 ] && echo "Large file"

    变量名称
    只能包含字母、数字和下划线,并且不能数字开头
    不应该跟系统中已有的环境变量重名
    最好做到见名知义

    如果用户存在,就显示用户已存在;否则,就添加添加此用户
    id user1 && echo "user1 exists" || useradd user1

    如果用户不存在,就添加;否则,显示其已经存在
    ! id user1 && useradd user1 || echo "user exists"

    如果用户不存在,添加并且给密码;否则,否则,显示其已经存在
    ! id user1 && useradd user1 && echo "user1" | passwd --stdin user1 || echo "user1 exists"

    练习,写一个脚本,完成以下要求:
    1、添加三个用户user1,user2,user3:但要先判断用户是否存在,不存在而后在添加
    2、添加完成后,显示一共添加了几个用户,当然,不能包括事先存在而没有添加的
    3、最后显示当前系统上共有多少个用户

    练习,写一个脚本,完成以下要求:
    给定一个用户:
    如果其UID为0,就显示此为管理员,否则,就显示其为普通用户;

    #! /bin/bash
    NAME=user1
    USERID= id -u $NAME
    [ $USERID -eq 0 ] && echo "admin" || echo "common user"

    #! /bin/bash
    NAME=user1
    USERID=id -u $NAME
    if $USERID -eq 0 ; then
    echo "admin"
    else
    echo "common user"
    fi

    条件判断,控制结构:

    单分支if语句
    if 判断条件; then
    statement1
    statement2
    ...
    fi

    双分支的if语句:
    if 判断条件; then
    statement1
    statement2
    ...
    else
    statement3
    statement4
    ...
    fi

    多分支的if语句:
    if 判断条件1; then
    statement1
    ...
    elif 判断条件2; then
    statement2
    ...
    elif 判断条件3; then
    statement3
    ...
    else
    statement4
    ...
    fi

    #! /bin/bash
    NAME=user1
    if id $NAME &> /dev/null(这个表示命令执行状态,即执行成功还是失败); then
    echo "$NAME exists."
    else
    useradd $NAME
    echo "$NAME" | passwd --stdin $NAME &> /dev/null
    echo "Add $NAME finished."
    fi

    练习:写一个脚本
    判断当前系统上是否有用户的默认shell为bash,如果有,就显示有多少个这类用户:否则,就显示没有这类用户
    #! /bin/bash
    grep "bash$" /etc/passwd &> /dev/null
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
    USERS=grep "bash$" /etc/passwd | wc -l
    echo "the shells of $USERS users is bash."
    else
    echo "no such user"
    fi

    练习:写一个脚本
    给定一个文件,比如/etc/inittab
    判断这个文件中是否有空白行:
    如果有,则显示其空白行数;否则,显示没有空白行

    练习:写一个脚本
    给定一个用户,判断其uid与gid是否一样
    如果一样,就显示此用户为"good guy":否则,就显示此用户为"bad guy".
    #! /bin/bash
    USERNAME=user1
    USERID=id -u $USERNAME
    GROUPID=id -g $USERNAME
    if [ $USERID -eq $GRUPID ]; then
    echo "GOOD guy"
    else
    echo "Bad guy"
    fi

    进一步要求:不使用id命令获得其id号:

    练习:写一个脚本
    判定命令历史中历史命令的总条目是否大于1000:如果大于,则显示"some command will gone.",否则显示ok。

    shell中如何进行算术运算:
    1、let算术运算表达式
    let C=$A+$B
    echo $C
    2、$[算术运算表达式]
    C=$[$A+$B]
    3、$((算术运算表达式))
    C=$(($A+$B))
    4、expr算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用
    C=expr $A + $B

    练习:写一个脚本
    给定一个用户,获取其密码警告期限:
    而后判断用户密码使用期限是否已经小于警告期限
    提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限
    如果小于,则显示"warning";否则,就显示"ok"

    #! /bin/bash
    W=grep "student" /etc/shadow | cut -d: -f6
    S=date +%s
    T=expr $S/86400
    L=grep "^student" /etc/shadow | cut -d: -f5
    N=grep "^student" /etc/shadow | cut -d: -f3
    SY=$[$L-$[$T-$N]]
    if [ $SY -lt $W ]; then
    else 'Warning'
    else
    else 'OK'
    fi

    圆整:丢弃小数点后的所有内容

    测试方法:
    [ expression ]
    [[ expression ]]
    test expression

    bash中常用的条件测试有三种:
    整数测试:
    -gt
    -le
    -ne
    -eq
    -ge
    -lt

    INT1=63
    INT2=77
    [ $INT1 -eq $INT2 ]
    [[ $INT1 -eq $INT2 ]]
    test $INT1 -eq $INT2

    if grep "^$USERNAME\>" /etc/passwd; then

    文件测试:
    -e FILE:测试文件是否存在
    -f FILE:测试文件是否为普通文件
    -d FILE:测试指定路径是否为目录
    -r FILE:测试当前用户对指定文件是否有读取权限
    -w FILE:测试当前用户对指定文件是否有写权限
    -x

    [ -e /etc/inittab ]
    [ -x /etc/rc.d/rc.sysinit ]

    练习:写一个脚本
    给定一个文件:
    如果是一个普通文件,就显示之
    如果是一个目录,亦显示之
    否则,此为无法识别之文件
    #! /bin/bash
    FILE=/etc/rc.d/rc.sysinit
    if [ ! -e $FILE ]; then
    echo "No such file."
    exit 6
    fi

    if [ -f $FILE ]; then
    echo "Common file"
    elif [ -d $FILE ]; then
    echo "Directory"
    else
    echo "Unknown"
    fi

    测试脚本是否有语法错误:
    bash -n 脚本
    bash -x 脚本:单步执行

    定义脚本退出状态码

    exit:退出脚本
    exit #
    如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码

    bash变量的类型:
    本地变量(局部变量)
    环境变量
    位置变量:
    $1,$2,...
    shift
    特殊变量:
    $?
    $#:参数的个数
    $*:参数列表
    $@:参数列表

    练习:写一个脚本
    能接受一个参数(文件路径)
    判定:此参数如果是一个存在的文件,就显示"ok";否则
    vim filetest3.sh
    #! /bin/bash
    if [ $# -lt 1 ]; then
    echo "Usage: ./filetest3.sh ARG1 [ARG2]..."
    exit 7
    fi

    if [ -e $1 ]; then
    echo ok
    else
    echo "No such file"
    fi

    bash filetest3.sh /etc/fstab

    练习:写一个脚本
    给脚本传递两个参数(整数):
    显示此两者之和,之积
    #! /bin/bash
    if [ $# -lt 2 ]; then
    echo "Usage: cacl.sh ARG1 ARG2"
    exit
    fi
    echo "The sum is:$[$1+$2]"
    echo "The prod is:$[$1*$2]"

    练习:
    传递一个用户名参数给脚本,判断此用户的用户名跟基本组的组名是否一致,并将结果显示出来
    #! /bin/bash
    if ! id $1 &> /dev/null; then
    echo "No such user."
    exit 10
    fi

    if [ id -n -u $1 == id -n -g $1 ]; then
    echo "yiyang"
    else
    echo "bu yiyang"
    fi

    字符测试:
    ==:测试是否相等,相等为真,不等为假
    !=:测试不等,不等为真,相等为假

    <
    -n string:测试指定字符串是否为空,空则真,不空为假
    -z string:测试指定字符串是否不空,不空为真,空则假

    练习:写一个脚本
    传递一个参数(单字符就行)给脚本,如果参数为q,就退出脚本,否则,就显示用户的参数

    练习:写一个脚本
    传递一个参数(单字符就行)给脚本,如参数为q,Q,quit或者Quit,就退出脚本;否则,显示用户的参数
    #! /bin/bash
    if [ $1 = 'q' ]; then
    echo "quitting..."
    exit 1
    elif [ $1 = 'Q' ]; then
    echo "quitting..."
    exit 2
    elif [ $1 = 'quit' ]; then
    echo "quitting..."
    exit 3
    elif [ $1 = 'Quit' ]; then
    echo "quitting..."
    exit 4
    else
    echo $1
    fi

    练习:
    传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,要去保留两位精度。形如:
    ./cacl.sh 5 / 2
    echo "scale=2;111/22;" | bc
    bc <<< "scale=2;111/22"

    练习:
    传递3个参数给脚本,参数均为用户名,将此些用户账号信息提取出来后放置于/tmp/testusers.txt文件中,并要求每一行行首有行号

    写一个脚本:
    判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id 一行中
    如果其生产商为AuthnticAMD,就显示其为AMD公司
    如果其生产商为GenuineIntel,就显示其为Intel公司
    否则,就说其非主流公司

    写一个脚本:
    给脚本传递三个整数,判断其中的最大数和最小数,并显示出来
    #! /bin/bash
    MAX=$1
    MIN=$1
    [ $2 -gt $MAX ] && MAX=$2
    [ $3 -gt $MAX ] && MAX=$3
    echo "$MAX"
    [ $2 -lt $MIN ] && MIN=$2
    [ $3 -lt $MIN ] && MIN=$3
    echo "$MIN"

    #! /bin/bash
    a=1
    MAX=0
    MIN=$3
    while [ $a -le 3 ]
    do
    [ $1 -gt $MAX ] && MAX=$1
    [ $1 -lt $MIN ] && MIN=$1
    shift 1
    a=$(($a+1))
    done
    echo $MAX
    echo $MIN

    循环:进入条件,退出条件
    for
    while
    until

    for 变量 in 列表; do
    循环体
    done

    for i in 1 2 3 4 5 6 7 8 9 10; do
    加法运算
    done

    遍历完成之后,退出:

    如何生成列表:
    {1..100}
    seq [起始数 [步进长度]] 结束数
    declare -i SUM=0

    #! /bin/bash
    declare -i SUM=0
    for i in {1..100}; d0
    let SUM=$[SUM+$i]
    done
    echo "the sum is:$SUM."

    写一个脚本:
    1.设定变量FILE的值为/etc/passwd
    2.依次向/etc/passwd中的每个用户问好,并显示对方的shell,形如:
    hello,root,your shell: /bin/bash
    3.统计一共多少个用户
    for i in seq 1 $LINES; do echo "Hello,head -n $I /etc/passwd | tail -1 | cut -d: -f1"; done

    只向默认shell为bash的用户问声好

    写一个脚本:
    1.添加10个用户user1到user10,密码同用户名:但要求只有用户不存在的情况下才能添加
    #! /bin/bash
    for i in user{1..10}; do
    if id $i &> /dev/null; then
    echo "$i exists."
    else
    useradd $i
    echo $i | passwd --stdin $i &> /dev/null
    echo "add user $i finished."
    fi
    done

    扩展:
    接受一个参数:
    add:添加用户user1..user10
    del:删除用户user1..user10
    其它:退出
    #! /bin/bash
    if [ $# -lt 1 ]; then
    echo "Usage: adminusers ARG"
    exit 7
    fi

    if [ $1 == '--add' ]; then
    for i in {1..10}; do
    if id user$i &> /dev/null; then
    echo "user$i exists."
    else
    useradd user$i
    echo user$i | passwd --stdin user$i &> /dev/null
    echo "Add user$i finished."
    fi
    done
    elif [ $1 == '--del' ]; then
    for i in {1..10}; do
    if id user$i &> /dev/null; then
    userdel -r user$i
    echo "user$i exists."
    else
    echo "No user$i."
    fi
    done
    else
    echo "Unknown ARG"
    exit 8
    fi

    #! /bin/bash
    if [ $1 == '--add' ]; then
    for i in echo $2 | sed 's/,/ /g'; do
    if id $i &> /dev/null; then
    echo "$i exists."
    else
    useradd $i
    echo $i | passwd --stdin $i &> /dev/null
    echo "add $i finished."
    fi
    done
    elif [ $1 == '--del' ]; then
    for i in echo $2 | sed 's/,/ /g'; do
    if id $i &> /dev/null; then
    userdel -r $i
    echo "delete $i finished"
    else
    echo "$i not exist"
    fi
    done
    elif [ $1 == '--help' ]; then
    echo "Usage:adminuser2.sh --add user1,user2... | --del user1,user2...| --help"
    else
    echo "Unknown options."
    fi

    写一个脚本:
    计算100以内所有能被3整除的正整数的和
    取模,取余:%
    3%2=1
    100%55=45

    写一个脚本:
    计算100以内的所有奇书的和以及所有偶数的和;分别显示之

    写一个脚本,分别显示当前系统上所有默认的shell为bash的用户和默认shell为/sbin/nologin的用户,并统计各类shell下的用户总数,显示结果形如下:
    BASH,3users,they are:
    root,redhat,gentoo

    NOLOGIN,2users,they are:
    bin,ftp

    expect远程自动批量登录以及执行命令
    #! /bin/bash
    cat /root/iplist | while read line iplist文件中存放了IP地址和密码,每行格式为"IP地址 密码"
    do
    A=($line)
    /usr/bin/expect<<EOF
    set timeout 5 是设置超时时间的
    spawn ssh root@${A[0]} spawn是进入expect环境后才可以执行的expect内部命令
    expect "password:" 这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的5秒
    send "${A[1]}\r" 用户的登陆密码,这里是root用户,密码是passwd
    expect "
    ]#" 意思为遇到这个提示符为执行命令开始
    send "df -h\r" 意思为发送命令
    send "pwd\r" 意思为发送命令
    expect "*]#" 意思为遇到这个提示符为执行命令结束
    send "logout\r" 退出远程机器
    EOF
    done

    #! /bin/bash
    cat /root/iplist | while read line
    do
    A=($line)
    /usr/bin/expect<<EOF
    set timeout 5
    spawn ssh root@${A[0]}
    expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" { send "${A[1]}\r" }
    }
    expect "]#"
    send "df -h\r"
    send "pwd\r"
    expect "
    ]#"
    send "logout\r"
    EOF
    done

    expect实现su切换脚本
    #! /bin/bash
    cat /root/iplist | while read line
    do
    A=($line)
    /usr/bin/expect<<EOF
    set timeout 5
    spawn ssh weihu@${A[0]}
    expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" { send "${A[1]}\r" }
    }
    expect "]$"
    send "su - root\r"
    expect "密码:"
    send "${A[2]}\r"
    send "ifconfig\r"
    expect "
    ]#"
    send "pwd\r"
    expect "*]#"
    send "logout\r"
    EOF
    done
    =========================================================================================>

    测试:
    整数测试
    -le
    -lt
    -gt
    -eq
    -ne
    字符测试

    !=
    >
    <
    -n
    -z

    文件测试
    -e
    -f
    -d
    -r
    -w
    -x

    if [ $# -gt -1 ]; then

    组合测试条件
    -a:与关系
    -o:或关系
    !:非关系

    if [ $# -gt 1 -a $# -le 3 ]
    if [ $# -gt 1 ] && [ $# -le 3 ]

    写一个脚本,利用RANDOM生成10个随机数,并找出其中的最大值,和最小值
    #! /bin/bash
    declare -i MAX=0
    declare -i MIN=0
    for i in {1..10}; do
    MYRAND=$RANDOM
    [ $i -eq 1 ] && MIN=$MYRAND
    if [ $i -le 9 ]; then
    echo -n "$MYRAND,"
    else
    echo "$MYRAND"
    fi
    [ $MYRAND -gt $MAX ] && MAX=$MYRAND
    [ $MYRAND -lt $MIN ] && MIN=$MYRAND
    done

    echo $MAX,$MIN

    面向过程
    控制结果
    顺序结构
    选择结构
    循环结构

    选择结构:
    if:单分支,双分支,多分支
    if condition; then
    statement
    ....
    fi

    if condition; then
    statement
    ....
    else
    statement
    ....
    fi

    if condition; then
    statement
    ....
    elif condition2; then
    statement
    ....
    else
    statement
    ....
    fi

    case语句:选择结构

    case switch in
    value1)
    statement
    ....
    ;;
    value2)
    statement
    ....
    ;;
    *)
    statement
    ....
    ;;
    esac

    #! /bin/bash
    case $1 in
    [0-9])
    echo "A digit." ;;
    [a-z])
    echo "Lower" ;;
    [A-Z])
    echo "Upper" ;;
    *)
    echo "Special character." ;;
    esac

    只接受参数start,stop,restart,status其中之一
    #! /bin/bash
    case $1 in
    start)
    echo "start server...." ;;
    stop)
    echo "stop server...." ;;
    restart)
    echo "restarting server...." ;;
    *)
    echo "basename $0 {start|stop|restrt|status}" ;;
    esac

    写一个脚本,可以接受选项及参数,而后能获取每一个选项,及选项的参数;并能根据选项及参数做出特定的操作,比如
    #! /bin/bash
    DEBUG=0
    ADD=0
    DEL=0

    for i in seq 1 $#; do
    case $1 in
    -v|--verbose)
    DEBUG=1
    shift ;;
    -h|--help)
    echo "Usage:basename $0 --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
    exit 0
    ;;
    --add)
    ADD=1
    ADDUSERS=$2
    shift 2
    ;;
    --del)
    DEL=1
    DELUSERS=$2
    shift 2
    ;;
    #*)

    echo "echo "Usage:basename $0 --add USER_LIST --del USER_LIST -v|--verbose -h|--help""

    exit 7

    ;;

    esac
    done

    if [ $ADD -eq 1 ]; then
    for USER in echo $ADDUSERS | sed 's@,@ @g'; do
    if id $USER &> /dev/null; then
    [ $DEBUG -eq 1 ] && echo "$USER exists."
    else
    useradd $USER
    [ $DEBUG -eq 1 ] && echo "Add user $USER finished."
    fi
    done
    fi

    if [ $DEL -eq 1 ]; then
    for USER in echo $DELUSERS | sed 's@,@ @g'; do
    if id $USER &> /dev/null; then
    userdel -r $USER
    [ $DEBUG -eq 1 ] && echo "$USER exists."
    else
    [ $DEBUG -eq 1 ] && echo "$USER not exist."
    fi
    done
    fi

    脚本编程控制结构:
    顺序
    选择
    if
    case
    循环
    for
    while
    until

    while condition; do
    statment
    done

    进入循环:条件满足
    退出循环:条件不满足

    until condition; do
    statment
    done

    进入循环:条件不满足
    退出循环:条件满足

    #! /bin/bash
    read -p "Input something: " STRING
    while [ $TRING != 'quit' ]; do
    echo $STRING | tr 'a-z' 'A-Z'
    read -p "Input something: " STRING

    done

    #! /bin/bash
    read -p "Input something: " STRING
    until [ $STRING == 'quit' ]; do
    echo $STRING | tr 'a-z' 'A-Z'
    read -p "Input something: " STRING
    done

    #! /bin/bash
    who | grep "hadoop" &> /dev/null
    RETVAL=$?
    until [ $RETVAL -eq 0 ]; do
    echo "hadoop is not come"
    sleep 5
    who | grep "hadoop" &> /dev/null
    RETVAL=$?
    done
    echo "hadoop is logged in"

    for 变量 in 列表; do
    循环体
    done

    for (( expr1 ; expr2 ; expr3 )); do
    循环体
    done

    #!/bin/bash
    declare -i sum=0
    for ((i=1;i<=100;i++)); do
    let sum+=$i
    done
    echo $sum

    写一个脚本:
    通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线,如果在线,就显示"ip is up",其中的ip要换成为真正的ip地址,且以绿色显示
    如果不在线,就显示"ip is down.",其中的ip要换成为真正的ip地址,且以红色显示
    要求:分别使用while,until和for循环实现

    awk 'PATTERN{ACTION}' file

    df -Ph | awk '{print $2}'
    awk -F: '{print $1,$2}' /etc/passwd

    写一个脚本(前提:请为虚拟机新增一块硬盘,假设它为/dev/sdb),为指定的硬盘创建分区:
    1.列出当前系统上所有的磁盘,让用户选择,如何选择quit则退出脚本;如果用户选择错误,就让用户重新选择;
    2.当用户选择后,提醒用户确认接下来的操作可能会损坏数据,并请用户确认,如果用户选择y就继续,否则,让用户重新选择;
    3.抹除那块硬盘的所有分区(提示,抹除所有分区后执行sync命令,并让脚本睡眠3秒钟后在分区):并为其创建三个主分区,第一个为20M,第二个为512M,第三个为128M,且第三个为swap分区类型;(提示:将分区命令通过echo传送给fdisk即可实现)
    #! /bin/bash
    echo 'n
    p
    1

    +20M
    n
    p
    2

    +512M
    n
    p
    3

    +128M
    t
    3
    82'
    w | fisk /dev/hda

    fdisk -l 2> /dev/null | grep ^Disk /dev/[sh]d[a-z]'' | awk -F: '{print $1}'
    dd if=/dev/zero of=/dev/hda bs=512 count=1
    sync
    sleep 3

    写一个脚本,完成以下功能:
    说明:此脚本能于同一个repo文件中创建多个yum源的指向;
    1.接受一个文件名作为参数,此文件存放至/etc/yum.repo.d目录中,且文件名以.repo为后缀;
    2.在脚本中,提醒用户输入repo id:如果为quit,则退出脚本;否则,继续完成下面的步骤;
    3.repo name以及baseurl的路径,而后以repo文件的格式将其保存至指定的文件中;
    4.enabled默认为1,而gpgcheck默认设定为0;
    5.此脚本会循环执行多次,除非用户为repo id指定为quit
    #! /bin/bash
    REPOFILE=/etc/yum.repos.d/$1
    if [ -e $REPOFILE ]; then
    echo "$1 exists."
    exit 3
    fi

    read -p "Repository ID:" REPOID
    until [ $REPOID == 'quit' ]; do
    echo "[$REPOID]" >> $REPOFILE
    read -p "Repository name: " REPONAME
    echo "name=$REPONAME" >> $REPOFILE
    read -p "Repository Baseurl:" REPOURL
    echo "baseurl=$REPOURL" >> $REPOFILE
    echo -e 'enabled=1\ngpgcheck=0' >> $REPOFILE
    read -p "Repository ID: " REPOID
    done

    while,until,for

    break:提前退出循环
    continue:提前结束本轮循环,而进入下一轮循环

    #! /bin/bash
    let sum=0
    let i=0
    while [ $i -lt 100 ]; fo
    let i++
    if [ $[$i%2] -eq 0 ]; then
    continue
    fi
    let sum+=$i
    done

    #! /bin/bash
    declare -i sum=0
    for i in {1..1000}; do
    let sum+=$i
    if [ $sum -gt 10000]; then
    break
    fi
    done
    echo $i
    echo $SUM

    while的特殊用法一:
    while :;do

    done

    while的特殊用法二:
    while read LINE; do

    done < /path/to/somefile

    #! /bin/bash
    file=/ect/passwd
    let i=0
    while read LINE; do
    [ echo $LINE | awk -F: '{print $3}' -le 505 ] && continue
    [ echo $LINE | awk -F: '{print $7}' == '/bin/bash' ] && echo $LINE | awk -F : '{print $1}' && let i++
    [ $i -eq 6 ] && break
    done < $FILE

    写一个脚本:
    1.判断一个指定的bash脚本是否有语法错误;如果有错误,则提醒用户键入Q或者q无视错误并退出,其它任何键可以通过vim打开这个指定的脚本;
    2.如果用户通过vim打开编辑后保存并退出时仍然有错误,则重复第一步中的内容;否则,就正常关闭退出
    #! /bin/bash
    until bash -n $1 &> /dev/null; do
    read -p "Syntax error,[Qq] to quit,others for editing: " CHOICE
    case $CHOICE in
    q|Q)
    echo "somthing wrong,quiting."
    exit 5
    ;;
    *)
    vim + $1
    ;;
    esac
    done

    函数:功能,function

    代码重用:

    库:so

    定义一个函数:
    function FUNNAME {
    command
    }

    FUNCNAME() {
    command
    }

    自定义执行状态返回值:
    return #
    0-255

    接受参数的函数:
    ./a.sh m n
    $1:m
    $2:n

    #! /bin/bash
    cat << EOF
    d|D) show disk usages
    m|M) show memory usages
    s|S) show swap usages
    q|Q) quit.
    EOF

    read -p "your choice: " CHOICE
    until [ $CHOICE == 'q' -o $CHOICE == 'Q' ]
    do
    case $CHIOCE in
    d|D) df -lh ;;
    m|M) free -m | grep '^Mem';;
    s|S) free -m | grep '^Swap';;
    *)
    cat << EOF
    d|D) show disk usages
    m|M) show memory usages
    s|S) show swap usages
    q|Q) quit.
    EOF
    read -p "your choice,again: " CHOICE
    esac
    cat << EOF
    d|D) show disk usages
    m|M) show memory usages
    s|S) show swap usages
    q|Q) quit.
    EOF
    read -p "your choice: " CHOICE
    done

    #! /bin/bash
    TWOINT() {
    A=9
    B=7
    C=$[$A+$B]
    echo $C
    }
    M=11
    SUM=$[$M+TWOINT]
    echo $SUM

    #! /bin/bash
    ADDUSER() {
    USERNAME=$1
    if ! id -u $USERNAME &> /dev/null; then
    useradd $USERNAME
    echo $USERNAME | passwd --stdin $USERNAME &> /dev/null
    return 0
    else
    return 1
    fi
    }
    for i in {1..10}
    do
    ADDUSER user$i
    fi [ $? -eq 0 ]; then
    echo "add user$i finished."
    else
    echo "Failuser."
    fi
    done

    #! /bin/bash
    function SHOWMENU {
    cat << EOF
    d|D) show disk usages
    m|M) show memory usages
    s|S) show swap usages
    q|Q) quit.
    EOF
    }
    SHOWMENU
    SHOWMENU
    SHOWMENU

    #! /bin/bash
    TWOSUM() {
    echo $[$1+$2]
    }
    for i in {1..10}
    do
    let J=$[$i+1]
    echo "$i plus $J is TWOSUM $i $j"
    done

    练习:写一个脚本,判定192.168.0.200-192.168.0.254之间主机哪些在线。要求
    1.使用函数来实现一台主机的判定过程
    2.在主程序中来调用此函数判定指定的范围内的所有主机的在线情况
    #! /bin/bash
    PING() {
    for i in {200..254}
    do
    if ping -c1 -W 1 192.168.0.$i &> /dev/null; then
    echo "192.168.0.$i is up."
    else
    echo "192.168.0.$i is down."
    fi
    done
    }
    PING

    #! /bin/bash
    PING() {
    if ping -c 1 -W 1 $1 &> /dev/null; then
    echo "$1 is up."
    else
    echo "$1 is down."
    fi
    }

    for i in {200..254}
    do
    PING 192.168.0.$i
    done

    for i in {220..254}
    do
    PING 172.16.100.$i
    done

    #! /bin/bash
    PING() {
    if ping -c 1 -W 1 $1 &> /dev/null; then
    return 0
    else
    return 1
    fi
    }

    for i in {200..254}
    do
    PING 192.168.0.$i
    if [ $? -eq 0 ]; then
    echo "192.168.0.$i is up."
    else
    echo "192.168.0.$i is down."
    fi
    done

    写一个脚本:使用函数完成
    1.函数能够接受一个参数,参数为用户名
    判断一个用户是否存在
    如果存在,就返回此用户的shell和UID;并返回正常的状态值
    如果不存在,就说此用户不存在;并返回错误的状态值
    2.在主程序中调用函数

    扩展1:在主程序中,让用户自己输入用户名后,传递给函数来进行判断
    扩展2:在主程序中,输入用户名判断后不退出脚本,而是提示用户继续输入下一个用户名;如果用户输入的用户不存在,请用户重新输入,但如果用户输入的是q或Q就退出;

    =========================================================================================>

    二、变量的截取替换

    表达式 含义
    ${#string} $string的长度

    ${string:position} 在$string中, 从位置$position开始提取子串
    ${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串

    ${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
    ${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
    ${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
    ${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串

    ${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
    ${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
    ${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
    ${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

    脚本编程知识点:
    1.变量中字符的长度:${#VARNAME}

    2.变量赋值等:
    ${parameter:-word}:如果parameter为空或未定义,则变量展开为"word":否则,展开为parameter的值:
    ${parameter:+word}:如果parameter为空或未定义,不做任何操作;否则,则展开为"word"值
    ${parameter:=word}:如果parameter为空或未定义,则变量展开为"word",并将展开后的值赋值为parameter
    ${parameter:offset}
    ${parameter:offset:length}:取字串,从offset处的后一个字符开始,取lenth长的字串

    3.脚本配置文件
    /etc/rc.d/init.d/服务脚本
    服务脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件

    vim a.conf
    TEST='hello world'

    vim a.sh
    #! /bin/bash
    . /root/a.conf
    TEST=${TEST:-info}
    [ -n "$TEST" ] && echo "$TEST"

    4.局部变量
    lcoal VAR_NAME=

    a=1
    test() {
    local a=$[3+4]
    }
    test
    for i in seq $a 10
    do
    echo "$i"
    done

    5.命令mktemp
    创建临时文件或者目录
    mktemp /tmp/file.XX
    -d:创建为目录

    6.信号
    kill -SIGNAL PID
    1:HUP
    2:INT
    9:KILL
    15:TERM
    脚本中,能实现信息捕捉,但9和15无法捕捉不了

    Ctrl+c:SIGINT

    trap命令:
    trap 'COMMAND' 信号列表

    vim showdate.sh
    #! /bin/bash
    trap 'echo "you go..."' INT
    while :
    do
    date
    sleep 2
    done

    7.一行执行多个语句,语句间用分号分隔
    #! /bin/bash
    NET=192.168.0
    FILE=mktemp /tmp/file.xxxxx
    clearup() {
    echo "quit...."
    rm -rf $FILE
    exit 1
    }
    trap 'clearup' INT
    for i in {200..254}
    do
    if ping -c 1 -W 1 $NET.$i &> /dev/null; then
    echo "$NET.$i is up."| tee >> $FILE
    else
    echo "$NET.$i is down."
    fi
    done

    任务计划:

    1.在未来的某个时间点执行一次某任务:
    at
    batch

    at 时间
    at> COMMAND
    at> Ctrl+d

    指定时间:
    绝对时间:HH:MM,DD.MM.YY MM/DD/YY
    相对时间:now+#
    单位:minutes,hours,days,weeks
    模糊时间:noon,midnight,teatime

    命令的执行结果:将以邮件的形式发给安排任务的用户

    at -l = atq
    at -d AT_JOB_ID = atrm AT_JOB_ID

    2.周期性地执行某任务
    cron:自身是一个不间断运行的服务
    anacron:cron的补充,能够实现让cron因为各种原因在过去的时间改执行而未执行的任务在恢复正常执行一次

    cron:
    系统cron任务:
    /etc/crontab
    分钟 小时 天 月 周 用户 任务
    用户cron任务:
    /var/spool/cron/USERNAME
    分钟 小时 天 月 周 任务

    时间的有效取值:
        分钟:0-59
        小时:0-23
         天:1-31
         月:1-12
         周:0-7,0和7都表示周日
    时间通配表示:
         *:对应时间的所有有效值
           3 * * * *
           3 * * * 7
           13 12 * * *
         ,:离散时间点:
           10,40 * * * *
         -:连续时间点
            10 02 * * 1-5
          /#:对应取值范围内每多久一次
            */3 * * * *

    每两小时执行一次:
    00 /2
    每两天执行一次:
    10 04 /2 *

    执行结果将以邮件形式发送给管理员:
    /3 * /bin/cat /etc/fstab &> /dev/null

    cron的环境变量:cron执行所有命令都去PATH坏境变量指定的路径下去找
    PATH /bin:/sbin:/usr/bin:/usr/sbin

    用户任务的管理:
    crontab
    -l:列出当前用户的所有cron任务
    -e:编辑
    -r:移除所有任务
    -u USERNAME:管理其用户的cron任务

    anacron:
    cat /etc/anacrontab

    service crond status
    service anacron status

    Knernel + initrd(busybox制作,提供ext3文件系统模块) + ROOTFS(busybox制作)

    make arch/
    arch/x86/boot/bzImage

    硬件驱动:initrd
    initrd:仅需要提供内核访问真正的根文件系统所在设备需要的驱动
    存储设备和文件系统相关的模块
    系统初始化rc.sysinit:初始化其它硬件的驱动程序

    ROOTFS:busybox,init不支持运行级别
    /etc/inittab:格式也不尽相同
    ash,hush
    bash

    内核编译:
    tar -zxvf linux-2.6.38.5.tar.gz -C /usr/src/
    cd linux-2.6.38.5
    ln -sv linux-2.6.38.5 linux
    cd linux
    mv kernel-2.6.38.1-i686.cfg .config
    make memuconfig
    make drivers/net/pcnet32.ko
    make arch/x86/或者(make SUBIDR=arch/)

    /boot/vmlinuz(ext3,IDE)

    /mnt/boot: /dev/hda1
    /mnt/sysroot: /dev/hda2

    1、安装grub
    grub-install --root-directory=/mnt /dev/hda

    cp /boot/vmlinuz-2.16.18-308.e15 /mnt/boot/vmlinuz

    tar -zxvf busybox-1.20.2.tar.gz
    mkdir busybox-1.20.2/include/mtd
    cp /usr/src/linux-2.6.38.5/include/mtd/ubi-user.h busybox-1.20.2/inuclude/mtd

    cd busybox-1.20.2
    make menuconfig
    make install
    mkdir /tmp/initrd
    cp _install/* /tmp/initrd/ -a
    cd /tmp/initrd/
    mkdir proc sys mnt/sysroot dev tmp lib/modules etc -pv
    rm -rf linuxrc
    mknod dev/console c 5 1
    mknod /dev/null c 1 3

    vim init
    #! /bin/sh
    echo "mounting proc and sys..."
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys

    echo "load ext3 module..."
    insmod /lib/modules/jbd.ko
    insmod /lib/modules/ext3.ko
    mdev -s
    mount -t ext3 /dev/hda2 /mnt/sysroot

    echo "Switch to real_rootfs..."
    exec switch_root /mnt/sysroot /sbin/init

    modinfo jbd
    mkdinfo ext3
    把输出的filename信息路径复制到 lib/modules

    find . | cpio -H newc --quit -o | gzip -9 > /mnt/boot/initrd.gz

    vim /mnt/boot/grub/grub.conf
    default=0
    timeout=3
    title MageEdu Tiny Linux (2.6.18)
    root(hda0,0)
    kernel /vmlinuz ro root=/dev/hda2
    initrd /initrd.gz

    cp -a busybox-1.20.2/_install/* /mnt/sysroot/

    cd /mnt/sysroot
    rm -rf linuxrc
    mkdir boot root etc/rc.d/init.d var/{log,lock,run} proc sys dev lib/moudles tmp home mnt media -pv

    mknod dev/console c 5 1
    mknod dev/null c 1 3

    vim etc/inittab
    ::sysinit:/etc/rc.d/rc.sysinit
    console::respawn:-/bin/sh
    ::ctrlaltdel:/sbin/reboot
    ::shutdown:/bin/umount -a -r

    vim /etc/rc.d/rc.sysinit
    #! /bin/sh
    echo -e "\tWelcome to \033[3
    4mMegeEdu Tiny\033[0m Linux"

    echo "mount proc and sys..."
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys

    echo -e "Rmount the rootfs..."
    mount -t ext3 -o remount,rw /dev/hda2 /

    echo "Detect and export hardward information"
    mdev -s

    echo "Mount the ohter filesystem.."
    mount -a

    chmod +x etc/rc.d/rc.sysinit

    vim etc/fstab
    sysfs /sys sysfs defaults 0 0
    proc /proc proc defaults 0 0
    /dev/hda1 /boot ext3 defaults 0 0
    /dev/hda2 / ext3 defaults 1 1

    ./bincp.sh bash
    然后吧etc/inittab中的/bin/sh改成/bin/bash

    grep -E "^root:" /etc/passwd > /mnt/systoot/etc/passwd
    grep -E "^root:" /etc/passwd > /mnt/sysroot/etc/shadow
    grep -E "^root:" /etc/group > /mnt/sysroot/group

    vim etc/inittab
    ::sysinit:/etc/rc.d/rc.sysinit
    ::respawn:/sbin/getty 9600 tty1
    ::ctrlaltdel:/sbin/reboot
    ::shutdown:/bin/umount -a -r

    vim /mnt/sysroot/etc/hostname
    HOSTNAME=tiny.magedu.com

    vim /mnt/sysroot/ect/rc.d/rc.sysinit
    #! /bin/sh
    echo -e "\tWelcome to \033[3
    4mMegeEdu Tiny\033[0m Linux"

    echo "set the hostname"
    [ -f /etc/hostname ] && . /etc/hostname
    [ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
    hostname $HOSTNAME

    echo "mount proc and sys..."
    mount -t proc proc /proc
    mount -t sysfs sysfs /sys

    echo -e "Rmount the rootfs..."
    mount -t ext3 -o remount,rw /dev/hda2 /

    echo "Detect and export hardward information"
    mdev -s

    echo "Mount the ohter filesystem.."
    mount -a

    cp /etc/issue /mnt/sysroot/ect/

    find . | cpio -H newc --quiet -o | gzip > /root/tiny.1.gz

    modinfo mii
    modinfo pcnet32
    同样复制其模块位置到lib/modules/

    在sysinit中末尾添加一行
    echo "Load ethernet card module..."
    insmod /lib/modules/...

    telnet:远程登录协议,23/tcp
    C/S
    S:telnet服务器
    C:telnet客户端

    ssh:Secure SHell,应用层协议,22/tcp
    通信过程及认证过程是加密的,主机认证
    用户认证过程加密
    数据传输过程加密

    主机密钥
    非对称加密
    Secret key
    Public key
    密钥交换

    ssh v1,v2
    man-in-middle

    sshv2

    认证过程:
    基于口令认证
    基于密钥认证

    协议:规范
    实现:服务器端、客户端

    Linux:openssh
    C/S
    服务器端:sshd,配置文件/etc/sshd_config
    客户端:ssh,配置文件/etc/ssh/ssh_config
    ssh-keygen:密钥生成器
    ssh-copy-id:将公钥传输至远程服务器
    scp:跨主机安全复制工具

    ssh:
    ssh USERNAME@HOST
    ssh -l USERNAME HOST
    ssh USERNAME@HOST 'COMMAND'

    scp:
    scp SRC DEST
    -r
    -a
    scp SERNAME@HOST:/path/to/somefile /path/to/lcoal
    scp /path/to/local USERNAME@HOST:/path/to/file

    ssh-keygen
    -t rsa
    ~/.ssh/id_rsa
    ~/.ssh/id_rsa.pub
    -f /path/to/KEY_FILE
    -P '':指定加密私钥的密码

    公钥追加到远程主机某用户的家目录下的.ssh/anthorized_keys文件或.ssh/authorized_keys2文件中

    ssh-copy-id
    -i ~/.ssh/id_rsa.pub
    ssh-copy-id -i ~/.ssh/id_rsa.pub USERNAME@HOST

    dropbear:嵌入式系统专用的ssh服务器和客户端工具
    服务器端:dropbear
    dropbearkey
    客户端:dbclient

    dropbear默认使用nsswitch实现名称解析
         /etc/nsswitch.conf
         /usr/libnss_files*
         /usr/lib/libnss3.so
         /usr/lib/libnss_files*
    
    dropbear会在用户登录检查其默认shell是否当前系统的安全shell
        /etc/shells

    主机密钥默认位置:
    /etc/dropbear/
    RSA:dropbear_rsa_host_key
    长度可变,只要是8的整数倍,默认为1024
    DSS:dropbear_dss_host_key
    长度固定,默认为1024
    dropbearkey

    tar -zxvf dropbear-2013.56.tar.bz2
    cd dropbear
    ./configure
    make
    make install

    ./bincp.sh dropbear dropbearkey dbclient

    cd /mnt/sysroot/
    vim etc/shells
    /bin/sh
    /bin/bash
    /bin/ash
    /bash/hush

    然后在etc/fstab中加一行加载
    devpts /dev/pts devpts mode=620 0 0

    mkdir /dev/pts

    dropberkey -t rsa -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key -s 2048
    dropberkey -t rsa -f /mnt/sysroot/etc/dropbear/dropbear_dss_host_key -s 2048

    mkdir usr/lib
    cp -d /lib/libnss_files* /mnt/sysroot/lib/
    cp -d /usr/lib/libnss3.so /usr/lib/libnss_files.so /mnt/sysroot/usr/lib/
    ls -l /mnt/sysroot/lib/
    cp /etc/nsswitch.conf /mnt/sysroot/etc

    vim nsswitch.conf
    只需要保留passwd,shadow,group,hosts这几行

    启动小系统,配置IP地址
    /usr/lcoal/sbin/dropbear [-E -F]

    /usr/lcoal/bin/dbclient -l root 172.16.200.1

    vim select.sh
    #! /bin/bash
    PS3="select your will exec memu:"
    select i in apache mysql php
    do
    case $i in
    apache)
    echo "apache"
    ;;
    mysql)
    echo "mysql"
    ;;
    php)
    echo "php"
    ;;
    esac
    done

    bash select.sh

    find . -maxdepth 1 -type f -name ".txt" -mtime +30 30天之前的文件
    find . -maxdepth 1 -type f -name "
    .txt" -mtime -1 一天以内的文件
    find . -maxdepth 1 -size +50M -type f -exec mv {} /tmp/ \;把大于50M的文件移到/tmp

    制作csv格式的文档:
    echo "ip,hostname,cpu,mem,disk" >> 1.csv
    echo "10.30.231.98,localhost,inter,1G,500M,40G" >> 1.csv

    发邮件格式:
    mail -s "邮件主题" -c"抄送地址" -b"密送地址" -f 发送人邮件地址 -F 发件人姓名 收件人地址 < "发邮件的内容"

    转载于:https://blog.51cto.com/12406012/2368182

    展开全文
  • shell编程: 编译器,解释器 编程语言:机器语言、汇编语言、高级语言 ...面向过程Shell,C 面向对象:JAVA,Python,perl,C++ 变量:内存空间,命名 内存:编址的存储单元 变量类型:事先确定数据的存储...

    shell编程:

    编译器,解释器

    编程语言:机器语言、汇编语言、高级语言

    静态语言:编译型语言
    强类型(变量)
    事先转换成可执行格式
    C、C++、JAVA、C#

    动态语言:解释性语言
    弱类型
    边解释边执行
    PHP、SHELL、Python、perl

    面向过程:Shell,C
    面向对象:JAVA,Python,perl,C++

    变量:内存空间,命名

    内存:编址的存储单元

    变量类型:事先确定数据的存储格式和长度
    字符
    数值:整型、浮点型
    布尔:真、假

    逻辑运算:与、或、非、异或

    强类型语言:变量在使用前,必须事先声明,甚至还需要初始化
    弱类型语言:变量用时声明,甚至不区分类型

    变量赋值:VAR_NAME=VALUE

    bash变量类型:
    本地变量(局部变量)
    环境变量
    位置变量
    特殊变量

    本地变量
    VARNAME=VALUE,作用域为整个bash进程
    局部变量:
    local VARNAME=VALUE,作用域为当前代码段

    环境变量:作用域为当前shell进程及其子进程
    export VARNAME=VALUE
    脚本在执行时会启动一个子shell进程
    命令行中启动的脚本会继承当前shell环境变量
    系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量

    引用变量:{VARNAME},括号有时可省略。
    单引号和双引号:
    单引号强引用,双引号弱引用
    字符串内部有变量并且想替换,那就使用双引号
    例子:控制台定义变量ANIMAL=dog
    echo “There are some $ANIMALs.” ,输出结果:There are some .
    echo “There are some ${ANIMAL}s.” ,输出结果:There are some dogs.
    echo ‘There are some ${ANIMAL}s.’ ,输出结果:There are some ${ANIMAL}s.

    位置变量:
    $1,$2,…

    特殊变量:
    $?:显示上一个命令的执行状态返回值
    使用方法:echo $?

    程序执行,可能有两类返回值:
    程序执行结果
    程序状态返回代码(0-255)
    0:正确执行
    1-255:错误执行,1,2,127系统预留

    输出重定向:
    >
    >>
    2>
    2>>
    &>

    /dev/null,软件设备,bit bucket,数据黑洞(重定向到该文件就相当于数据丢弃了)

    撤销变量:
    unset VARNAME

    shebang:魔数
    #!/bin/bash
    #注释行,不执行,shell脚本第一行必须这么写
    which bash,查看bash所在路径位置

    展开全文
  • 九、shell编程

    2017-11-27 15:06:00
    变量初始化:在变量声明的时候给变量一个初始值,初始化...变量赋值:手动给变量空间中存储数据的过程。 变量类型转换:显式、隐式,比如讲字符型转换数值型。 变量类型: 本地变量: set var_name=value u...

    变量初始化:在变量声明的时候给变量一个初始值,初始化相当于给里面放东西。

    变量赋值:手动给变量空间中存储数据的过程。

    变量类型转换:显式、隐式,比如讲字符型转换成数值型。

    变量类型:

         本地变量:   

                              set var_name=value

                              unset var_name

                              ${var_name}

                                       作用范围:当前shell进程。

          局部变量:

                               local var_name=value 

                               unset var_name

                               ${var_name}

                                        作用范围:当前shell进程的局部范围内有效

          环境变量:

                               export var_name=value

                               unse var_name

                               ${var_name}

                                         作用范围:当前shell及其子shell。

           位置变量:$1/$2................

           特殊变量:$$/$?/$#/$@...................

    脚本的写法格式:

             指定脚本运行的shell环境:

                   独立执行脚本的条件: 

                                                       1、要有执行权限。

                                                       2、定义好shebang,及脚本的第一行:#! /path/to/explainer 例如:/bin/bash ,/usr/bin/python。

                                                       3、定义命令的path环境变量。

    bash的配置文件:

     profile:声明环境变量,执行程序脚本 ,/etc/profile,/etc/profile.d/*.sh,~/bash_profile,交互式登陆

    bashrc:定义本地变量、定义命令别名/etc/bashrc,~/.bashrc,非交互式

    脚本文件中,除第一行外其他所有已#开头的行均为注释行。

    练习一、添加一组用户,并且用户名同密码一样。

                   #!/bin/bash

                   #author:gongbing

                   #time :20150731

                   #version:1.0

                   #description:add user 

                   useradd user1

                   echo user1 |passwd --stdin user1&>/dev/null

                   echo "add user1 successful!"

                 

                   useradd user2

                   echo user2 |passwd --stdin user2 >/dev/null

                    echo "add user1 successful!"

                   

                    useradd user3

                    echo user3 |passwd --stdin user3 >/dev/null

                    echo "add user1 successful!"

    编写完毕保存为.sh文件,并赋予执行权限。


    检查脚本的语法错误:

              bash -n 脚本路径/脚本名

                   

    调试执行脚本语法:

               bash -x /path/to/script_file.sh


    变量名称取名规则:

        1、数字、字母、下划线

        2、不能以数字开头

        3、区分大小写

        4、风格统一,见名知意。

    面向过程的编译语言,都有语言控制结构:

     1、顺序执行:默认、逐条执行。

     2、选择执行:依据条件语句判断来选择执行的步骤。 0:真,非零:假

     3、循环执行:依据条件重复执行某一条命令的次数。

    控制语句:

    不同语句写在同一行里需要用分号;隔开。

             bash循环控制语句:

                  for循环:

                      事先提供一个元素列表,然后让变量去遍历(挨个提取)此元素列表;每访问一个元素,执行一次循环体,直至元素遍历完毕。

                          用法: for var_name in 元素列表比如元素1 元素2 元素3

                                       do      

                                               语句1;

                                               语句2;

                                       done

                  while

                  until

    练习二:给练习一调整为循环语句。

                  #!/bin/bash

                      for username in user1 user2 user3;

                       do;

                            useradd $username ;

                            echo $username |passwd --stdin $username;

                        done;

                  

    练习三 、显示/et/inittab,/etc/rc.d/rc.sysinit,/etc/fstab三个文件各有多少行。

                  #!/bin/bash

                  for PathWc in /etc/inittab /etc/rc.d/rc.sysinit /etc/fstab 

                  do

                       cat $PathWc |wc -l 

                  done

    练习:

               1、 使用for循环创建/tmp/1.dir,/tmp/2.dir和/tmp/3.dir,权限为750

                  #!/bin/bash

                  for Direc_Gest in 1.dir 2.dir 3.dir

                  do

                        mkdir /tmp$Dire_Gest

                        chmod 750 /tmp/$Dire_Gest

                   done

               

                 2、统计/etc/fstab、/etc/rc.d/rc.sysinit、/etc/inittab文件中各自以#开头的行的行数和空白行行数。

                       #!/bin/bash

                       for filecount in /etc/fstab /etc/rc.d/rc.sysinit /etc/inttab

                       do

                           egrep ^#|^$ $filecount |wc -l

                       done

                  3、将/etc/passwd 、/etc/shadow的最近一次修改时间改为2010年3月12日14:11 3秒

                        #!/bin/bash

                        for ModfyTime in  /etc/passwd /etc/shadow

                        do 

                             touch -m -t 201003121411.03 $ModfyTime

                        #touch -a 修改访问时间 默认当前时间

                        #touch -m 修改修改时间 当前时间

                        #touch -m -t yymmddhhmm.ss 修改指定时间。

                         done

                  4、将user1、user2、user3加入到testgrp组中,以其为额外组。

                         #!/bin/bash

                         groupadd testgrp

                          for usertogrp in 1 2 3 

                          do

                               usermod -G testgrp user$usertogrp

                           done

                 5、copy /etc/passwd /etc/shadow /etc/inittab 到/tmp/目录下,并将名称已当前时间进行重命名。

                         #!/bin/bash

                         for filerename in  /etc/passwd /etc/shadow /etc/inittab

                            do                     

                                   basefile= `basename $filerename`

                                   cp $filename /tmp/$basefile-`date +%F`

                              done

                    6、显示/etc/paswd文件的第1、3、6、12个用户的用户名、id、基本组的组名。

                       #!/bin/bash

                       for Line in 1 3 6 12 

                        do

                         username=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 1`

                         Idname=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 3`         

                         Groupname='id -gn $username'

                        echo "username:$username idname=$Idname groupname=$Groupname"

                       done

    列表的生成:

            1、逐个列出,例如1 2 3 4

            2、使用通配符列出,例如 /etc/*

                       #!/bin/bash

                       for file in /etc/*

                          do

                              file $file

                           done

              3、使用命令生成列表。

                      #!/bin/bash

                    for File in `ls  /var`

                       do

                            file /var/$File

                       done

               4、生成数字序列,

                                    {}:例如生成1到100的数值,{1..100}

                                equ:equ [起始数字] [步长] [结束数字]


    练习:

               1、取出每个用户的用户名和shell

                         思路:首先需要确定行数

                      #!/bin/bash

                         line=`wc -l /etc/passwd |cut -d : f 1`

                         for Line in equ 1 $line

                         do

                              head -$Line /etc/passwd |tail -1 |cut -d: -f 1,7

                           done


    如何在shell中进行算术运算

     shell不支持浮点数(小数),计算结果中如果有浮点数会被圆整为正数(化零为整)


    默认变量使用的是字符变量类型。实现算数运算的方法:

    1、   $[变量名]=valume

    2、   $((变量名))=valume

    3、 let     例如:let a=$a+$b

    4、 expr  例如:f=`expr $a + $b`


    练习:

               随意声明两个变量,并给出整数值,然后计算他们的加减乘除的结果。

                #!/bin/bash

                Valume1=12

                Valume2=43

                for suanfa   in + - * /

                do

                     echo "$Valume1$suanfa$Valume2= `let $Valume$suanfa$Valume`"

                 done



    选择执行语句

    可以独自执行的命令不需要添加[]来完成测试。

     bash条件测试方式有以下几种:

    1、    [ expression ]:[]里面有空格。表示条件选择的依据。

    2、    ` expression `:

    3、    test  expression:

    4、    bash 命令:

    bash执行命令后有执行结果的状态返回值:echo $? (0表示成功,其他都是错误)

    可以使用exit命令在脚本中自定义脚本执行状态返回值,如果没有定义,脚本执行状态返回值取决于脚本执行结束前的最后一条语句的执行结果。

    判断格式:

       单分支if语句:

      1、 if 条件 ;then

            语句1

            语句2

        fi


    练习: 

            1、查看某用户是否存在,并显示相关信息。

                      #!/bin/bash

                       Username=user1

                       if id $Username &>/dev/null

                           then

                                 echo "$Username is living"

                        fi

            2、如果用户存在,显示用户id和shell信息。

            3、如果一个设备已经挂载,显示挂载点。

            4、  检查某一文件的 的空白行,并统计行数。

                      

      2、if 条件

               then 

                     语句1

                     语句2

                else

                      语句1

                      语句2

             fi


    练习:

              1、检查用户是否存在,并显示相关信息,如果不存在创建用户名,密码。

                      #!/bin/bash

                      Username=zhangliang

                           if id $Username &>/dev/null

                              then

                                 echo "$Username is living"

                                 echo "$Username id&shell is`grep "$Username:" /etc/passwd |cut -d : -f 3,7`"

                              else

                                 useradd $Username

                                echo "no this username,please wait....useradding......   "

                                echo "$Username" |passwd --stdin $Username

                                echo "$Username id&shell is `grep "$Username:" /etc/passwd |cut -d : -f 3,7`"

    fi


    整数测试:

              expression: 数值1 比较符号 数值2

                 比较符号:

                                       -gt:大于号

                                       -ge:大于或等于号

                                       -eq:等于号

                                        -lt:小于号

                                        -le:小于或等于

                                        -ne:不等于

    例如,写一个脚本,随意生成两个整数,比较其大小,显示大数。

    #!/bin/bash

    a=$RANDOM
    b=$RANDOM
    if [$a -gt $b ]
    then
     echo "the max number is $a"
    else
      echo "the max number is $b"
    fi

    2、给定一个整数,判定奇偶性。

    3、给定一个用户,如果其ID号大于499,就显示其为普通用户,否则显示其为管理员。

    4、给定一个用户,如果其uid等于gid,就说明这个是“good guy”否则显示“bad guy”

    #!/bin/bash
    Username=pulse
    if [ `id -u $Username` -eq `id -g $Username` ]
    then
    echo "this user($Username) is good guy! "
    else

    echo "this user($Username) is bad guy!"

       嵌套练习:

                       求200以内的所有为3的整数倍的整数之和

    #!/bin/bash
    sum=0
    for n in {1..100}
    do
      if [ $[$n%3] -eq 0 ]
       then
         sum=$[$sum+$n]
       fi
    done
      echo "300 zhengshu he equal is $sum"

                                        

    bash编程之位置变量

          $1.....$11.......:表示可以通过执行程序,然后加常量的方式来执行并替换程序中的$1等相关变量。

                      $@:表示可以将多个常数按照一个字符串的形式显示出来

                      $*:将多个常数分别以各自字符串的形式显示出来。

                      $#:汇总常数的个数。

                      $0:脚本名称。


                  #!/bin/bash

                    echo $1

                    echo $2

                    echo $@

                    echo $*

                    echo $#


        执行程序:./pos.sh a b c d e

        执行结果:a

                          b 

                          a b c d e

                          a b c d e

                          5

    例:通过参数传递n个正整数给脚本,并求和。

    #!/bin/bash
    Num=0
    Count=0
    for n in $@
    do
      Count=$[$Count+$n]
    done
    echo "Count is $Count"

    shift:对一组数进行重新定位第一个数。shift之前的数被踢掉。

               实现位置参数轮替。

                   #!/bin/bash

                      echo $1

                      shift

                       echo $1

                       shift

                       echo $1

                 执行:./shift.sh a b c d 

                 结果:a 

                            b 

                            c

    练习:

             添加10个用户,需要先判断用户是否存在,如果不存在才添加,统计添加的用户数,并显示总的用户数。

                        

    #!/bin/bash
    countaddu=0
    for n in `seq 1 10`
    do
      if [ `grep "user$n" /etc/passwd` &>/dev/null ]
          then
             echo "old user"
           else
           adduser user$n
           countaddu=$[$countaddu+1]
        fi
    done
    echo "adduser count is $countaddu"
    echo "countuser is :`wc -l /etc/passwd`"

    字符测试:

    文件测试:


    默认变量使用的是字符变量类型。实现算数运算的方法:

    1、   $[变量名]=valume

    2、   $((变量名))=valume

    3、 let     例如:let a=$a+$b

    4、 expr  例如:f=`expr $a + $b`




    — +:对两个变量做加法。

    — -:对两个变量做减法。

    — *:对两个变量做乘法。

    — /:对两个变量做除法。

    — **:对两个变量做幂运算。

    — %:取模运算,第一个变量除以第二个变量求余数。

    — +=:加等于,在自身基础上加第二个变量。

    — -=:减等于,在第一个变量的基础上减去第二个变量。

    — *=:乘等于,在第一个变量的基础上乘以第二个变量。

    — /=:除等于,在第一个变量的基础上除以第二个变量。

    — %=:取模赋值,第一个变量对第二个变量取模运算,再赋值给第一个变量。

     (1)、在括号运算中((i=$j+$k))运算符号两边可以有空格也可以没有空格,但是expr运算i=`expr $j + $k`中运算符号两边必须要有空格!

     (2)、乘法运算符号是 \* ,而不是 * ;除法运算 / 表示整除,1/2=0。

    2、Let expressions  执行一个或多个表达式。

              (1)、表达式中的变量前不必有$.

             (2)、如果表达式中包含了空格或其他特殊字符,则必须引起来。(let i=i+1中除了let后面有一个空格外,其他地方不能有一个空格!)

              例:let “I = I + 1” 或 let i=i+1


    bash脚本的知识点:

     条件测试方式:

        bash命令: 

             [ expression ]

             test expression

             ` expression `

    条件测试的方法:

             整数测试:

                           大于:-gt 

                            小于:-lt

                             等于:-eq

                            大于等于:-ge

                            小于等于:-le

                            不等于:-ne

             字符测试

             文件测试

       命令状态返回值:0 正确

       exit [n] :脚本执行的最后一条命令的状态返回值,

             A37CF6BA45F34E698ECBC0D7B72AC455


    bash字符测试:

       >:大于

       <:小于

       ==:等于

       =~:判定左边的字符串是否能够被右边的模式所匹配,通常使用` `,[]内需要空格。

             模式要求: 一般做行尾、行首锚定($^等),不可以做词尾锚定,不能加引号


       单目操作:一个操作数,

        -z $string:为空则为真,不空为假。

       -n $string:为空则为假,不空为真。

    例子:写一个脚本,判定用户的shell是否为bash。

    #!/bin/bash
    hell=`grep "$1:" /etc/passwd |cut -d : -f 7`
    if [ $hell == "/bin/bash" ]
    then

        echo "this is bash user"

        ret =0

    else

        echo "this is not bash user"

       ret =8

    fi

                                     exit $ret

    bash的特殊参数:$0 scriptsname

    如果脚本是带路径的时候,要提取脚本名使用如下命令:

    basename $0

    2A16B760DEA54E88A846977F2ED9F4EB


    bash编程之位置变量

          $1.....$11.......:表示可以通过执行程序,然后加常量的方式来执行并替换程序中的$1等相关变量。

                      $@:表示可以将多个常数按照一个字符串的形式显示出来

                      $*:将多个常数分别以各自字符串的形式显示出来。

                      $#:汇总常数的个数。

                      $0:脚本名称。  如果是带路径的$0 ,使用basename $0


    AE4D1EF9C640449695FED881FF4A8B2B

    bash知识点:组合条件测试

            -a:与

            -o:或

             !:非 单目操作

    写一个脚本:给定用户,如果其不存在,就退出脚本。

    #!/bin/bash
    if  ! id $1 &>/dev/null
    then
       exit 6
    else
       echo user is exist
    fi

    bash之if多分支语句语法讲解及脚本练习

    多分支if语句

    语法格式:

             if 条件;then

                 语句1

         elif  条件2;then

                  语句1

         elif   条件3;then

                   语句

           else

                  语句

            fi

    练习:

    判断当前主机的cup制造商,其信息在/proc/cpuinfo文件中vendor id 一行。

    如果制造商是genuineintel ,就显示为intel

    如果制造商是authenticamd,就显示amd

    否则,显示无法识别。

    #!/bin/bash

    Vendor=`grep "vendor_id" /proc/cpuinfo |uniq |cut -d : -f 2`

    if [[$Vendor =~ [[ :space: ]]*GenuienIntel$]];

        then

             echo "intel"

    elif [[$Vendor =~ [[ :space: ]]*AuthenticAMD$]];

         then

              echo "AMD"

    fi

    2、通过参数传递给一个脚本参数,如fedora,gentoo,redhat,判断linux发行版所处的发行系列。

         如果为fedora,centos,redhat,就显示为redhat

            [ $1 == fedora -o $1 == centos -o $1 == redhat ]

         如果为suse,opensuse,就显示为suse

        如果是ubuntu,mint、debian,就显示为debian

       否则,显示为其他。

    C392F94B1AC044FCAB081681DF80B10F


    bash测试之文件测试

    方法:操作符  文件路径

    -f:测试其是否是普通文件,即文件类型为-。

     -d:测试其是否为目录文件,文件类型d

     -e:测试文件是否存在,存在为真,否则为假。

     -r:测试文档对当前用户来说是否可读。

    -w:测试文件对当前用户是否可写。

    -x:测试文件是否对当前用户可执行。

    -s:测试文件内容是否为空,不空为真,否则为假。

    -l:测试文件是否是链接文件。

    练习:如果/tmp/test10文件不存在,就创建之:

    if [ ! -e /tmp/test10 ];

    then

          mkdir /tmp/test10

    fi

    短路操作:

    与运算:&& 全真则真 ,有假则假

    或运算:|| 有假则全假,有真则全真

    通过以上运算思路,可以确定如果一个运算的前半部分是真,对于与运算,就需要进行后面的运算才能知道结果是真还是假,如果是用或运算,则知道前面是假可以推断出后面是任何运算都为假,也就没有必要进行后面的运算。这个就是短路运算的思维。

    比如:F06A55A360A34B3D9E334B8A74DB473D

    前面的运算为真,确实存在这个文件,就不会进行后面的操作,如果前面为假,则会进行后面的操作。


    97F6B6A0A05749F1BE79BB904709D456

    1、mkdir /backup

         tar Jcf /backup/etc-`date +%f`.tar.xz /etc/*

    2、tar xf /backup/etc-2013-07-22.tar.xz -C /var/tmp/

    3、               #!/bin/bash 

    comdec=$1 
    if [ -z $comdec ];
    then
        comdec=gzip
    fi
    [ -d /backup ] || mkdir /backup

    if  [ $comdec == 'gzip' ];
    then
        tar zcf /backup/etc-`date +%F-%H-%S`.tar.gz /etc/*
        [ $? -eq 0 ] && echo "backup etc finished.(gzip)"
    elif [ $comdec == 'bzip2' ];
    then
        tar jcf /backup/etc-`date +%F-%H-%S`.tar.bz2 /etc/*
        [ $? -eq 0] && echo "backup etc finished.(bzip2)"
    elif [ $comdec == 'xz' ];
    then
        tar Jcf /backup/etc-`date +%F-%H-%S`.tar.xz /etc/*
        [ $? -eq 0 ] && echo "backup etc finished.(xz)"
    else
        echo "usage: `basename $0` {[gzip|bzip2|xz]}"
        exit 6
    fi

    bash编程之CASE语句:

    case 变量引用(${}) in value1)

         语句

         ;;

    value2)

    语句

    ;;

    value3)

    语句

    ;;

    *)

    语句

    esac
    #!/bin/bash

    if [ -z $comdec ];
    then
        comdec=gzip
    fi
    [ -d /backup ] || mkdir /backup

    case  $comdec in
    gzip)
        tar zcf /backup/etc-`date +%F-%H-%S`.tar.gz /etc/*
        Retval=$?
        ;;
    bzip2)
        tar jcf /backup/etc-`date +%F-%H-%S`.tar.bz2 /etc/*
        Retval=$?
        ;;
    xz)
        tar Jcf /backup/etc-`date +%F-%H-%S`.tar.xz /etc/*
        Retval=$?
        ;;
    *)
        echo "usage: `basename $0` {[gzip|bzip2|xz]}"
        exit 6

        ;;

    esac

     [ $Retval -eq 0] && echo "backup etc finished.($comdec)"


    交互式编程及实例:

    read命令

    可以读取键盘输入数值到变量中

    例如:

    read a b

    2 5

    echo $a

    2

    1、echo -n 表示不换行,结合read一起使用。

    2、read -p “内容” value

    参数:

       -t :设置超时时间

      -p :设置输出说明的内容



    练习: 显示一下菜单内容

    m|M show memory 

    d|D  show disk

    q|Q quit

    2、如果用户选择了第一个选项,在显示内存信息

      如果选择2,显示磁盘挂载及使用情况

      选择3,退出,并显示退出

     其他任何信息,均说明错误。

    #!/bin/bash
    echo "(m|M) SHOW MEMORY"
    echo "d|D show disk"
    echo "q|Q quit"
    echo -n  "please input (m|d|q)" && read choice

    case $choice in
    m|M)
         free -m
         ;;
    d|D)
         df -lh
         ;;
    q|Q)
         echo "you are quit now"
         exit  0
         ;;
    *)
        echo "invalid input"
        exit 5
        ;;
    esac
    ~      

    安全上下文

           用户执行访问某一个文件的时候,涉及到两个内容,第一就是使用的命令,第二就是被访问对象,那么他的安全权限就分别由这两个来决定,如果他没有命令执行权限,被访问对象无法执行,同样如果被访问对象没有访问权限,那么即使他有命令执行权限也是没有用的。

    通过passwd来理解特殊权限。

    s:suid,set uid,属主有s权限,意味着任何用户在执行此程序的时候,其进程的属主不在是发起人本身,而是这个程序的属主。

    chmod u+|- s  /path/to/somefile

    可以通过大小写s来判断这个suid是原来就有的还是后来赋予的,

    s:原来有

    S:后来加

    s:sgid set gid,属组有s权限,意味着执行此程序时,其进程的属组不再是运行者所属的基本组,而是程序的属组。

    chmod g+|- s /path/to/somefile

    t:sticky,黏贴位,附加在other的权限上,表现为t,作用是只有文件所有者可以删除,其他用户不可以删除。

    chmod o+|- t /path/to/somefile 

    chmod 3775  /tmp/test

    练习:

    1、复制/bin/cat为/tmp/cat

         cp /bin/cat /tmp/cat

    2、复制/etc/rc.d/rc.sysinit为/tmp/hello

          cp /bin/rc.d/rc.sysinit /tmp/hello

    3、设定helllo文件的其它用户权限为无权限。

           chmod o-rwx /tmp/hello

    4、切换至普通用户,执行/tmp/cat,查看/tmp/hello,验证是否可查。

           /tmp/cat /tmp/hello   无权限

    5、以root用户身份设定/tmp/cat 具有suid权限,然后用普通用户,查看/tmp/cat,/tmp/hello,并验证。

            chmod u+s /tmp/cat

             /tmp/cat /tmp/hello    成功   如果反过来只修改hello的suid,是不会执行成功的。

    不同命令操作权限不同,结果也不同,总之要求编辑权限既要设置命令权限,也要设置文件权限最好。

    练习二:

    1、创建组magedu

         groupadd magedu

    2、添加用户hadoop和hive,均以magedu为额外组。

          useradd -g magedu hadoo

     

    3、创建目录/tmp/test,并设定其组为magedu。

         mkdir /tmp/test

         chgrp magedu /tmp/test

    4、分别使用两个普通用户在/tmp/test目录创建文件,看权限。

         su hadoo

         touch /tmp/test/123  不成功

    5、设定/tmp/test目录具有写权限。

          chmod g+w /tmp/test

    6、再次分别使用普通用户创建文件,查看权限。如果能,查看文件属组

           touch /tmp/test/123 不成功

    7、设定/tmp/test的属组具有SGID,再次创建并查看。并验证删除操作

           chmod g+s /tmp/test/123 成功

    8、以root设定/tmp/test具有sticky,验证删除操作。

           rm /tmp/test/123 成功

           chmod o+t /tmp/test

           rm /tmp/test/123   不成功,权限不足。

    练习三:

    1、复制/etc/issue为/tmp/issue

         cp /etc/issue /tmp/issue

    2、修改/tmp/issue的权限为属主读写执行,属组读写,其他只读,且具有suid

          chmod 4764 /tmp/issue

    3、复制文件/etc/fstab为/tmp/fstab,修改/tmp/fstab的权限为属主读写执行,属组读,其他只读,且具有sgid和sticky。

           cp /etc/fstab /tmp/fstab

           chmod 3744 /tmp/fstab

    FACL文件访问控制列表

    用于在原有的访问控制机制之外增加一种文件访问控制机制。由于普通用户创建的文件不可以修改自身的权限(chmod)。就可以使用acl来限制其他用户的访问。

    1、通过getfacl可以查看文件的权限。

    getfacl /tmp/test/123

    2、通过setfacl设置文件的访问权限。

      -m, --modify=acl        modify the current ACL(s) of file(s)              

      setfacl -m u:username:mode /path/to/file    #为用户username设定具有mode的权限

      setfacl -m g:groupname:mode /path/to/file     #为组groupname设定具有mode的权限

      -M, --modify-file=file  read ACL entries to modify from file

      -x, --remove=acl        remove entries from the ACL(s) of file(s)

      setfacl -x u:username /path/to/file           #取消某一个用户的acl权限。

      -X, --remove-file=file  read ACL entries to remove from file

      -b, --remove-all        remove all extended ACL entries

      -k, --remove-default    remove the default ACL

          --set=acl           set the ACL of file(s), replacing the current ACL

          --set-file=file     read ACL entries to set from file

          --mask              do recalculate the effective rights mask

      -n, --no-mask           don't recalculate the effective rights mask

      -d, --default           operations apply to the default ACL

      -R, --recursive         recurse into subdirectories

      -L, --logical           logical walk, follow symbolic links

      -P, --physical          physical walk, do not follow symbolic links

          --restore=file      restore ACLs (inverse of `getfacl -R')

          --test              test mode (ACLs are not modified)

      -v, --version           print version and exit

      -h, --help              this help text

    对于新加入的磁盘默认情况下是不支持acl功能的,需要通过在挂载的时候添加挂载选项-o acl才可以。

    比如:

               mount -o acl /dev/sdb1 /mnt/sdb1

    C52B1FFEF2D14BFBB191FA633168CE03

    拒绝hive用户对文件的任何访问

    setfacl -m u:hive:---  /tmp/test/123   设置后即使o有权限也是不能访问的。

    bash编程之while和until

    while 测试条件;

    do

    语句

    done

    条件满足时就循环,直到条件不再满足,就退出循环。

    补充:

    算数运算符

    count=$[$count+$i]  等于  count+=$i

    sum=$[$sum+1]  等于  let sum++

    类似的 let sum-- 现加后引用

               let --sum  先引用后加


    计算100以内正整数的和

    #!/bin/bash

    sum=0

    for i in {1..100};

    do

    sum+=$i

    done

    echo $sum


    #!/bin/bash

    sum=0

    count=1

    while [ $count -le 100];

    do

    sum+=$count

    let count++

    done


    练习:如果用户的id号是偶数,就显示其名称和shell,对所有用户执行此操作。

    while read line ;

    do

    uid=`echo $line |cut -d: -f 3`

    if [ $[$uid%2 ] -eq 0 ];

    then

     echo $line | cut -d: -f 1,7

    fi

    done < /etc/passwd


    练习:转换用户输入的字符为大写,除了quit(遇见quit退出)

    #!/bin/bash

    String

    read -p "A string:" String

    while[ "$String" != 'quit' ];       #引号 用于带空格的字符串转换

    do

    echo $String |tr 'a-z' 'A-Z'

    read -p "next(QUIT for quiting)"  String

    done


    until 测试条件;

    do

    语句

    done

    条件不满足就循环,满足则不循环。


    练习:每个10秒查看hadoo用户是否登陆,如果登陆,显示登陆并退出,否则,显示时间,并说明未登陆。

    until who |grep "hadoo" &>/dev/null ;

    do

    date

    sleep 10

    done

    echo “hadoo is here”


    程序在循环过程中不在执行循环体上面的内容了,所有需要继续执行循环体外的内容,需要将其写在循环体里面。




    本文转自 blackstome 51CTO博客,原文链接:http://blog.51cto.com/137783/1916955,如需转载请自行联系原作者

    展开全文
  • 前言 之前手机里管理密码的脚本,都是直接编写进纯文本然后进行多次归档及压缩来实现...对称加密的加密过程使用秘钥将明文转换密文,而解密过程则使用同个秘钥将密文转换明文,而最简单的实现就是利用位运算中...

    前言

    之前手机里管理密码的脚本,都是直接编写进纯文本然后进行多次归档及压缩来实现不明文存储,一直觉得不太安全,于是昨天晚上编写脚本实现了简单的文件对称加密。

    网上文章都利用 openssl 来进行文件加解密,这不符合在手机上运行的需要,所以必须自己编写文件的对称加密。

    核心原理解析

    对称加密的加密过程使用秘钥将明文转换成密文,而解密过程则使用同个秘钥将密文转换成明文,而最简单的实现就是利用位运算中的亦或运算。

    例如下面是一字节明文数据 src 利用一字节秘钥 key 进行亦或运算,生成一字节密文 dst 的过程。

    src 1010 1000
    key 1100 1000
    dst 0110 0000

    下面则是利用秘钥对密文进行解密的过程,同样也是利用亦或运算。

    dst 0110 0000 
    key 1100 1000
    src 1010 1000

    上面介绍的是最核心的原理,下面先讨论密钥和文件数据的读写,再来介绍整个加密过程。

    不定长密钥

    为了使得密钥更安全,所以采用不定的长度,但为了后续编写代码方便,就需要使用摘要算法将不定长密钥映射到统一长度,代码中选择了 md5 算法。

    下面代码使用 md5sum 命令来获取密钥的 md5 值,注意由于 md5sum 得到的输出包含 -(两个空格)字段加原始值,所以最后一步截取了 md5 值部分。

    password="password" # enter your password
    md5=`echo -n "${password}"|md5sum`
    md5=${md5%  -*}

    文件数据的读写

    hexdump 命令可以很方便的来读取文件,并输出自定义的格式,下面就是代码中用来读取文件的命令。

    hexdump -e '16/1 "%02x" "|"' ${input_file}

    这里 -e 选项后面的格式化字符串 '16/1 "%02x" "|"' ,表示每一个字节的输出格式为 %02x 即用两位十六进制表示一字节,而每十六字节就输出 | 字符,这是为了后面分割用的,也可以用别的分割字符串代替。

    直接利用 echo 命令的 -e 选项,就可以输出十六进制数据,例如下面的例子。

    echo -ne "\x41" > ${output_file} # output ASCII character 'A'

    整体过程

    上面谈到利用 md5 算法将密钥映射到统一的 16 字节的值,所以只需要明文数据的每 16 个字节中的每个字节,与密钥 16 字节的 md5 值中的每个字节进行亦或运算,就可以进行加密,然后利用上面谈到的方式进行输出即可,而解密过程只需将明文数据换成密文数据即可。

    后话

    通过这个简单的脚本,会发现计算机世界真的很简单也很奇妙,一个位运算就对数据实现数据的加解密,而且数据无非就是零与壹,代码所做的就是操作这些零与壹。

    完整代码见笔者的 Github,由于编写仓促代码质量很差,后面会专门写一个密码管理的脚本然后优化下这个脚本。

    转载于:https://www.cnblogs.com/linzhehuang/p/10738281.html

    展开全文
  • 然后上传到Unix下(测试),但是通常情况下工具保存的是dos格式,上传上去后往往会出现一些问题(如ClearCase下下来后都增加了换行,Oracle存储过程、Unix Shell不能运行等),于是我们就需要将格式转换unix格式再...
  • 第二十天

    2016-07-31 17:21:25
    机器语言、汇编语言、高级语言静态语言:编译型语言 强类型(变量) 事先转换可执行格式 C、C++、JAVA、C# 动态语言:解释型语言,on the fly 弱类型 边解释边执行 PHP、SHELL、Python、perl面向过程shell,c...
  • 编程语言

    2018-12-24 11:08:35
    静态语言 事先转换可执行格式 C语言 ,c++ ,JAVA ,C#动态语言 边解释边执行 ASP ,PHP,SHELL ,Python,perl脚本需要解释器 ,易上手shell 功能最简单,python 高级编程能力 脚本编程面向过程 :C ,Perl linux是...
  • 标记

    2013-02-16 22:19:55
    争取能够将计算模块做全oracle型,学习linux c编程和linux shell的一些东西,执行一些装束的dump方式。 现在我把基本的sql增删改查的基本语言,分组,存储过程,等过了一遍。接下来可以是学习一些行列,mo
  • 一:SQL如何备份到异机 () 写成存储过程,建立作业定时备份 <br />1. --在sql中建个映射 exec master..xp_cmdshell 'net use z: //本地计算机名或IP/本地共享文件夹的共享名 "密码" /user...
  • 2.现在每天18点 ,生产系统会抽一批数据利用shell脚本传递给B,然后系统B解析入库,然后经过mysql简单的存储过程处理 3.每天凌晨1点,生产系统D会将全部的生产数据从oracle中抽txt文件,上传FTP,运营系统会从...
  • Unix/Linux 编程实践教程.PDF

    千次下载 热门讨论 2010-09-03 18:34:12
    4.3.4 文件系统的实现:创建一个文件的过程 4.3.5 文件系统的实现:目录的工作过程 4.3.6 文件系统的实现:cat 命令的工作原理 4.3.7 i- 节点和大文件 4.3.8 Unix 文件系统的改进 4.4 理解目录 4.4.1 理解...
  • linux 面试题

    2019-04-01 15:44:44
    节点号,通过该 i 节点的磁盘地址表把分散存放的文件物 理块连接文件的逻辑结构。 l 2.简述进程的启动、终止的方式以及如何进行进程的查看。 参考答案: 在 Linux 中启动一个进程有手工启动和调度启动两种方式: ...
  • delphi 开发经验技巧宝典源码

    热门讨论 2010-08-12 16:47:23
    0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 0040 如何实现类的形 26 0041 如何实现数据加密与解密算法 27 0042 如何继承父类的方法 27 0043 如何实现函数重载 28 0044 类中多态的应用 28 0045 将函数作为参数进行调用 30 2.3 参数与指针 30 ...
  • 多道程序设计的基础:是将运行过程进一步细化几个小的步骤,从而实现宏观上的并行。但从微观上看,内存中的多道程序轮流地或分时地占用处理机,交替执行。 多道程序系统 ≠ 多重处理系统 ≠ 多用户 ≠ 多...
  • 实例175 使用Shell函数打开记事本 实例176 获取系统环境信息 实例177 掷骰子 实例178 倒计时程序 实例179 数字时钟 实例180 文本加密与解密 实例181 我的计算器 实例182 幸运抽奖 实例183 自制闹钟 实例184...
  • 实例175 使用Shell函数打开记事本 实例176 获取系统环境信息 实例177 掷骰子 实例178 倒计时程序 实例179 数字时钟 实例180 文本加密与解密 实例181 我的计算器 实例182 幸运抽奖 实例183 自制闹钟 实例184...
  • 3.8.6 Korn shell编程中的流控制结构 53 3.9 管理UNIX进程 55 3.9.1 用ps命令收集进程信息 55 3.9.2 在注销后运行进程 56 3.9.3 在后台执行进程 56 3.9.4 用kill命令终止进程 56 3.10 UNIX系统管理和...
  • Apache HBase: 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群 HBase入门————《HBase不睡觉》 《HBase实战》见下方ebook 一条数据...
  • Invoke:用于管理面向 shell 的子进程,同时支持将可执行的 Python 代码组织命令行可调用的状态。 tmuxp: tmux 会话管理器。 高级 CLI httpie:一个命令行 HTTP 客户端,cURL 的替代品,易用性更好。 i...
  • 新版Android开发教程.rar

    千次下载 热门讨论 2010-12-14 15:49:11
    程序可以采用 JAVA 开发,但是因为它的虚拟机 (Virtual Machine) Dalvik ,是将 JAVA 的 bytecode 转成 自 己的格式,回避掉需要付给 SUN 有关 JAVA 的授权费用。 对手机制造者的影响 � Android 是款开源的移动计算...
  • 存储引擎方面,为了提升大规模集群的稳定性和性能,TiDB 优化了 Raft 的流程,引入 Region Merge、Raft Learner 等新特性;优化热点调度机制,统计更多的信息,并根据这些信息做更合理的调度;优化 RocksDB 的性能...
  • 本书是高清扫描版的,但正文的内容已经过文字识别软件识别文字的了,大部分的字正确地识别出来了,可以直接复制文字内容。 本书部分目录如下,太多了,只列出了大部分: 第1篇 求职准备和技巧 第1章 了解面试--...
  • 应用案例 - 华氏温度转换摄氏温度 / 输入圆的半径计算周长和面积 / 输入年份判断是否是闰年 Day03 - 分支结构 分支结构的应用场景 - 条件 / 缩进 / 代码块 / 流程图 if语句 - 简单的if / if-else结构 / if-...
  • 我已经建立了用majordomo、MUSH(Mail User’s Shell)和少量Perl、awk及shell脚本来管理邮件列表的存储结构。我实现了一个CGI的web接口,允许用户搜索这个列表和其它用户的信息,其内部使用了grep。然后相继出现了...

空空如也

空空如也

1 2 3
收藏数 50
精华内容 20
关键字:

存储过程转成shell