zoukankan      html  css  js  c++  java
  • shell编程学习

    在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash

    #! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

    运行 Shell 脚本有两种方法:

    1、作为可执行程序

    将上面的代码保存为 test.sh,并 cd 到相应目录:

    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本

    注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。

    2、作为解释器参数

    这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:

    /bin/sh test.sh
    /bin/php test.php

    这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

    Shell 变量

    定义变量时,变量名不加美元符号($,PHP语言中变量需要),如:

    your_name="runoob.com"



    使用变量

    使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

    your_name="qinjx"
    echo $your_name
    echo ${your_name}

    变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

    for skill in Ada Coffe Action Java; do
        echo "I am good at ${skill}Script"
    done

    如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

    推荐给所有变量加上花括号,这是个好的编程习惯。

    已定义的变量,可以被重新定义,如:

    your_name="tom"
    echo $your_name
    your_name="alibaba"
    echo $your_name

    这样写是合法的,但注意,第二次赋值的时候不能写$your_name="alibaba",使用变量的时候才加美元符($)。

    Shell 字符串

    字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号。单双引号的区别跟PHP类似。

    单引号

    str='this is a string'

    单引号字符串的限制:

    • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

    双引号

    your_name='runoob'
    str="Hello, I know you are "$your_name"! 
    "
    echo -e $str

    输出结果为:

    Hello, I know you are "runoob"!

    双引号的优点:

    • 双引号里可以有变量
    • 双引号里可以出现转义字符

    拼接字符串

    your_name="runoob"
    # 使用双引号拼接
    greeting="hello, "$your_name" !"
    greeting_1="hello, ${your_name} !"
    echo $greeting  $greeting_1
    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3

    输出结果为:

    hello, runoob ! hello, runoob !
    hello, runoob ! hello, ${your_name} !

    获取字符串长度

    string="abcd"
    echo ${#string} #输出 4

    提取子字符串

    以下实例从字符串第 2 个字符开始截取 4 个字符:

    string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo



    shell脚本例子集锦(习题总结)

     
    练习一:写一个脚本
           1.设定变量FILE的值为/etc/passwd
           2.依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么
            形如:(提示:LINE=`wc -l /etc/passwd | cut -d" " -f1`)
             Hello,root,your UID is 0.
           3.统计一个有多少个用户
         答案一:#!/bin/bash
               file="/etc/passwd"
               LINES=`wc -l $file | cut -d" " -f1`
               for I in `seq 1 $LINES`;do
               userid=`head -$I $file | tail -1 |cut -d: -f3`
               username=`head -$I $file | tail -1 |cut -d: -f1`
               echo "hello $username,your UID is $userid"
               done
               echo "there are $LINES users"
         答案二:#!/bin/bash
               file=/etc/passwd
               let num=0
               for I in `cat $file`;do
               username=`echo "$I" | cut -d: -f1`
               userid=`echo "$I" | cut -d: -f3`
               echo "Hello,$username,your UID is $userid"
               num=$[$num+1]
               done
               echo "there are $num users"
    练习二:写一个脚本
          1.切换工作目录至/var
          2.依次向/var目录中的每个文件或子目录问好,形如:
            (提示:for FILE in /var/*;或for FILE in `ls /var`;)
            Hello,log
          3.统计/var目录下共有多个文件,并显示出来
      答案:#!/bin/bash
             cd /var
             let num=0
             for I in `ls /var/*`;do
             echo "hello $I"
             num=$[$num+1]
             done
             echo "the number of files is $num"
    练习三:写一个脚本
          1.设定变量file的值为/etc/passwd
          2.使用循环读取文件/etc/passwd的第2,4,6,10,13,15行,并显示其内容
          3.把这些行保存至/tmp/mypasswd文件中
      答案:#!/bin/bash
           file="/etc/passwd"
           for I in 2 4 6 10 13 15;do
           exec 3>/tmp/mypasswd
           line=`head -$I $file | tail -1`
           echo "$line"
           echo "$line" >&3
           exec 3>&-
           done
    练习四:写一个脚本
           传递两个整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
            答案如下:vim test.sh
                       #!/bin/bash
                        echo "first number $1"  (表示输出第一个数)
                        echo "second number $2" (表示输出第二个数)
                        echo " $(($1+$2))"      (输出两数之和)
                        echo "$[$1-$2]"         (输出两数之差)
                        echo "$[$1*$2]"         (输出两数之积)
                        echo "$[$1/$2]"         (输出两数之商)
                        :wq                    (表示保存并退出vi编辑器)
                        chmod +x test.sh       (给test.sh执行的权限)
                        ./test.sh 2 3          (传递两个参数并执行脚本     
    作业一:写一个脚本:
           1.创建目录/tmp/scripts
           2.切换工作目录至此目录中
           3.复制/etc/pam.d目录至当前目录,并重命名为test
           4.将当前目录的test及其里面的文件和子目录的属主改为redhat
           5.将test及其子目录中的文件的其它用户的权限改为没有任何权限
       答案:
           #!/bin/bash
           mkdir -v /tmp/scripts
           cd /tmp/scripts
           cp -r /etc/pam.d ./test
           chown -R redhat ./test
           chmod -R o=--- ./test
    作业二:写一个脚本
           1.显示当前系统日期和时间,而后创建目录/tmp/lstest
           2.切换工作目录至/tmp/lstest
           3.创建目录a1d,b56e,6test
           4.创建空文件xy,x2y,732
           5.列出当前目录下以a,x或者6开头的文件或目录
           6.列出当前目录下以字母开头,后跟一个任意数字,而后跟任意长度字符的文件或目录
       答案:
           #!/bin/bash
           date
           mkdir -pv /tmp/lstest
           cd /tmp/lstest
           mkdir a1d b56e 6test
           touch xy x2y 732
           ls [ax6]*
           ls [[:alpha:]][[:digit:]]*
                
    作业三:写一个脚本
            添加10个用户user1到user10,但要求只有用户不存在的情况下才能添加
      答案:
           #!/bin/bash
           for I in `seq 1 10`;do
           cut -d: -f1 /etc/passwd |grep "user$I" 2>>/tmp/etc.err || useradd user$I
           done
    作业四:写一个脚本
           通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线
           如果在线,就显示“ip is up”
           如果不在线,就显示“ip is down”
          答案: #!/bin/bash
           for I in `seq 151 254`;do
           ping -c1 -w1 192.168.0.$I &>/dev/null && echo "192.168.0.$I is up" ||        echo "192.168.0.$I is down"
           done
     
  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/panxuejun/p/10586708.html
Copyright © 2011-2022 走看看