Shell入门基础(靠这个就够了)

Shell概述

Shell是一个命令解释器,它给用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序。

脚本格式

#!/bin/bash

#!是说明这个文件的类型,有点类似于Windows系统下用不同文件后缀来表示不同文件类型的意思(但不相同)

使用分号;可以在同一行上写两个或两个以上的命令

#需要可执行文件的权限

#!/bin/bash
echo hello; echo there
filename=ttt.sh
if [ -e "$filename" ]; then    # 注意: "if"和"then"需要分隔,-e用于判断文件是否存在
    echo "File $filename exists."; cp $filename $filename.bak
else
    echo "File $filename not found."; touch $filename
fi; echo "File test complete."

使用双引号;;终止case选项

执行脚本方式

chmod u+x filename

./ filename

等价于 bash filename

等价于 source filename

等价于 . filename

bash 中的 source 命令用于在当前 bash 环境下读取并执行 FileName.sh 中的命令。

Shell符号规则

引号

双引号(")

“STRING” 将会阻止(解释)STRING 中大部分特殊的字符。后面的实验会详细说明。

单引号(’)

‘STRING’ 将会阻止 STRING 中所有特殊字符的解释,这是一种比使用"更强烈的形式。后面的实验会详细说明。

斜线(/

文件名路径分隔符。多个/根一个效果相同

反斜线(\

一种对单字符的引用机制。\X 将会“转义”字符 X。这等价于"X",也等价于’X’。\ 通常用来转义双引号(")和单引号('),这样双引号和单引号就不会被解释成特殊含义了。

  • 符号 说明

  • \n 表示新的一行

  • \r 表示回车

  • \t 表示水平制表符

  • \v 表示垂直制表符

  • \b 表示后退符

  • \a 表示"alert"(蜂鸣或者闪烁)

  • \0xx 转换为八进制的 ASCII 码, 等价于 0xx

  • \" 表示引号字面的意思

反引号

表示执行引号内的语句

冒号

空命令

等价于“NOP”(no op,一个什么也不干的命令)。也可以被认为与 shell 的内建命令 true 作用相同。“:”命令是一个 bash 的内建命令,它的退出码(exit status)是(0)。

如:

#!/bin/bash

while :
do
    echo "endless loop"
done

等价于

#!/bin/bash

while true
do
    echo "endless loop"
done
变量扩展/子串替换

在与 > 重定向操作符结合使用时,将会把一个文件清空,但是并不会修改这个文件的权限。如果之前这个文件并不存在,那么就创建这个文件。

: > test.sh   # 文件“test.sh”现在被清空了
# 与 cat /dev/null > test.sh 的作用相同
# 然而,这并不会产生一个新的进程, 因为“:”是一个内建命令

: 还用来在 /etc/passwd$PATH 变量中做分隔符,如:

echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
cop

问号

测试操作符

在一个双括号结构中,? 就是 C 语言的三元操作符

美元符号

变量替换

小括号()

1.命令组

在括号中的命令列表,将会作为一个子 shell 来运行。

在括号中的变量,由于是在子 shell 中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子 shell 中创建的变量。

2.初始化数组

#!/bin/bash

arr=(1 4 5 7 9 21)
echo ${arr[3]} # get a value of arr
bash test
大括号{}

1、文件名扩展

注意: 在大括号中,不允许有空白,除非这个空白被引用或转义。

2、代码块

代码块,又被称为内部组,这个结构事实上创建了一个匿名函数(一个没有名字的函数)。然而,与“标准”函数不同的是,在其中声明的变量,对于脚本其他部分的代码来说还是可见的。

#!/bin/bash

a=123
{ a=321; }
echo "a = $a"

运行结果:a=321

中括号

1、条件测试

条件测试表达式放在 [ ] 中。下列练习中的 -lt (less than)表示小于号。

2、数组元素

在一个 array 结构的上下文中,中括号用来引用数组中每个元素的编号。

尖括号

重定向

test.sh > filename:重定向 test.sh 的输出到文件 filename 中。如果 filename 存在的话,那么将会被覆盖。

test.sh &> filename:重定向 test.sh 的 stdout(标准输出)和 stderr(标准错误)到 filename 中。

test.sh >&2:重定向 test.sh 的 stdout 到 stderr 中。

test.sh >> filename:把 test.sh 的输出追加到文件 filename 中。如果 filename 不存在的话,将会被创建。

竖线

管道

分析前边命令的输出,并将输出作为后边命令的输入。这是一种产生命令链的好方法。

tr :表示替换

#!/bin/bashtr 'a-z' 'A-Z'exit 0
chmod 755 test26.shls -l | ./test26.sh

输出的内容均变为了大写字母。

破折号

选项、前缀

在所有的命令内如果想使用选项参数的话,前边都要加上“-”。

用于重定向stdin或stdout

波浪号

目录 ~表示home目录

Shell运算规则

变量定义

变量的名字就是变量保存值的地方。引用变量的值就叫做变量替换。

如果 variable 是一个变量的名字,那么 $variable 就是引用这个变量的值,即这变量所包含的数据。

$variable 是 v a r i a b l e 的 简 写 形 式 , 如 果 遇 到 有 时 候 {variable}的简写形式,如果遇到有时候 variablevariable引起错误,改为${variable}

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

变量名命名规则:

  • 首个字符必须为字母(a-z,A-Z)。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。

也可以进行语句给变量赋值

for file in `ls /etc`
只读变量

使用readonly命令可以将变量定义为只读变量,只读变量的值不能改变

#!/bin/bashmyUrl="http://www.shiyanlou.com"readonly myUrl
特殊变量

局部变量

这种变量只有在代码块或者函数中才可见

环境变量

这种变量将影响用户接口和shell的行为。在通常情况下,每个进程都有自己的“环境”,这个环境是由一组变量组成的,这些变量中存有进程可能需要引用的信息。在这种情况下,shell 与一个一般的进程没什么区别。

位置参数

从命令行传递到脚本的参数:$0$1$2$3$0 就是脚本文件自身的名字,$1 是第一个参数,$2 是第二个参数,$3 是第三个参数,然后是第四个。$9 之后的位置参数就必须用大括号括起来了,比如,${10}${11}${12}

  • $# : 传递到脚本的参数个数
  • $* : 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9 个
  • $$ : 脚本运行的当前进程 ID 号
  • $! : 后台运行的最后一个进程的进程 ID 号
  • $@ : 与 $* 相同,但是使用时加引号,并在引号中返回每个参数
  • $: 显示 shell 使用的当前选项,与 set 命令功能相同(注意:显示当前shell中所有变量:set)
  • $? : 显示最后命令的退出状态。 0 表示没有错误,其他任何值表明有错误。
#!/bin/bash

# 作为用例, 调用这个脚本至少需要10个参数, 比如:
# bash test.sh 1 2 3 4 5 6 7 8 9 10
MINPARAMS=10

echo

echo "The name of this script is \"$0\"."

echo "The name of this script is \"`basename $0`\"."


echo

if [ -n "$1" ]              # 测试变量被引用.
then
echo "Parameter #1 is $1"  # 需要引用才能够转义"#"
fi

if [ -n "$2" ]
then
echo "Parameter #2 is $2"
fi

if [ -n "${10}" ]  # 大于$9的参数必须用{}括起来.
then
echo "Parameter #10 is ${10}"
fi

echo "-----------------------------------"
echo "All the command-line parameters are: "$*""

if [ $# -lt "$MINPARAMS" ]
then
 echo
 echo "This script needs at least $MINPARAMS command-line arguments!"
fi

echo

exit 0
撤销变量

unset 变量

算数运算符

5-1-1

注意:表达式和运算符之间要有空格 $a + $b 写成 $a+$b 不行

**注意:**条件表达式要放在方括号之间,并且要有空格 [ $a == $b ] 写成 [$a==$b] 不行

**注意:**乘号(*)前边必须加反斜杠(\)才能实现乘法运算

关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

5-2-1

0为真,1为假

逻辑运算符

5-3-1

注意:

  • -a 表示逻辑与
  • -o 表示逻辑或
  • ! 表示逻辑非
字符串运算符

图片描述

注意:-z 和 -n 两个是反的,建议还是 -z较好

​ str指的是字符串本身

文件测试运算符

5-5-1

注意:-e 判断文件是否存在 -f 表示文件为一般类型

expr 只能用于整数计算,可以使用 bc 或者 awk 进行浮点数运算。

​ expr 用法: echo ``expr 1+2 输出为3

浮点数运算实验
#!/bin/bashradius=2.4pi=3.14159girth=$(echo "scale=4; 3.14 * 2 * $radius" | bc)area=$(echo "scale=4; 3.14 * $radius * $radius" | bc)echo "girth=$girth"echo "area=$area"

scale表示指定保留小数点后的位数,不设定就默认为0

Shell语句

if else语句

if语句

if conditionthen   
    command1    
    command2    ...    
    commandN
fi

if else语句

if  conditionthen    
    command1    
    command2    ...  
    commandN
else   
    commandfi

if-elif-else 语法格式

if condition1
   then   
   command1
   elif condition2
   then    
   command2
   else   
   commandN
fi
实验一、if else使用判断两个变量
#!/bin/bash
#test1.sh
a=10
b=20
if [ $a -eq $b ]
then
  echo "a=b"
 elif [ $a -gt $b  ]
    then
   echo "a>b"
 elif [ $a -lt $b ]
   then
    echo "a<b"
 else
    echo "Ineligible"
  fi

输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nngXgslS-1630919748580)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905161407342.png)]

if else 语句经常与test命令结合使用

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo 'Two numbers are equal!'
else
    echo 'The two numbers are not equal!'
fi

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y1e8pjzi-1630919010305)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905161912580.png)]

for循环

for循环的一般格式为:

for var in item1 item2 ... itemN
do   
 command1    
 command2    
 ...   
  commandN
  done
实验二 顺序输出fujingwen
 #!/bin/bash
  2 #test3.sh
  3 for str in Hello  fu jing zhu
  4  do
  5    echo $str
  6 done


输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3r5R94VQ-1630919010306)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905162341346.png)]

while循环

while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件 格式为:

while condition
do   
 command
 done
实验三、计算1到100之和
1 #!/bin/bash
  2 #test4.sh
  3 i=1
  4 while (( $i<=100 ))
  5   do
  6   s=$[ $s + $i ]
  7   let "i++"
  8 done
  9 echo $s

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3iibz2eH-1630919010307)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905163152722.png)]

这里使用了Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上$来表示变量

注意:

while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量MAN,按<Ctral + D>结束循环

  #!/bin/bash
  #test5.sh
   echo "press <CTRL-D> exit"
  echo -e "who do you think is the most handsome\n"
   while read MAN
    do
    if [ $MAN -eq 201931773444 ]
       then
       echo "Yes! hujie is really handsome"
    else
       echo "SB"
    fi
  done
无限循环

格式

while :
do    command
done
或者
while true
do   
 command
 done

或者

for (( ; ; ))
until循环

until循环执行一系列命令直至条件为真时停止。until循环与while循环在处理方式上刚好相反。一般情况while优先于until循环,但在极少数的时候,until循环更加有用。until的格式如下

until condition
do    
command
done

条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次—请注意这一点。

case

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,入如果匹配成功,执行相匹配的命令。case语句格式如下

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

取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;

取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

实验四 case的使用

下面脚本提示输入1到4,与每一种模式匹配

echo "Enter a number between 1 to 4:"
echo "The number you entered is:"
read num
case $num in
     1)
       echo 'You have chosen 1'
       ;;
     2)
       echo 'You have chose 2'
       ;;
     3)
       echo 'You have chose 3'
       ;;
     4)
       echo 'You have chosen 4'
       ;;
     *)
       echo 'You did not enter a number between 1 to 4'
       ;;
 e

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwdPasn8-1630919010308)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905165618616.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXcxndmM-1630919010310)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905165648304.png)]

跳出循环

在循环过程中,有时候需要在为达到循环结束条件的时候强制跳出循环,Shell使用两个命令来实现该功能:break和continue

break命令

break命令允许跳出所有循环(终止执行后面的所有循环)

**注意:**每个case分支用右圆括号,用两个分号表示break

continue命令

continue命令与break命令相似,只有一点差别,它不会跳出所有的循环,仅仅跳出当前循环。

实验五 break的使用

脚本进入死循环直至用户输入数字大于5.要跳出这个循环,返回shell提示符下。需要使用break命令

#!/bin/bash
while :
do
 echo -n "Enter a number between 1 and 5:"
 read num
 case $num in
 1|2|3|4|5) echo "The number you entered is $num!"
            ;;
         *)echo "The number you entered is not between i and 5! game over!"
           break
           ;;
 esac
done

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MYuYSQMz-1630919010310)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905192129865.png)]

实验六、continue的使用
#!/bin/bash
while :
do
   echo -n "Enter a number between 1 and 5:"
   read num
   case $num in
        1 |2|3|4|5)echo "The number you entered is $num!"
                   ;;
                 *)echo "The number you entered is not between 1 and 5!"
                   continue
                   echo "game over"
                   ;;
   esac
done

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VzIGfrYo-1630919010311)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905192916861.png)]

实验七

写一个脚本实现以下功能

1)提示用户输入一个字符串

2)判断:如果输入的是quit,则退出脚本; 否则,则显示输出的内容

#!/bin/bash
#test3.sh
echo -n "Please enter a string:"
read str
case $str in
     quit) exit 1
          ;;
     *) echo "You have entered is $str!"
          ;;
es

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTOPgqMx-1630919010312)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905193954703.png)]

实验八、找最值

判断8 、4 、5三个数的最大值

#!/bin/bash
#test4.sh
echo "Please enter three numbers: "
read a b c
if [ $a -gt $b ]
   then
   d=$a
   else
   d=$b
fi
if [ $c -gt $d ]
   then
   echo "The largist number is $c"
   else
   echo "The largist number is $d"
fi

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2f2tSRRy-1630919010314)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905195325914.png)]

实验九、求100以内所有偶数之和
#!/bin/bash
#test6.sh
s=0
i=2
until [ $i -gt 100 ]
  do
  s=$[ $s + $i ]
  i=$[ $i + 2 ]
done
echo $s
#!/bin/bash
cnt=0
sum=0
for cnt in `seq 2 2 100`
do
  sum=$((cnt+sum))
done

echo $sum

seq 2 2 100 表示列出 1 到 100 的所有偶数

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZVsXQHb-1630919010315)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905200916087.png)]

函数

函数的定义

shell中函数的定义格式如下:

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

说明:

​ 1.可以带function fun()定义,也可以直接fun()定义,不带任何参数

​ 2.参数返回,可以显示加:return返回,如果不加,将以最后一条指令运行结果,作为返回值。return后跟数值(0-255)

实验一、函数的定义被调用
#!/bin/bash
#test1.sh
demoFun(){
  echo "Hello world"
}
echo "----------"
demoFun
echo "----------"

​ 输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZS24nj0r-1630919010316)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905203644029.png)]

下面定义一个带return语句的函数:

#!/bin/bash
#test2.sh
funwithreturn(){
 echo "Enter first number:"
 read num1
 echo "Enter seconded number:"
 read num2
 echo "The result of two number is : $[ $num1 + $num2 ]"
 return $(($num1+$num2))
}
funwithreturn
echo $?

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7rjapMGS-1630919010317)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905204401250.png)]

函数参数

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

实验二、函数参数的获取

#!/bin/bash
#test3.sh
funwithreturn(){
 echo "the fist parameter is $1"
 echo "the second parameter is $2"
 echo "the tenth parameter is $10"
 echo "the tenth parameter is ${10}"
 echo "the total number of parameter is $#"
 echo "Outputs all parameter as a string $*"
}
funwithreturn 1 2 3 4 5 6 7 8 9 34 73

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ei7u169n-1630919010318)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905205138814.png)]

注意:

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

$#:表示输出元素总的个数

$*:表示输出所有的元素

实验三、猜数字游戏

首先让系统随机生成一个数字,给这个数字一个范围,让用户猜这个数字,对输出做出判断,并给出提示。

用while实现

#!/bin/bash
#test.sh
function randNum(){
echo "Please enter a number:"
 while :
   do
   read num
   if test $num -eq $1
   then
   echo "right"
   exit 1
   else
      if [ $num -lt $1  ]
        then
        echo "Your number is smaller"
      else
        echo "Your number is largger"
      fi
    fi
done
}

randNum $[ $RANDOM%100+1 ]

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YrEbR01F-1630919010319)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210905210230652.png)]

**注意:**随机数的表示方法 $RANDOM%100+1

输出结果因为我是直接笔记上传的,所以就没有弄好,大家见谅,但是都是没有问题的。而且Shell基础部分挺简单的,大家子集也会检验!

如果大家需要文档可以直接下载:https://download.csdn.net/download/m0_56145255/21964539

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacky~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值