美文网首页Shell
六试Ubuntu-Shell脚本

六试Ubuntu-Shell脚本

作者: 壮士干了这碗皮蛋瘦肉粥 | 来源:发表于2015-11-08 20:27 被阅读235次

    随意读:

    Linux Kernel 4.3发布,4.4将会是LTS版本 - Linux 4.3

    程序员崩溃:2.55乘100结果竟不是255 - 二进制


    Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。

    它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Unix/Linux系统的关键。

    下面介绍两个有意思的shell命令

    1. 循环广播(广播轰炸)

    #!/bin/sh

    while true

    do

    echo wall hi

    done

    执行以上shell命令,只要电脑连接一台服务器,就可以无限度广播下去,按Ctrl+C即可终止。稍加修改

    #!/bin/sh

    while true

    do

    echo write 6000 hi

    done

    即可指定对一个人推送消息(以此来报复)

    2. shell脚本上的俄罗斯方块(Linux下shell脚本制作俄罗斯方块游戏 )

    将网站内代码复制到 .sh 脚本中随后运行

    就可以体验一下阔别依旧的俄罗斯方块了。

    此外还有许多shell下的小游戏例如扫雷一类的,大家可以自己搜搜看


    参考来源:

    Linux Shell脚本教程:30分钟玩转Shell脚本编程_Shell中文网

    #!/bin/bash

    # Tetris Game

    # 10.21.2003 xhchen< [email]xhchen@winbond.com.tw[/email]>

    #APP declaration

    APP_NAME="${0##*[\\/]}"

    APP_VERSION="1.0"

    #颜色定义

    cRed=1

    cGreen=2

    cYellow=3

    cBlue=4

    cFuchsia=5

    cCyan=6

    cWhite=7

    colorTable=($cRed$cGreen$cYellow$cBlue$cFuchsia$cCyan$cWhite)

    #位置和大小

    iLeft=3

    iTop=2

    ((iTrayLeft=iLeft+2))

    ((iTrayTop=iTop+1))

    ((iTrayWidth=10))

    ((iTrayHeight=15))

    #颜色设置

    cBorder=$cGreen

    cScore=$cFuchsia

    cScoreValue=$cCyan

    #控制信号

    #改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;

    #当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。

    sigRotate=25

    sigLeft=26

    sigRight=27

    sigDown=28

    sigAllDown=29

    sigExit=30

    #七中不同的方块的定义

    #通过旋转,每种方块的显示的样式可能有几种

    box0=(00011011)

    box1=(0212223210111213)

    box2=(0001111201101120)

    box3=(0102101100101121)

    box4=(01021121101112220111202100101112)

    box5=(01112122101112200001112102101112)

    box6=(01111221101112210110112101101112)

    #所有其中方块的定义都放到box变量中

    box=(${box0[@]}${box1[@]}${box2[@]}${box3[@]}${box4[@]}${box5[@]}${box6[@]})

    #各种方块旋转后可能的样式数目

    countBox=(1222444)

    #各种方块再box数组中的偏移

    offsetBox=(013571115)

    #每提高一个速度级需要积累的分数

    iScoreEachLevel=50#be greater than 7

    #运行时数据

    sig=0#接收到的signal

    iScore=0#总分

    iLevel=0#速度级

    boxNew=()#新下落的方块的位置定义

    cBoxNew=0#新下落的方块的颜色

    iBoxNewType=0#新下落的方块的种类

    iBoxNewRotate=0#新下落的方块的旋转角度

    boxCur=()#当前方块的位置定义

    cBoxCur=0#当前方块的颜色

    iBoxCurType=0#当前方块的种类

    iBoxCurRotate=0#当前方块的旋转角度

    boxCurX=-1#当前方块的x坐标位置

    boxCurY=-1#当前方块的y坐标位置

    iMap=()#背景方块图表

    #初始化所有背景方块为-1, 表示没有方块

    for((i=0;i

    #接收输入的进程的主函数

    functionRunAsKeyReceiver()

    {

    localpidDisplayerkeyaKeysigcESCsTTY

    pidDisplayer=$1

    aKey=(000)

    cESC=`echo-ne"\033"`

    cSpace=`echo-ne"\040"`

    #保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。

    #如果在read -s时程序被不幸杀掉,可能会导致终端混乱,

    #需要在程序退出时恢复终端属性。

    sTTY=`stty-g`

    #捕捉退出信号

    trap"MyExit;"INTTERM

    trap"MyExitNoSub;"$sigExit

    #隐藏光标

    echo-ne"\033[?25l"

    while:

    do

    #读取输入。注-s不回显,-n读到一个字符立即返回

    read-s-n1key

    aKey[0]=${aKey[1]}

    aKey[1]=${aKey[2]}

    aKey[2]=$key

    sig=0

    #判断输入了何种键

    if[[$key==$cESC&&${aKey[1]}==$cESC]]

    then

    #ESC键

    MyExit

    elif[[${aKey[0]}==$cESC&&${aKey[1]}=="["]]

    then

    if[[$key=="A"]];thensig=$sigRotate#<向上键>

    elif[[$key=="B"]];thensig=$sigDown#< 向下键>

    elif[[$key=="D"]];thensig=$sigLeft#< 向左键>

    elif[[$key=="C"]];thensig=$sigRight#< 向右键>

    fi

    elif[[$key=="W"||$key=="w"]];thensig=$sigRotate#W, w

    elif[[$key=="S"||$key=="s"]];thensig=$sigDown#S, s

    elif[[$key=="A"||$key=="a"]];thensig=$sigLeft#A, a

    elif[[$key=="D"||$key=="d"]];thensig=$sigRight#D, d

    elif[["[$key]"=="[]"]];thensig=$sigAllDown#空格键

    elif[[$key=="Q"||$key=="q"]]#Q, q

    then

    MyExit

    fi

    if[[$sig!=0]]

    then

    #向另一进程发送消息

    kill-$sig$pidDisplayer

    fi

    done

    }

    #退出前的恢复

    functionMyExitNoSub()

    {

    localy

    #恢复终端属性

    stty$sTTY

    ((y=iTop+iTrayHeight+4))

    #显示光标

    echo-e"\033[?25h\033[${y};0H"

    exit

    }

    functionMyExit()

    {

    #通知显示进程需要退出

    kill-$sigExit$pidDisplayer

    MyExitNoSub

    }

    #处理显示和游戏流程的主函数

    functionRunAsDisplayer()

    {

    localsigThis

    InitDraw

    #挂载各种信号的处理函数

    trap"sig=$sigRotate;"$sigRotate

    trap"sig=$sigLeft;"$sigLeft

    trap"sig=$sigRight;"$sigRight

    trap"sig=$sigDown;"$sigDown

    trap"sig=$sigAllDown;"$sigAllDown

    trap"ShowExit;"$sigExit

    while:

    do

    #根据当前的速度级iLevel不同,设定相应的循环的次数

    for((i=0;i<21-iLevel;i++))

    do

    sleep0.02

    sigThis=$sig

    sig=0

    #根据sig变量判断是否接受到相应的信号

    if((sigThis==sigRotate));thenBoxRotate;#旋转

    elif((sigThis==sigLeft));thenBoxLeft;#左移一列

    elif((sigThis==sigRight));thenBoxRight;#右移一列

    elif((sigThis==sigDown));thenBoxDown;#下落一行

    elif((sigThis==sigAllDown));thenBoxAllDown;#下落到底

    fi

    done

    #kill -$sigDown $$

    BoxDown#下落一行

    done

    }

    #BoxMove(y, x), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以

    functionBoxMove()

    {

    localjixyxTestyTest

    yTest=$1

    xTest=$2

    for((j=0;j<8;j+=2))

    do

    ((i=j+1))

    ((y=${boxCur[$j]}+yTest))

    ((x=${boxCur[$i]}+xTest))

    if((y<0||y>=iTrayHeight||x<0||x>=iTrayWidth))

    then

    #撞到墙壁了

    return1

    fi

    if((${iMap[y*iTrayWidth+x]}!=-1))

    then

    #撞到其他已经存在的方块了

    return1

    fi

    done

    return0;

    }

    #将当前移动中的方块放到背景方块中去,

    #并计算新的分数和速度级。(即一次方块落到底部)

    functionBox2Map()

    {

    localjixyxpypline

    #将当前移动中的方块放到背景方块中去

    for((j=0;j<8;j+=2))

    do

    ((i=j+1))

    ((y=${boxCur[$j]}+boxCurY))

    ((x=${boxCur[$i]}+boxCurX))

    ((i=y*iTrayWidth+x))

    iMap[$i]=$cBoxCur

    done

    #消去可被消去的行

    line=0

    for((j=0;j

    do

    for((i=j+iTrayWidth-1;i>=j;i--))

    do

    if((${iMap[$i]}==-1));thenbreak;fi

    done

    if((i>=j));thencontinue;fi

    ((line++))

    for((i=j-1;i>=0;i--))

    do

    ((x=i+iTrayWidth))

    iMap[$x]=${iMap[$i]}

    done

    for((i=0;i

    do

    iMap[$i]=-1

    done

    done

    if((line==0));thenreturn;fi

    #根据消去的行数line计算分数和速度级

    ((x=iLeft+iTrayWidth*2+7))

    ((y=iTop+11))

    ((iScore+=line*2-1))

    #显示新的分数

    echo-ne"\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore}         "

    if((iScore%iScoreEachLevel

    then

    if((iLevel<20))

    then

    ((iLevel++))

    ((y=iTop+14))

    #显示新的速度级

    echo-ne"\033[3${cScoreValue}m\033[${y};${x}H${iLevel}        "

    fi

    fi

    echo-ne"\033[0m"

    #重新显示背景方块

    for((y=0;y

    do

    ((yp=y+iTrayTop+1))

    ((xp=iTrayLeft+1))

    ((i=y*iTrayWidth))

    echo-ne"\033[${yp};${xp}H"

    for((x=0;x

    do

    ((j=i+x))

    if((${iMap[$j]}==-1))

    then

    echo-ne"  "

    else

    echo-ne"\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m[]\033[0m"

    fi

    done

    done

    }

    #下落一行

    functionBoxDown()

    {

    localys

    ((y=boxCurY+1))#新的y坐标

    ifBoxMove$y$boxCurX#测试是否可以下落一行

    then

    s="`DrawCurBox 0`"#将旧的方块抹去

    ((boxCurY=y))

    s="$s`DrawCurBox 1`"#显示新的下落后方块

    echo-ne$s

    else

    #走到这儿, 如果不能下落了

    Box2Map#将当前移动中的方块贴到背景方块中

    RandomBox#产生新的方块

    fi

    }

    #左移一列

    functionBoxLeft()

    {

    localxs

    ((x=boxCurX-1))

    ifBoxMove$boxCurY$x

    then

    s=`DrawCurBox0`

    ((boxCurX=x))

    s=$s`DrawCurBox1`

    echo-ne$s

    fi

    }

    #右移一列

    functionBoxRight()

    {

    localxs

    ((x=boxCurX+1))

    ifBoxMove$boxCurY$x

    then

    s=`DrawCurBox0`

    ((boxCurX=x))

    s=$s`DrawCurBox1`

    echo-ne$s

    fi

    }

    #下落到底

    functionBoxAllDown()

    {

    localkjixyiDowns

    iDown=$iTrayHeight

    #计算一共需要下落多少行

    for((j=0;j<8;j+=2))

    do

    ((i=j+1))

    ((y=${boxCur[$j]}+boxCurY))

    ((x=${boxCur[$i]}+boxCurX))

    for((k=y+1;k

    do

    ((i=k*iTrayWidth+x))

    if((${iMap[$i]}!=-1));thenbreak;fi

    done

    ((k-=y+1))

    if(($iDown>$k));theniDown=$k;fi

    done

    s=`DrawCurBox0`#将旧的方块抹去

    ((boxCurY+=iDown))

    s=$s`DrawCurBox1`#显示新的下落后的方块

    echo-ne$s

    Box2Map#将当前移动中的方块贴到背景方块中

    RandomBox#产生新的方块

    }

    #旋转方块

    functionBoxRotate()

    {

    localiCountiTestRotateboxTestjis

    iCount=${countBox[$iBoxCurType]}#当前的方块经旋转可以产生的样式的数目

    #计算旋转后的新的样式

    ((iTestRotate=iBoxCurRotate+1))

    if((iTestRotate>=iCount))

    then

    ((iTestRotate=0))

    fi

    #更新到新的样式, 保存老的样式(但不显示)

    for((j=0,i=(${offsetBox[$iBoxCurType]}+$iTestRotate)*8;j<8;j++,i++))

    do

    boxTest[$j]=${boxCur[$j]}

    boxCur[$j]=${box[$i]}

    done

    ifBoxMove$boxCurY$boxCurX#测试旋转后是否有空间放的下

    then

    #抹去旧的方块

    for((j=0;j<8;j++))

    do

    boxCur[$j]=${boxTest[$j]}

    done

    s=`DrawCurBox0`

    #画上新的方块

    for((j=0,i=(${offsetBox[$iBoxCurType]}+$iTestRotate)*8;j<8;j++,i++))

    do

    boxCur[$j]=${box[$i]}

    done

    s=$s`DrawCurBox1`

    echo-ne$s

    iBoxCurRotate=$iTestRotate

    else

    #不能旋转,还是继续使用老的样式

    for((j=0;j<8;j++))

    do

    boxCur[$j]=${boxTest[$j]}

    done

    fi

    }

    #DrawCurBox(bDraw), 绘制当前移动中的方块, bDraw为1, 画上, bDraw为0, 抹去方块。

    functionDrawCurBox()

    {

    localijtbDrawsBoxs

    bDraw=$1

    s=""

    if((bDraw==0))

    then

    sBox="\040\040"

    else

    sBox="[]"

    s=$s"\033[1m\033[7m\033[3${cBoxCur}m\033[4${cBoxCur}m"

    fi

    for((j=0;j<8;j+=2))

    do

    ((i=iTrayTop+1+${boxCur[$j]}+boxCurY))

    ((t=iTrayLeft+1+2*(boxCurX+${boxCur[$j+1]})))

    #\033[y;xH, 光标到(x, y)处

    s=$s"\033[${i};${t}H${sBox}"

    done

    s=$s"\033[0m"

    echo-n$s

    }

    #更新新的方块

    functionRandomBox()

    {

    localijt

    #更新当前移动的方块

    iBoxCurType=${iBoxNewType}

    iBoxCurRotate=${iBoxNewRotate}

    cBoxCur=${cBoxNew}

    for((j=0;j<${#boxNew[@]};j++))

    do

    boxCur[$j]=${boxNew[$j]}

    done

    #显示当前移动的方块

    if((${#boxCur[@]}==8))

    then

    #计算当前方块该从顶端哪一行"冒"出来

    for((j=0,t=4;j<8;j+=2))

    do

    if((${boxCur[$j]}

    done

    ((boxCurY=-t))

    for((j=1,i=-4,t=20;j<8;j+=2))

    do

    if((${boxCur[$j]}>i));theni=${boxCur[$j]};fi

    if((${boxCur[$j]}

    done

    ((boxCurX=(iTrayWidth-1-i-t)/2))

    #显示当前移动的方块

    echo-ne`DrawCurBox1`

    #如果方块一出来就没处放,Game over!

    if!BoxMove$boxCurY$boxCurX

    then

    kill-$sigExit${PPID}

    ShowExit

    fi

    fi

    #清除右边预显示的方块

    for((j=0;j<4;j++))

    do

    ((i=iTop+1+j))

    ((t=iLeft+2*iTrayWidth+7))

    echo-ne"\033[${i};${t}H        "

    done

    #随机产生新的方块

    ((iBoxNewType=RANDOM%${#offsetBox[@]}))

    ((iBoxNewRotate=RANDOM%${countBox[$iBoxNewType]}))

    for((j=0,i=(${offsetBox[$iBoxNewType]}+$iBoxNewRotate)*8;j<8;j++,i++))

    do

    boxNew[$j]=${box[$i]};

    done

    ((cBoxNew=${colorTable[RANDOM%${#colorTable[@]}]}))

    #显示右边预显示的方块

    echo-ne"\033[1m\033[7m\033[3${cBoxNew}m\033[4${cBoxNew}m"

    for((j=0;j<8;j+=2))

    do

    ((i=iTop+1+${boxNew[$j]}))

    ((t=iLeft+2*iTrayWidth+7+2*${boxNew[$j+1]}))

    echo-ne"\033[${i};${t}H[]"

    done

    echo-ne"\033[0m"

    }

    #初始绘制

    functionInitDraw()

    {

    clear

    RandomBox#随机产生方块,这时右边预显示窗口中有方快了

    RandomBox#再随机产生方块,右边预显示窗口中的方块被更新,原先的方块将开始下落

    localit1t2t3

    #显示边框

    echo-ne"\033[1m"

    echo-ne"\033[3${cBorder}m\033[4${cBorder}m"

    ((t2=iLeft+1))

    ((t3=iLeft+iTrayWidth*2+3))

    for((i=0;i

    do

    ((t1=i+iTop+2))

    echo-ne"\033[${t1};${t2}H||"

    echo-ne"\033[${t1};${t3}H||"

    done

    ((t2=iTop+iTrayHeight+2))

    for((i=0;i

    do

    ((t1=i*2+iLeft+1))

    echo-ne"\033[${iTrayTop};${t1}H=="

    echo-ne"\033[${t2};${t1}H=="

    done

    echo-ne"\033[0m"

    #显示"Score"和"Level"字样

    echo-ne"\033[1m"

    ((t1=iLeft+iTrayWidth*2+7))

    ((t2=iTop+10))

    echo-ne"\033[3${cScore}m\033[${t2};${t1}HScore"

    ((t2=iTop+11))

    echo-ne"\033[3${cScoreValue}m\033[${t2};${t1}H${iScore}"

    ((t2=iTop+13))

    echo-ne"\033[3${cScore}m\033[${t2};${t1}HLevel"

    ((t2=iTop+14))

    echo-ne"\033[3${cScoreValue}m\033[${t2};${t1}H${iLevel}"

    echo-ne"\033[0m"

    }

    #退出时显示GameOVer!

    functionShowExit()

    {

    localy

    ((y=iTrayHeight+iTrayTop+3))

    echo-e"\033[${y};0HGameOver!\033[0m"

    exit

    }

    #显示用法.

    functionUsage

    {

    cat<

    Usage:$APP_NAME

    Starttetrisgame.

    -h,--helpdisplaythishelpandexit

    --versionoutputversioninformationandexit

    EOF

    }

    #游戏主程序在这儿开始.

    if[["$1"=="-h"||"$1"=="--help"]];then

    Usage

    elif[["$1"=="--version"]];then

    echo"$APP_NAME $APP_VERSION"

    elif[["$1"=="--show"]];then

    #当发现具有参数--show时,运行显示函数

    RunAsDisplayer

    else

    bash$0--show&#以参数--show将本程序再运行一遍

    RunAsKeyReceiver$!#以上一行产生的进程的进程号作为参数

    fi

    相关文章

      网友评论

        本文标题:六试Ubuntu-Shell脚本

        本文链接:https://www.haomeiwen.com/subject/nusqhttx.html