脚本文件基础记录case

以下规则以bash为准!

输入sudo dkpg-reconfigure dash,在跳出的窗口中会提示是否使用dash为默认shell,选No就好了,这样就变成用bash了。

可以按如下方式查看目前使用的是哪种shell。

root@ubuntu:/home/user/shell# echo $0
bash

root@ubuntu:/home/user/shell# echo $SHELL
/bin/bash

Hello,world

写一个hello,world吧。
要注意的地方
  • 使脚本具有执行功能
  • #!解释器
  • 句子后面不需要加";"哦
  • echo会自动换行


变量定义

  • 变量定义的时候变量名以及变量值与=之间不能有空格,否则变量会被认为没定义
  • 变量首字母只能是字母,不能是下划线了哦,不过变量名里边是可以有下划线的
  • 使用$来引用变量,和JavaScript很像哦。最好是都加上{}把变量名包围起来
  • 变量在单引号里边是不起作用的哦,不加引号是起作用的啦
#!/bin/sh
a=1
echo $a
echo '$a'
echo "${a}is 1"

1
$a
1is 1


命令替换

  • 命令执行的结果可以保存在变量里边
  • 命令用··括起来,·符号位于Esc下面
  • 输出的时候如果不用引号把变量包围起来,输出就是一条长行,因为\n不会被认为是换行,所以最好是用引号把变量包围哦
#!/bin/sh
DATE=`date`
echo "Date is $DATE"
LS=`ls -l`
echo Ls "$LS"
user@ubuntu:~/shell$ ./var.sh
Date is Sun Aug 30 03:02:41 PDT 2015
Ls total 8
-rwxrwxr-x 1 user user 30 Aug 30 02:18 first.sh
-rwxrwxr-x 1 user user 68 Aug 30 03:02 var.sh


运算符

  • 加减乘除用`expr 1 + 2`的格式来表示,注意最外面的依然是Esc下面的·,而不是Enter旁边的‘哦!!
  • 1 + 2 表达式1 和 2之间要有空间,要不会被认为是字符串
  • 乘法用\*表示,如果用*。会提示语法错误,好奇怪哦
  • 条件判断用[ ] 括起来,并且[ $a == $b ]这一句,$a 与左边的[ 和邮编的 == 都要有空格, $b同理。
  • 关于等于这一判断,因为linux默认使用dash,而dash是使用=来做等于判断,所以写成==会被认作是没见过的操作符哦
  • 要想使用==来做等于判断,我们就该使用bash,输入sudo dkpg-reconfigure dash,在跳出的窗口中选No就好了。
  • bash可以使用==和=一起做等于判断

#!/bin/sh
a=1
b=1
val=`expr $a + $b`
echo "$a + $b is $val" 
val=`expr 1+2`
echo "1+2=" $val
val=`expr 1 + 2`
echo "1 + 2=" $val
val=`expr 1 - 2`
echo $val
val=`expr 1 / 2`
echo $val
val=`expr 1 * 2`
echo "1 * 2=" $val
val=`expr 1 \* 2`
echo "1 \* 2= $val"
if [ $a = $b ]
then
  echo "$a == $b"
fi
if [ $a != $b ]
then

user@ubuntu:~/shell$ ./var.sh
1 + 1 is 2
1+2= 1+2
1 + 2= 3
-1
0
expr: syntax error
1 * 2=
1 \* 2= 2
1 == 1

字符串

  • 单引号里边的字符串不管是什么,变量也好,转义字符也好,都不会起作用,输出的时候单引号里边的串是什么,输出的就是什么,一丁点都不变哦
  • 好吧,上面这句在实践中出问题了哦,只要我加了-e选项,输出的时候转义字符就会起作用。
  • 双引号里边就算有转义字符,比如\n,但如果不写成echo -e "str",那也不会起作用,要有-e 选项啊啊啊!!!!
#!/bin/sh
a=1
echo -e '$a test\n'
echo -e "$a test\n"
echo -e $a \\n
str="abc"123"d\n"
echo $str
echo -e $str "abc"
看吧,都换行了,加-e选项就可以换行啦,如果不加呢?可以试试看哦!

$a test

1 test

1 

abc123d\n
abc123d
 abc

  • 字符串长度${#}
  • 子串${str:index1:index2},注意下标不要越界啦
  • 字符串查找`expr index "str" str_finding`,注意待查找串在参数里边是需要加双引号的,而变量$str_var是没有双引号的,所以要写成"$str_var"才可以,查找串则不需要加引号



#!/bin/sh
str1="I am str1"
length=${#str1}
echo "str length is : "$length
endindex=`expr ${length} - 1`
echo "extracting the substr of \"${str1}\" from index 1 to ${endindex} or `expr 1 + 1`"
substr1=${str1:1:${endindex}}
substr2=${str1:1:`expr 1 + 1`}
echo $substr1
echo $substr2
echo "searching ${str1} with the word \"am\", finded in index `expr index "$str1" am`"
echo `expr index "I am abc" am`


str length is : 9
extracting the substr of "I am str1" from index 1 to 8 or 2
am str1
a
searching I am str1 with the word "am", finded in index 3
3


字符串拼接

字符串变量和其它变量如何拼接在一起组成新的字符串呢?
#!/bin/sh
str1="I am str1"
str2="prev"${str1}"next"
num=12
str3='p'${str1}${num}'n'
str4="p" ${str1} "n"
echo $str2
echo $str3
echo $str4
从结果可以看出,字符串可以拼接双引号或单引号包围的字符串以及各种变量,但是两个拼接对象直接不能存在空格,必须紧密联系在一起!!!

user@ubuntu:~/shell$ ./test.sh
./test.sh: line 6: I: command not found
prevI am str1next
pI am str112n

user@ubuntu:~/shell$

printf

  • 格式为printf "format" value
  • format格式可以用双引号或单引号包围起来,如果只有一个格式,那也可以不用引号,但如果有多个格式就一定要用引号了哦
  • %s->string,%d->整数number
  • 像下面'%s %s \n'格式,参数个数超过了格式,则可以格式复用,也即"str1" "Str2"用一次格式进行输出,接着"ab" "cd"再进行一次输出,最后"e" 也有一次输出
  • 默认str是空字符串,默认数字则是0
  • 如果用%d格式输出str,则会提示无效数字,并把字符串当做数字0输出。
#!/bin/sh
printf "%s %d \n" "str" 12
printf %d 23 34 45 "str"
printf '\n%s %d\n' "str" 12
printf '%s %s \n' "str1" "Str2" "ab" "cd" "e"
printf "default str is %s default num is %d\n"

str 12 
./test.sh: line 3: printf: str: invalid number
2334450
str 12
str1 Str2 
ab cd 
e  
default str is  default num is 0



数组

  • 数组的定义用括号()包围起来
  • 数组的下标可以不是连续变量,但是长度不会因为用了不连续变量就突然暴增,还是一个一个加的
  • 字符串单个元素用${array[index]}访问
  • 所有元素用${array[*]}或者${array[@]}访问
  • 长度和字符串的求取一样哦${#array[index]}
  • 如果我使用了非数组作为下标,会出现什么情况呢?
#!/bin/sh
array=(1 2 3 "ab")
array[8]="123"
echo ${array[0]}
echo ${array[8]}
echo ${array[*]}
echo ${array[@]}
len=${#array[*]}
echo "array length is ${len}"
echo "${array[8]} length is ${#array[8]}"
echo "${array[3]} length is ${#array[3]}"
    1
    123
    1 2 3 ab 123
    1 2 3 ab 123
    array length is 5
    123 length is 3
    ab length is 2
    


    在上面数组的基础上,我这样写
    array=(1 2 3 "ab")
    array[8]="123"
    array["a"]="a"
    array["c"]="c"
    array["b"]="b"
    

    下标"a","c","b"实际上修改的都是下标0的元素,而且会不断覆盖,所以最后修改的那个才有效,所以输出全部数组结果
    b 2 3 ab 123

    If-else

    if-else的语法一共有以下三种
    1. 只有一个if,写成if , then ,fi
    2. 有一个if和一个else,写成if, then, else, fi
    3. 有多个条件,写成if ,then ,elif, then, elif, then,...,else, fi
    4. 条件判断用[]包围,记住要有很多空格
    5. 条件判断操作符有==,!=,-gt,-lt,-eq,-ne。-gt是大于,如果要得到大于等于呢?用! -lt
    6. 可以用test代替[]
    7. 如果我把相等判断"=="换成"="呢?好吧,结果一样,也是相等判断,很奇怪哦

    #!/bin/sh
    a=1
    b=3
    c=1
    
    if [ $a == $c ]
    then
      echo "$a == $c"
    fi
    
    if [ $a == $b ]
    then
      echo "$a == $b"
    elif [ $a -gt $b ]
    then
      echo "$a is greater than $b"
    elif [ $a -lt $b ]
    then
      echo "$a is less than $b"
    else
      echo "~~~~"
    fi
    
    if test $a -eq $c
    then
      echo "$a == $c"
    fi
    
    1 == 1
    1 is less than 3
    1 == 1
    


    case语句

    • case语句的格式是case $var in  
    • a)  ... ;;
    • b) ... ;;
    • *) ... ;;
    • esac
    • 表示各种情况可以用如[1-9]表示从1到9的数组,不同情况可以用|来并列,比如下面的[a-z]|[A-Z]
    #!/bin/sh
    echo -e "Please input a number or letter:\c"
    read num
    case $num in
    [1-9])
      echo "the num is <= 10"
      ;;
    [a-z]|[A-Z])
      echo "it is a letter"
      ;;
    *)
      echo "the input is **"
      ;;
    esac
    

    For语句

    • for语句的格式是for var in 值列表 
    • do ... done
    • 和case有个很大的不同在于case里边的值是需要$var的,而for里边则不需要$符号
    • 列表则是用空格进行分隔,可以是数字,也可以是字符串,也可以是个文件列表
    • 以下演示了数字输出,字符串拼接,文件夹中文件遍历
    #!/bin/sh
    for var in 1 2 3 4 5
    do
      echo "loop num $var"
    done
    str0=""
    for str in 'ab' "cd" 'ef'
    do
      str0=${str0}" "${str}
    done
    echo $str0
    echo "typing all the files in the data dir"
    for FILE in /home/user/data/*
    do
      echo ${FILE}
    done
    


    loop num 1
    loop num 2
    loop num 3
    loop num 4
    loop num 5
    ab cd ef
    typing all the files in the data dir
    /home/user/data/HTTP.dat
    /home/user/data/InverseIndex.jar
    /home/user/data/parTest.jar
    /home/user/data/result.dat
    /home/user/data/testComp.jar
    

    while循环

    • while语句格式为
    • while 判断语句
    • do
    • ...
    • done
    #!/bin/sh
    COUNTER=0
    while [ $COUNTER -lt 5 ]
    do
      COUNTER=`expr $COUNTER + 1`
      echo $COUNTER
    done
    
    1
    2
    3
    4
    5

    Until语句

    • until语句的格式和while是一样的只是停止条件有些不同。
    • until的停止条件为判断语句为真时停止。
    #!/bin/sh
    COUNTER=10
    until [ $COUNTER -lt 5 ]
    do
      COUNTER=`expr $COUNTER - 1`
      echo $COUNTER
    done
    

    9
    8
    7
    6
    5
    4

    break与continue

    • break和continue的作用和C中的都一样,都是跳出循环
    • break n表示跳出第几层循环,默认为第一层
    • -a是and的操作符,-lt是小于的操作符,要得到大于等于,需要用!+ -lt。
    #!/bin/sh
    for var1 in 1 2 3 4
    do
      for var2 in 4 3 2 1
      do
        if [ $var1 -gt $var2 -a ! $var1 -lt 2 ]
        then
           break;
        fi
        echo "var1 and var2 are : "${var1}" "${var2}
      done
    done
            

    var1 and var2 are : 1 4
    var1 and var2 are : 1 3
    var1 and var2 are : 1 2
    var1 and var2 are : 1 1
    var1 and var2 are : 2 4
    var1 and var2 are : 2 3
    var1 and var2 are : 2 2
    var1 and var2 are : 3 4
    var1 and var2 are : 3 3
    var1 and var2 are : 4 4

    #!/bin/sh
    for var1 in 1 2 3 4
    do
      for var2 in 4 3 2 1
      do
        if [ $var1 -gt $var2 -a ! $var1 -lt 2 ]
        then
           break 2;
        fi
        echo "var1 and var2 are : "${var1}" "${var2}
      done
    done
    
    break 2 跳出第二层循环,所以if条件满足之后循环就会结束,这里写成break n(n>=2)都会跳出第二层循环的哦!
    var1 and var2 are : 1 4
    var1 and var2 are : 1 3
    var1 and var2 are : 1 2
    var1 and var2 are : 1 1
    var1 and var2 are : 2 4
    var1 and var2 are : 2 3
    var1 and var2 are : 2 2
    


    如果把上面的break都换成continue呢?
    continue只会跳出当前的循环,所以上面的例子换成continue之后,结果都是
    var1 and var2 are : 1 4
    var1 and var2 are : 1 3
    var1 and var2 are : 1 2
    var1 and var2 are : 1 1
    var1 and var2 are : 2 4
    var1 and var2 are : 2 3
    var1 and var2 are : 2 2
    var1 and var2 are : 3 4
    var1 and var2 are : 3 3
    var1 and var2 are : 4 4
    


    函数

    • 可以加个function指明是定义一个函数,也可以不加
    • 和C里边的格式很一致,区别就是()里边没有参数项
    • echo -n和echo -e "\c"效果一样,都是在不换行
    • 运算除了用expr,也可以用$(($a+$b))这样的方式来做诶,不过很麻烦,要写2次括号
    • 函数返回值要是整数哦,一般返回0表示运行成功
    • 如果函数没有返回语句,那么函数返回的是0哦
    • 函数调用直接写函数的名字就可以了
    • 函数返回值用$?获取
    #!/bin/sh
    function fun(){
      echo "I am a function"
      echo -n "read a number:"
      read a
      echo -n "read another number:"
      read b
      c=`expr $a + $b`
      return $(($a+$b))
    }
    fun
    ret=$?
    echo $ret
               

    函数参数

    • 传递函数函数的方式即是
    • 函数名  参数列表(参数之间用空格分开)
    • $0是当前脚本的名字
    • $1则是第一个参数的名字,依次类推
    • 对于第10个以及之后的参数要写成${10},否则会被认为是${1}0的字符串
    • $#表示传递给函数的参数个数
    • $*,$@记录所有参数的列表
    • 函数的返回值只能取非负数,而且它只记录0~255的数,如果超过了255,则会对256取模,比如返回256,最后得到的是0,返回257,则得到的是1.
    #!/bin/sh
    myfun()
    {
    echo $0
    echo $1
    echo ${2}
    echo $3
    echo "the wrong ten'th is "$10
    echo "the right ten'th is "${10}
    echo "number of parameters is "$#
    echo "all "$*
    echo "all "$@
    return 256
    }
    
    myfun  2 3 4 5 a b cd ed cd aa dd
    echo "ret is "$?
    

    ./test.sh
    2
    3
    4
    the wrong ten'th is 20
    the right ten'th is aa
    number of parameters is 11
    all 2 3 4 5 a b cd ed cd aa dd
    all 2 3 4 5 a b cd ed cd aa dd
    ret is 0
    


    输出重定向

    • 使用>和<进行重定向,>可以将命令的结果重定向到某个输出文件上,<则可以让某个文件做命令的输入
    • 使用>会把已经存在的输出文件的内容情况,如果想要在文件末尾添加内容,可以使用>>。
    root@ubuntu:/home/user/shell# ls > ls
    root@ubuntu:/home/user/shell# ls
    d.sh  ls  test.sh
    root@ubuntu:/home/user/shell# echo hi,baby >> ls
    root@ubuntu:/home/user/shell# cat ls
    d.sh
    ls
    test.sh
    hi,baby
    root@ubuntu:/home/user/shell# echo hi,baby > ls
    root@ubuntu:/home/user/shell# cat ls
    hi,baby
    

    root@ubuntu:/home/user/shell# wc < ls
    1 1 8

    Here Documnet

    command << delimiter
        document
    delimiter



    #!/bin/sh
    wc -w << del
    hi baby, I love you
    ohh I love you, too!
    del
    10

    文件包含

    要在一个.sh文件中包含另一个.sh文件,要用". 文件路径"或"source 文件路径"的方式.
    <span style="font-size: 12.6315793991089px;"></span><pre name="code" class="javascript">test.sh
    #!/bin/sh
    fun(){
    wc -w << del
    hi baby, I love you
    ohh I love you, too!
    del
    }   
     
      
    test2.sh
    注意文件路径要写全哦!
    #!/bin/sh
    . /home/user/shell/test.sh
    fun
    

    ./test2.sh
    10

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值