shell脚本入门基础-1

 

前言

本文主要是shell脚本的一些基本语法,小编也是shell菜鸟,不当之处欢迎指正。

一.变量

1.环境变量

#!bin/bash
#环境变量
echo "User Info :"    
echo "user : $USER"
echo "UID : $EUID"
echo "home : $HOME"
echo ''HOSTNAME''

2.用户变量

变量命名规则:

        由字母,数字和下划线组成;

        大小写敏感

#!bin/bash
var1="hello"
var2="world"
var3=100
echo "$var1 $var2 $var3"

3.特殊变量   

变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。
$? 上个命令的退出状态,或函数的返回值。
$$

当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

 

#!bin/bash

echo " file name : $0 "
echo " Total Number Parameters : $# "
echo " Frist name : $1"
echo " Quoted Values: $@ "
echo " Quoted Values: $* " 
echo " $? "
echo " shell PID: $$"

$@ 与 $* 的区别

$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

#! /bin/bash
echo '$@:'
for i in $@
do
    echo $i
done
echo '"$@:"'
for i in "$@"
do
    echo $i
done  
echo '$*:'
for i in $*
do
    echo $i
done
echo '"$*:"'
for i in "$*"
do
    echo $i
done

结果:      

$@:
1
2
3
"$@:"
1
2
3
$*:
1
2
3
"$*:"
1 2 3

4. `` 与 $()

将命令的执行结果赋值给变量的两种形式

#!/bin/bash

var=`date +%y%m%d`

echo $var

var1=$(date +%y%m%d)

echo $var1

二.数学计算

1.expr

#!/bin/bash
# 注意变量和=之间不能有空格,expr 和 = 之间要有一个空格
var= expr 1 + 2
echo $var

2.[ ] 与 (( ))

#!/bin/bash
# 
var=$[ 1 + 2 ]
echo $var var=$(( 3 + 4 ))
echo $var

3. bc

上述两种智能计算整数,对于浮点数就要用到bc

脚本中使用bc的格式:

variable=`echo "option; expression" |bc` 
#!/bin/bash
var=`echo "scale=2;5/3" | bc`
echo $var

三.逻辑控制

1.if

1.1 if-then

if command
then
      command
fi

例:

#!/bin/bash

if date
then
      echo "command is succeed"
fi

1.2 if -then -else  

#!/bin/bash
if command
then 
      command
else 
      command
fi

例:

#!/bin/bah
# 查找系统中是否存在httpd用户
if grep httpd /etc/passwd
then
    echo "httpd is exist"
else
    echo "httpd not find"
fi

1.3 if嵌套

#!/bin/bash
if command
then
    command
elif command
    command    
else
     command	    
fi

2.test

功能:

      数值比较

      字符串比较

       文件比较

格式:  

#!/bin/bash
test condition
或
[ command ]    --更常用

2.1 数值比较

比较 描述
-eq 等于
-ge 大于等于
-gt 大于
-le 小于等于
-lt 小于
-ne 不等于

 

例:

#!bin/bash
date
if [ $? -eq 0 ]
then
     echo "command is succeed"
fi
#或
if test date
then
     echo "command is succeed"
fi

2.2 字符串比较

比较 描述
str1=str2 字符串是否相同  
str1 !=str2 字符串是否不同  
str1<str2 str1是否小于str2  
str1>str2 str1是否大于str2

 [b\>a] && echo "true"

(注意>需要转义)

-n str  字符串长度非零为真  [-n "abc"] && echo "str is not null"
-z str  字符串长度为0为真   [-z ""] && echo "str is  null"

  

2.3 文件比较

比较 描述
-d file 检查file是否存在并是一个目录  
-f file 检查file是否存在并是一个目录  
-e file 检查file是否存在  
-r file 检查文件是否存在并可读  
-s file  检查文件是否存在并非空  
-w file 检查文件是否存在并可写  
-x file 检查文件是否存在并可执行  
-O file 检查文件是否存在并属当前用户所有  
-G file 检查文件是否存在并且默认组与当前用户相同  
file1 -nt file2 file1是否比file2新  

 

2.4 复合条件

[condition1] && [condition2]

[condition1] ll [condition2]

3.case

格式:

case variable in
pattern1 | pattern2) command1 ;;
pattern3) command2 ;;
*) default command ;;
esca  

例:

#!、bin/bash
read -p "input something: " var
case $var in 
[0-9])
       echo "number";;
[a-z]) 
       echo "str"
*)    echo "请重新输入"
esca

4.for

4.1 bash中的for

格式:

for var in command
do
      command
done

例:

#!/bin/bash
#查看服务状态
for service in apache2 mysqld zabbix-server zabbix-agent
do
      status=$(systemctl status mysql | awk ' /Active/  {print $2,$3}' )
      echo $service $status
done

例:使用通配符

#!/bin/bash
#注意在$file上加" ",否则如果出现带空格的目录名,脚本会出错
for file in /tmp/*
do
     if [ -d "$file" ]
     then 
           echo " file is a directory "
     elif [ -f "$file"]
     then
           echo "$file"  is a file
      fi
done

 4.2 使用c语言风格for

#!/bin/bash 
#单变量

for (( i=1; i<=10; i++ ))
do
     echo $i
done

#多变量

for (( i =1,j=10; i<=10; i++,j-- ))
do
    echo $i $j
done

5.while  

 例:

#!/bin/bash
#检查站点状态
urls="
https://www.baidu.com
https://www.taobao.com
https://www.jd.com/abc
https://www.12306.cn/index/
192.168.1.111
"
for url in $urls
do 
     count =0
     while [ $count -lt 3 ] 
     do
          status = $(curl -I -m 10 -o /dev/null -s -w %{http_code} $url)
          if [ $status -eq 200 ]
          then
              echo "$url ok"
              break 1
           fi
      count = $((count +1 ))
      done
      if [ ¥count -eq 3 ]
      then
          echo  " $url Error "
      fi
done
  

6.until 

#!.bin/bash
var=10
until [ $var -eq 0 ]
     do
     var = $[ $var-2 ]
     echo $var
done

7.循环控制

7.1 break

#!/bin/bash
#break跳出当前循环
#break n 跳出n层循环
for (( i=1; i<=10; i++ ))
do
    if [$i -eq 5]
    then
        break
    fi
    echo $i
done 

四 . 输入

 1.命令行参数

例:

#!/bin/bash
echo $1 + 0$2 =$[ $1 +$2 ]

#执行命令
./shell_name 3 4
3 + 4=7

例:

#!/bin/bash
#把变量位置左移
while [ -n "$!"]
do
     echo $1
     shift
done

2.getopts

格式:getopts optstring variable

optstring:选项字母,如果字母要求有参数就加一个:,要去掉错误信息的话可以再optstring前加一个:

variable:保存当前参数

#!/bin/bash
#getopts用法
#opt会保存输入的参数,如 r,i,x
#OPTARG保存参数值
#参数需要就在后面加一个: 如 i:
while getopts rix: opt
do
        case "$opt" in
        r ) echo " remove all service " ;;
        i ) echo " install service $OPTARG " ;;
        x) echo " 可执行 "   ;;
        *) echo " Unknown option :$opt " ;;
        esac
done

root@localhost:/# ./getopts.sh -i apache1
install service apache2
root@localhost:/# ./getopts.sh -r
remove all service
root@localhost:/# ./getopts.sh -a
./getopts.sh: illegal option -- a
Unknown option: ?

3.获得用户输入read

3.1普通用法  

#!/bin/bash
read name
echo $name

3.2指定提示符

#!/bin/bash
read -p " Enter you name: " name
echo " Hello $name "

3.3指定超时时间

#!/bin/bash
if read -t 5 -p " Enter you name: " name
then
      echo " Hello $name "
else 
       echo " time out"
fi

3.4隐藏数据

#!/bin/bash
read -s -p " Enter Password: " password
echo
echo " $password " 

五.输出

现实脚本输出的方法:

 1.显示器显示

 2.将输出重定向到文件

描述符 缩写 描述
0 STDIN 标准输入
1 STDOUT 标准输出
2 STDERR 标准错误

 

1.脚本中重定向

1.1临时重定向

使用场景:脚本中生成错误信息

#!/bin/bash
echo "This is an error message" >&2
echo "This is normal output" 

默认情况下Linux会将STDERR定向到STDOUT

$ ./error.sh

This is an error message
This is normal output

在执行脚本的时候重定向STDERR,ERR文本就会被重定向

$ ./error.sh 2> error.log
This is normal output
$ cat error.log
This is an error message

1.2永久重定向

用exec命令告诉shell在执行脚本期间重定向某个特定文件描述符。

#!/bin/bash
exec 2>errout
echo "This is error"
exec 1>testout
echo "testout"
echo "testout  to errout" >&2

 

$ ./test.sh
This is error
$ cat errout
testout  to errout
$ cat testout
testout  

 六.函数

1.基本函数

#!/bin/bash
#定义方式1
functionfoo{
     echo "This is a func "    
}
   
#定义方式2
bar() {
     echo " This is another func "

} 
#函数的调用
foo
bar

 2.返回值

1.默认退出状态码

#!/bin/bash
#定义方式1
function foo{
     echo "hello world "   
}
foo
echo "Exit status is $?"

2.使用return命令

#!/bin/bash
#定义方式1
function foo{
     echo " hello world " 
     return 1   
}

foo
echo " Exit status is $?"

  

 3.使用函数输出

#!/bin/bash
#定义方式1
function foo{
     echo " hello world " 
     return 1   
}
#赋值给变量
result = foo
echo " Exit status is $result "

 3.变量

1.传参

#!/bin/bash
function status{
      systemctl status $1

}
status  sshd

2.局部变量与全局变量

#!/bin/bash
#定义全局变量
hostname = "web"
function foo {
     str = " hello "
     #使用local定义局部变量
     local user = "https"
     echo " $hostname "
     echo " $user "

}
foo
#在函数内部定义的局部变量不能再全局使用

echo " $str $user" 

3.数组变量

#解决方法
#!/bin/bash
function foo {
     arr =$@
     echo "Thr received array is ${ arr[ * ] } "
}
myarr = (1 2 3 4 )
foo ${ myarr[*] }

七.控制脚本

1.处理信号

1.1. 查看LInux信号

kill -l 

在Linux 编程时会遇到最常见的Linux系统信号

信 号	值	描 述	                   触发
1	SIGHUP	挂起进程	
2	SIGINT	终止进程	                   Ctrl + C
3	SIGQUIT	停止进程	
9	SIGKILL	无条件终止进程	
15	SIGTERM	尽可能终止进程	
17	SIGSTOP	无条件停止进程,但不是终止进程	
18	SIGTSTP	停止或暂停进程,但不终止进程	   Ctrl+Z
19	SIGCONT	继续运行停止的进程	

1.2.脚本执行

1.脚本执行

bash filename.sh 或

chmod +x filename.sh

./ilename.sh 

2.后台运行脚本

./test.sh &

nohup ./test.sh &

附:退出状态

可以使用$? 查看上一个命令的退出状态码

状态码 含义
0 命令成功结束
1 通知未知错误
2 误用shell命令
126 命令不可执行
127 没有找到命令
128+x Linux信号x的严重错误
130 命令通过Ctrl+C终止
255 退出状态码越界
posted @ 2021-03-08 14:41  流水小哥  阅读(108)  评论(0编辑  收藏  举报