前言
本文主要是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 | 退出状态码越界 |