linux shell 编程基础

shell编程基础

  • 创建shell文件的第一行必须是:#!/bin/bash 指明要使用的shell.
  • cat << HELP
    ...
    HELP
    可以用来显示帮助信息等
  • “ (跟波浪线在一块的那个) 执行命令并赋值给变量
  • 设置局部变量
    various=test
  • 设置局部变量为全局变量
    export various
  • 输出重定向
    ls >> a.txt 追加到文件
    ls > a.txt 覆盖到文件
    ls &>> a.txt 所有信息包括错误信息 追加到文件
  • 输入重定向
    cat < test.sh | more
    将test.sh的内容输出终端 并以more的形式显示
  • 使用expr 进行数值计算
    使用反引号 echo `expr 1 \* 2` ==> 2
    使用方括号 echo $[1 * 2] ==> 2
  • 使用bc计算机解决浮点计算的问题
    使用反括号 echo `echo " scale=2;3.44/5" | bc`
    #友好一点,把不同的计算放到不同的行
    var5=`bc << EOF
    scale = 4
    a = 4
    b = 3
    a / b
    EOF
    `
    echo $var5
  • echo $?查看退出状态
  • if-then语句
    if command[;]
    then
    commands
    fi
  • if-then-else语句
    if command
    then
    commands
    else
    commands
    fi
  • 嵌套if语句
    if command1
    then
    commands
    elif command2
    then
    more commands
    fi
  • test命令
    if-then 语句不能测试跟命令的退出状态无关的条件,即if后边所跟随的command必须是要返回退出状态的。
    • 语法1
      if test condition
      then
      commands
      fi
    • 语法2
      if [condition]
      then
      commands
      fi

      []定义test命令中用到的条件,[]左右必须加空格
      test命令可以判断3类条件
      • 数值比较
        • n1 -eq n2 检查n1和n2是否相等
        • n1 -ge n2 大于等于
        • n1 -gt n2 大于
        • n1 -le n2 小于等于
        • n1 -lt n2 小于
        • n1 -ne n2 不等于
      • 字符串比较
        • str1 = str2
        • str1 != str2
        • str1 \< str2
        • str1 \> str2
        • -n str1 检查str1的长度是否非0
        • -z str1 检查str1的长度是否为0
      • 文件比较
        • -d file 检查file是否存在并且是一个目录
        • -e file 检查file是否存在
        • -f file 检查file是否存在并且是一个文件
        • -r file 检查文件是否存在并可读
        • -s file 检查文件是否存在并非空
        • -w file 检查文件是否存在并可写
        • -x file 检查文件是否存在并可执行
        • -O file 检查文件是否存在并属于当前用户
        • -G file 检查文件是否存在并且默认组与当前用户相同
        • file1 -nt file2 检查file1是否比file2新
        • file1 -ot file2 检查file1是否比file2旧
  • 复合条件测试
    [ condition ] && [ condition ]
    [ condition ] || [ condition ]
  • 双圆括号
    (( expression ))
    # 针对数字计算的高级特性

    特性描述
    val++
    val--
    ++val
    --val
    !逻辑求反
    ~位求反
    **幂运算
    <<
    >>
    &
    |
    &&
    ||
  • 双方括号
    [[ expression ]]
    # 针对字符串的高级特性
    # 模式匹配,正则表达式

  • case
    case variable in
    pattern1 | pattern2) command1;;
    parttern3) command2;;
    *) default command3;;
    esac
  • for
    for var in list
    do
    commands
    done

    #默认以“空格 制表符 换行符”作为字段分隔符
    #修改字段分隔符 IFS=”\n”
    #用通配符读取目录
    for file in /home/mmm/ /etc/
    do
    done

    #C风格的for
    for(( i=0,j=10; i<10;i++,j-- ))
    do
    commands
    done

  • while
    while test command
    do
    other command
    done

    当test语句执行后的退出状态为0时才执行do…done

  • until
    until test command
    do
    other command

    当test语句执行后的退出状态非0时才执行do…done
  • break
    跳出for while until内部循环
    break 1
    跳出外部循环
    break 2 (3,4,5。。。。)
  • 处理循环的输出
    for var in ...
    do
    done >> out.txt
  • 读取命令行参数
    $1 $2 $3 $....
  • 读取在执行的程序的名称
    $0
  • 在对命令行参数进行处理之前,最好判断一下用户是否输入了参数
    if [ -n $# ]
    then
    ...
    fi
  • 特殊参数变量
    参数计数:$#
  • 抓取所有数据
    $* 将所有参数当成单个单词保存
    $@ 将所有参数当成一个字符串处理
  • 移动变量
    shift
    默认情况下它会将每个参数变量减1,$3的值会移动到$2. $1的值会被删除,并且无法恢复
    但是$0依旧表示的是当前正在执行的程序的名称
  • 查找简单选项
    while [ -n "$1" ]
    do
    case "$1" in
    -a) echo "";;
    -b) echo "";;
    *) echo "";;
    shift
    done

    并不能识别类似-at类型的参数
  • 分离参数和选项
    while [ -n "$1" ]
    do
    case "$1" in
    -a) echo "Found the -a option";;
    -b) echo "-b option";;
    -c) echo "-c option";;
    # 用--区分参数和选项
    --)shift; break;;
    *) echo "$1 is not an option";;
    esac
    shift
    done
    count=1
    #打印参数
    for param in $@
    do
    echo "Parameter #$count : $param"
    count=$[$count+1]
    done

    并不能识别类似-at类型的参数
  • 处理带值的选项
    while [ -n "$1" ]
    do
    case "$1" in
    -a) echo "Found the -a option";;
    -b)
    param=$2
    echo "Fount the -b option , with parameter value is $param"
    shift 2
    ;;
    -c) echo "-c option";;
    --)shift; break;;
    *) echo "$1 is not an option";;
    esac
    shift
    done
    #打印参数
    count=1
    for param in $@
    do
    echo "Parameter #$count : $param"
    count=$[$count+1]
    done

    并不能识别类似-at类型的参数
  • 使用getopt命令
    getopt options optstring parameters
    其中 optstring定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值
    getopt ab:cd -a -b test1 -cd test2 test3
    解释:ab:cd是命令行有效的选项字母,其中b是需要参数值的,b的参数值是test1,-cd是第二组选项字母,test2 test3是parameters.
  • 在脚本中使用getopt命令
    用set命令将命令行参数替换成set命令的命令行的值
    set -- `getopt -q ab:cd "$@"`
    set -- `getopt ab:cd -ab testb -cd test3 test4`
    while [ -n "$1" ]
    do
    case "$1" in
    -a) echo "Found the -a option";;
    -b)
    param=$2
    echo "Fount the -b option , with parameter value is $param"
    shift 2
    ;;
    -c) echo "-c option";;
    --)shift; break;;
    *) echo "$1 is not an option";;
    esac
    shift
    done
    #打印参数
    count=1
    for param in $@
    do
    echo "Parameter #$count : $param"
    count=$[$count+1]
    done
  • 在脚本中使用getopts命令
    getopts optstring various
    getopt只有一行输出
    getopts有多个输出,对应参数变量的顺序,并且会删除选项前的-号
    #getopts :ab:c opt
    #./abc.sh运行输出:not found -b option
    #getopts ab:c opt
    #./abc.sh运行输出:./abc.sh:选项需要一个参数 -- b \n not found -b option
    while getopts ab:c opt
    do
    case "$opt" in
    a) echo "Found a option";;
    b) echo "Found b option,with parameter value is $OPTARG";;
    c) echo "Fount c option";;
    *) echo "not found $1 option";;
    esac
    done
  • 选项标准化
    # 设置命令行参数的选项时,有一些是已经有固定意义的,如下

    选项描述
    -a显示所有对象
    -c生成一个计数
    -d指定一个目录
    -e扩展一个对象
    -f指定读入数据的文件
    -h显示命令的帮助信息
    -i忽略文本大小写
    -l产生输出的长格式版本
    -n使用非交互模式
    -o指定将所有输出重定向到的输出文件
    -q以安静模式运行
    -r递归地处理目录和文件
    -s以安静模式运行
    -v生成详细输出
    -x删除某个对象
    -y对所有问题回答yes
  • 获得用户输入(read)
    echo -n "Enter your name:"
    read name
    echo "hello $name,XXXX"
    read -p 无需写echo -n "Enter your name:"
    #给输入的数据分配多个变量,如果变量表在数据完成之前用完了,剩余数据分配在最后一个变量中
    read -p "Enter your name:" first last
    echo "Checking data for $first, $last .....
    #如果不在read命令中指定变量,则read命令会将它收到的任何数据都放进特殊环境变量REPLY中
    read -p "Enter your name:"
    factorial=1
    for (( count=1;count<=$REPLY;count++ ))
    do
    factorial=$[ $factorial * $count ]
    done
    echo "阶乘:"$factorial
    #read命令的超时参数-t
    if read -t 5 -p "Please enter your name:" name
    then
    echo "Hello $name,XXX"
    else
    echo "Sorry,too slow!"
    fi
    #read命令对输入的字符计数,当输入的字符打到预设的字符数时,自动退出,将输入的数据赋给变量
    #-n1说明 -n表示对输入的字符计数 1则表示预设的字符的个数,即输入满几个字符时退出read命令
    read -n1 -p "Do you want to continue [Y/N]?" answer
    case $answer in
    Y|y) echo "you can continue";;
    N|n) echo "ok,goodbye";exit;;
    esac
    echo "The End!"
    #隐藏方式读取-s
    #比如密码,不希望其显示在屏幕上.
    read -s -p "Enter you password:" pass
    echo
    echo "Is your password really $pass?"
    #read 读取文件
    #将文件运行cat命令后的输出通过管道直接传给含有read命令的while命令
    count=1
    cat test | while read line
    do
    echo "Line $count:$line"
    (( count++ ))
    done
    echo "The end"

  • 标准文件描述符
    #linux文件描述符是一个非负整数,每个过程一次最多可以有9个文件描述符.
    #bash中保留的仅有三个:

    文件描述符缩写描述
    0STDIN标准输入
    1STDOUT标准输出
    2STDERR标准错误

    # STDIN
    cat : 接收STDIN(键盘)的输入,并显示在终端
    cat < a.txt/cat << a.txt: 接收非STDIN文件的输入,并显示在终端
    #STDOUT
    ls -l:将结果直接显示在终端
    ls -l > a.txt/ls -l >> a.txt:将结果显示在文本文件中

  • 创建本地临时文件
    #6个X自动生成6个随机字母数字,用来保证文件名在目录中是唯一的
    #在当前目录创建
    mktemp test.XXXXXX
    #在/tmp/文件夹创建
    mktemp -t test.XXXXXX

  • 创建临时目录
    mktemp -d dir.XXXXXX
  • 记录消息
    # 将消息显示在STDOUT,并且重定向到filename文件中
    tee filename
    # 默认情况下tee是覆盖的,如果想追加使用-a
    date | tee -a testfile

  • 最常见的linux信号

    信号描述
    1SIGHUP挂起进程
    2SIGINT终止进程
    3SIGQUIT停止进程
    9SIGKILL无条件终止进程
    15SIGTERM可能的话终止进程
    17SIGSTOP无条件停止进程,但不是终止进程
    18SIGTSTP停止或暂停进程,但不终止进程
    19SIGCONT继续运行停止的进程
  • 捕捉信号
    trap commands signals
    #如果脚本收到了trap命令中列出的信号,它会阻止它被shell处理,而在本地处理它.
    #表示其不会被外部处理,只会在当前执行的程序中进行处理
    trap "echo 'Sorry! I have trapped Ctrl-C'" SIGINT SIGTERM

  • 捕捉脚本的退出
    trap "echo byebye" EXIT
    count=1
    while [ $count -le 5 ]
    do
    echo "Loop #$count"
    sleep 3
    count=$[ $count + 1 ]
    done
  • 移除捕捉
    trap "echo byebye" EXIT
    count=1
    while [ $count -le 5 ]
    do
    echo "Loop #$count"
    sleep 3
    count=$[ $count + 1 ]
    done
    trap - EXIT
  • 后台运行脚本
    ./test.sh &
  • 在非控制台下运行脚本
    #如果使用nohup命令,关闭关联会话时,脚本会忽略掉任何终端发送过来的SIGHUP信号
    #由于nohup命令会从终端解除进程的关联,进程会丢掉到STDOUT和STDERR的链接.nohup命令会自动将STDOUT和STDERR的消息重定向到一个名叫nohup.out的文件中.
    nohup ./test1 &
  • 查看作业
    jobs

    参数描述
    -l列出进程的PID以及作业号
    -n只列出上次shell发出的通知后改变了状态的作业
    -p只列出作业的PID
    -r只列出运行中的作业
    -s只列出已经停止的作业
  • 重启停止的作业
    #以后台模式重启一个作业 2是作业号
    bg 2

  • 调整谦让度
    #调度优先级是个整数值,从-20(最高)到+20(最低).默认情况下,bash shell以优先级0来启动所有进程
    #nice命令用来在启动命令时调度优先级.
    #让命令以更低的优先级运行 -n
    #nice命令阻止普通系统用来来增加命令的优先级
    nice -n 10 ./test.sh &
    #renice 指定运行进程的PID来改变它的优先级
    #只能对属于你的进程执行renice
    #只能通过renice降低进程的优先级
    #root用户可以通过renice调整任何进程的优先级到任何级别
    renice 10 -p 28501
  • 定时运行作业
    #at 命令.
    #at的守护进程atd以后台模式运行.
    #atd检查系统上/var/spool/at这个特殊目录,来获取用at命令提交的作业.
    #at命令只执行一次
    at [ -f filename ] time
    #at命令能识别的时间格式
    #1.标准的小时和分钟格式 10:15
    #2.~AM/~PM指示符 10:15~PM
    #3. 特定可命名的时间,now noon,midnight,teatime(4~PM)
    #如果指定一个已经过去了的时间,at命令会在第二天改时间运行改作业
    #4.标准日期格式.MMDDYY MM/DD/YY DD.MM.YY
    #5.文本日期,Jul 4 Dec 25.加不加年份均可
    #6.指定时间增量 当前时间+25 min
    #7. 明天10:15~PM
    #8.10:15+ 7 天
    #列出等待的作业并删除
    #atq列出等待的作业
    #atrm 59 删除
  • 计划定期执行脚本
    #cron时间表
    #可周期性执行
    #假设linux系统是7X24小时运行的,如果关机导致错过了计划作业,则不会再执行
    #格式: min hour dayofmonth month dayofweek command
    # 15 10 1 2 * command
    #以上表示 在2月份的第一天(2月1日)上午10点15分执行
    #在一个月的最后一天执行,通过在每天的12点检查明天是不是下月的第一天.
    # 00 12 * * * if[ `date +%d -d tomorrow`=01 ];then;command
    #构建cron时间表
    # 查看 crontab -l
    #添加时间表 -e
    #当创建的脚本不要求有精确的执行时间时,可以用预配置的cron脚本目录,4个基本目录: hourly daily monthly weekly
  • anacron程序
    #解决cron错过计划作业的问题
    #如果anacron知道作业错过了计划好的运行,它会尽快运行改作业.
    #通常用于进行常规日志维护的脚本
    #只处理位于cron目录的程序,比如/etc/cron.monthly
  • 开机时运行脚本
    #System V init过程
    #red hat系列

    运行级描述
    0关机
    1单用户模式
    2多用户模式,通常不支持网络
    3全功能的多用户模式,支持网络
    4可定义用户
    5多用户模式,支持网络和图形化X Window会话
    6重启

    #debian发行版

    运行级描述
    0关机
    1单用户模式
    2~5多用户模式,支持网络和图形化X Window会话
    6重启

    # 存储运行级别的目录
    # 有的是/etc/rc#.d #代表运行级
    # 有的是/etc/init.d
    # 有的是/etc/init.d/rc.d
    #Upstart init 过程
    #不关注运行级别,而关注时间,比如系统开机.
    #使用/etc/event.d或者/etc/init目录下的文件来启动进程.
    #定义自己的开机脚本
    #linux本地开机文件位置

    发行版文件位置
    debianetc/init.d/rc.local
    Fedora/etc/rc.d/rc.local
    Mandriva/etc/rc.local
    openSuse/etc/init.d/boot.local
    Ubuntu/etc/rc.local

    #在新shell中启动
    # 当新shell是新的登录生成的话,bash shell 会运行.bash_profile文件.
    # 当新shell启动时,包括有新的登录的情况,bash shell会运行.bashrc文件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值