Shell编程入门

课程地址

helloworld

#! /bin/bash
echo "hello,world"

关于hisroty命令:

  • HISTSIZE 是保存历史命令的条数
  • HISTFILE 是保存历史命令的文件
  • !N 表示执行编号为N的历史命令
  • !! 表示执行上一条命令
$ echo $HISTSIZE
1000
$ echo $HISTFILE
/home/daniel/.bash_history
$ !2014
ls
$ !!
ls

变量

shell中的变量都是字符串类型

变量的定义

变量名和等号之间不能有空格

#! /bin/bash

my_name="daniel"
echo $my_name
echo ${my_name}

for i in $(ls /etc/); do
        echo $i
done
//或者这样写
for j in `ls /bin/`; do
        echo $j
done

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

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

使用readonly命令可以将变量修饰为只读变量

#!/bin/bash

myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"		#报错

使用unset命令可以删除变量,但是不能删除只读变量

#!/bin/sh

myUrl="https://www.runoob.com"
unset myUrl
echo $myUrl

变量类型

  • 本地变量:本地变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问本地变量
  • 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量
  • 局部变量:shell函数中定义的变量
  • 位置参数变量:$0 代表脚本名,$1$N 代表脚本的第N个参数

在这里插入图片描述

bash执行脚本和source执行脚本的区别:

  • 每次使用 bash 执行shell脚本时,都会开启一个bash子进程,所以访问不到我们在原来bash中定义的变量
  • 但是如果我们用 source 执行脚本,由于它是在当前环境中加载脚本,所以我们能够访问到原来的变量

在这里插入图片描述
答案是C

关于环境变量:

export 命令显示当前系统定义的所有环境变量
echo $PATH 命令输出当前的PATH环境变量的值

修改环境变量的几种方法:

使用命令追加:export PATH=/home/uusama/mysql/bin:$PATH
修改配置文件:~/.bashrc~/.bash_profile/etc/profile


字符串

单引号里的任何字符都会原样输出,单引号字符串不会解引用变量

my_name="daniel"
echo "my name is \"${my_name}\"!"
echo "my name is "${my_name}"!"
echo "my name is ${my_name}!"

echo 'my name is ${my_name}!'

#输出结果
my name is "daniel"!
my name is daniel!
my name is daniel!
my name is ${my_name}!

获取字符串长度:echo "my_name length = ${#my_name}"

提取子串:

str="my name is daniel"
echo "ths substr is:${str:1:5}"

查找子串:

string="runoob is a great site"
echo `expr index "${string}" io`

数组

在 Shell 中,用圆括号来表示数组,数组元素用"空格"符号分割开

fruit=(
        "apple"
        "orange"
        "banana"
        "grape"
)

echo ${fruit[3]}
echo ${fruit[*]}	#获取数组中所有元素
echo ${#fruit[*]}	#获取数组中元素的个数

#输出结果
grape
apple orange banana grape
4

多行注释

echo ${fruit[3]}
:<<!
echo ${fruit[*]}
echo ${#fruit[*]}
!
echo ${fruit[3]}

:<<!
注释内容...
注释内容...
注释内容...
!

传递参数

脚本内获取参数的格式为:$n
n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数

#! /bin/bash

echo "${0}"
echo "${1}"
echo "${2}"

#运行及结果
$ ./test01.sh fuck you
./test01.sh
fuck
you

几个特殊的参数:

参数处理说明
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数。如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@ ∗ 相同,但是使用时加引号,并在引号中返回每个参数。如 " *相同,但是使用时加引号,并在引号中返回每个参数。如" 相同,但是使用时加引号,并在引号中返回每个参数。如"@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
$-命令行参数,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
for i in "$@"
do
        echo $i
done

for j in "$*"
do
        echo $j
done
#输出结果
$ ./test01.sh fuck you
fuck
you
fuck you

运算符

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。例如,两个数相加(注意使用的是反引号 ` 而不是单引号 ’

val=`expr 2 + 2`
echo "2 + 2 = $val"

算数运算符

注意表达式和运算符之间必须要有空格

#! /bin/bash

a=10
b=20

val=`expr $a + $b`
echo "$a + $b = $val"

val=`expr $a - $b`
echo "$a - $b = $val"
#乘号(*)前边必须加反斜杠(\)才能实现乘法运算
val=`expr $a \* $b`
echo "$a * $b = $val"

val=`expr $a / $b`
echo "$a / $b = $val"

val=`expr $a % $b`
echo "$a % $b = $val"

if [ $a == $b ]
then
        echo "$a == $b"
fi

if [ $a != $b ]
then
        echo "$a != $b"
fi

注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]


关系运算符

在这里插入图片描述

#! /bin/bash

a=10
b=20

if [ $a -eq $b ]
then
        echo "$a equals $b"
else
        echo "$a not equals $b"
fi

if [ $a -ne $b ]
then
        echo "$a not equals $b"
else
        echo "$a equals $b"
fi

if [ $a -gt $b ]
then
        echo "$a greater than $b"
else
        echo "$a not greater than $b"
fi

if [ $a -lt $b ]
then
        echo "$a less than $b"
else
        echo "$a not less than $b"
fi

if [ $a -ge $b ]
then
        echo "$a greater equal $b"
else
        echo "$a not greater equal $b"
fi

布尔运算符

在这里插入图片描述

a=10
b=20

if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a == $b: a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
   echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
   echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
   echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi

在这里插入图片描述

if [[ $a -lt 100 && $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

字符串运算符

在这里插入图片描述

a="abc"
b="efg"

if [ $a = $b ]
then
        echo "$a = $b"
else
        echo "$a != $b"
fi

if [ $a != $b ]
then
        echo "$a != $b"
else
        echo "$a = $b"
fi

if [ -z $a ]
then
        echo "$a len = 0"
else
        echo "$a len != 0"
fi

if [ -n $a ]
then
        echo "$a len != 0"
else
        echo "$a len = 0"
fi

if [ $a ]
then
        echo "$a is not empty"
else
        echo "$a is empty"
fi

文件测试运算符

在这里插入图片描述

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"
fi

if [ -w $file ]
then
   echo "文件可写"
else
   echo "文件不可写"
fi

if [ -x $file ]
then
   echo "文件可执行"
else
   echo "文件不可执行"
fi

if [ -f $file ]
then
   echo "文件为普通文件"
else
   echo "文件为特殊文件"
fi

if [ -d $file ]
then
   echo "文件是个目录"
else
   echo "文件不是个目录"
fi

if [ -s $file ]
then
   echo "文件不为空"
else
   echo "文件为空"
fi

if [ -e $file ]
then
   echo "文件存在"
else
   echo "文件不存在"
fi
#! /bin/bash

echo "Input the file name"

read FILE_NAME

if [ -f "$FILE_NAME" ]; then
        echo "This is a file"
elif [ -d "$FILE_NAME" ]; then
        echo "This is a dir"
elif [ -l "$FILE_NAME" ]; then
       echo "This is a link"
elif [ -p "$FILE_NAME" ]; then
        echo "This is a pipe"
elif [ -c "$FILE_NAME" ]; then
        echo "This is a charDevice"
elif [ -b "$FILE_NAME" ]; then
        echo "This is a blockDevice"
elif [ -s "$FILE_NAME" ]; then
   echo "This is a socket"
else
        echo "This is a Unknown"
        exit 0
fi

echo命令

#读入一个变量再显示
read name
echo "hello,$name"

换行与不换行:

#输出换行
echo -e "OK! \n"	#-e开启转义	
echo "It's a test"
#输出不换行
echo -e "OK! \c"
echo "It's a test"

显示结果定向到文件:echo "It's a test" > myfile
显示命令执行的结果:

echo `date`

如需原样输出字符串,不进行转义或取变量,请用单引号


printf命令

语法:printf format-string [arguments...]

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等

#! /bin/bash

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

test命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

a=10
b=20
if test $[a] -eq $[b]
then
        echo "$a == $b"
else
        echo "$a != $b"
fi

代码中的 [] 执行基本的算数运算

a=5
b=6

result=$[a+b] # 注意等号两边不能有空格
echo "result 为: $result"

文件测试:

cd /bin

if test -e ./not_file -o -e ./bash; then
        echo "exist at least one file"
else
        echo "exist no file"
fi

或者将测试条件用方括号括起来:

if [ -e ./not_file -o -e ./bash ]; then
        echo "exist at least one file"
else
        echo "exist no file"
fi

流程控制

if

语法:

if condition1; then
    command1
elif condition2; then 
    command2
else
    commandN
fi

例子:

a=10
b=20

if test $a -eq $b
then
        echo "$a == $b"
elif test $a -gt $b
then
        echo "$a > $b"
else
        echo "$a < $b"
fi

//如果不用test
if [ $a -eq $b ]
then
        echo "$a == $b"
elif [ $a -gt $b ]
then
        echo "$a > $b"
else
        echo "$a < $b"
fi
#! /bin/bash

echo "Is it morning?Please answer yes or no"

read YES_OR_NO

if [ "$YES_OR_NO" = "yes" ];then
        echo "Good morning"
elif [ "$YES_OR_NO" = "no" ];then
        echo "Good afternoon"
else
        echo "Sorry,$YES_OR_NO not recognized.Enter yes or no"
fi
diff hash-result.txt expected-hash-result.txt

if [ $? == 0 ]; then
    echo "all tests passed"
fi

for循环

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

例子:

for i in 1 2 3 4 5
do
        echo $i
done

for s in this is a string
do
        echo $s
done
#! /bin/bash

for FRUIT in apple banana pear; do
        echo "I like $FRUIT"
done

#batch rename the files
for FILENAME in chap?; do
        mv $FILENAME $FILENAME~;
done

#another form
for FILENAME in `ls chap?`; do
        mv $FILENAME $FILENAME~;
done

while语句

语法:

while condition
do
    command
done

例子:

i=0
while test $i -lt 5
do
        echo $i
        let i++
done

i=0
while [ $i -lt 5 ]
do
        echo $i
        let i++
done

i=0
while (($i<5))
do
        echo $i
        let i++
done

while循环还可以用来读取键盘信息:

echo "ctrl+D to exit"
echo -n "input your name:"

while read NAME
do
        echo "hello,$NAME"
done
#! /bin/bash

echo "Enter password"
CNT=1

read TRY

while [ "$TRY" != "syc" -a $CNT -lt 10 ]; do
        echo "Try again"
        CNT=$(($CNT+1));
        CNT=$[CNT+1]
        read TRY
done

case语句

语法格式:

casein
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

例子:

echo "input a num:"
read num

case $num in
        1) echo "num=1"
                ;;
        2) echo "num=2"
                ;;
        3) echo "num=3"
                ;;
        4) echo "num=4"
                ;;
        *) echo "others"
                ;;
esac

case的值甚至可以是字符串:

echo "input a site:"
read site

case "$site" in
        "google") echo "www.google.com"
                ;;
        "taobao") echo "www.taobao.com"
                ;;
        "baidu") echo "www.baidu.com"
                ;;
        *) echo "others"
                ;;
esac
#! /bin/bash

echo "Is it morning?Please answer yes or no"

read YES_OR_NO

case "$YES_OR_NO" in
        y|yes|Yes|YES)
                echo "Good morning";;
        [nN][oO])
                echo "Good afternoon";;
        *)
                echo "Sorry,$YES_OR_NO not recognized.Entry yes or no"
        return 1;;
esac

break和continue

while true
do
        echo -n "input a num between 1-5:"
        read num
        case $num in
                1|2|3|4|5)
                        echo "your num is $num"
                        ;;
                *)
                        echo "your num is illgel"
                        break
                        ;;
        esac
done

函数

语法

[ function ] funname [()]{
    action;
    [return int;]
}

调用函数仅使用其函数名即可,实例:

function func(){
        echo "this is a function"
}
func
echo $?

返回值

函数返回值在调用该函数后通过$?来获得

function adder(){
        echo "this is an adder"
        echo "input your first num:"
        read a
        echo "input your second num:"
        read b
        return $(($a+$b))
        #return `expr $a + $b`
}

adder
echo $?

参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数

function funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

输入输出重定向

在这里插入图片描述
统计文件的行数:

wc -l myfile
#或者
wc -l < myfile

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

文件包含

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。

语法:

#在test1.sh中定义了url
source ./test1.sh
echo "the url is $url"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值