一:shell脚本内容解释器
#!/bin/bash
#!/bin/sh
以上两种方式都行 ,sh是bash的软链接,后者更加规范
二:shell脚本的执行方式
1. bash/sh script_name #推荐使用
2. ./script_name #此方式需要脚本有执行权限,若没有则无法自动补全
3. source script_name
4. . script_name #此方式中"."和script_name中间必须有空格
以上3、4两种1方式和1、2两种方式的区别是:3、4方式会将shell脚本中的变量自动加到环境变量中。
三:变量
变量分为:环境(全局)变量和普通(局部)变量
环境变量:可以在创建他们的shell和其派生出来的任意子进程shell中使用,环境变量又分为自定义环境变量和内置环境变量
普通变量:只能在创建他们的shell函数或shell脚本中使用
环境变量的定义方式:
1: export 变量名=value
2: 变量名=value;export 变量名
3: declare -x 变量名=value
注:
以上变量在退出命令行时变量就会丢失,若想永久保存环境变量则在用户家目录下的:
/etc/bashrc(优先推荐)
/root/.bashrc (用户的环境变量优先推荐)
/root/.bash_profile
/etc/profile
配置以上文件即可
变量显示的方式:
显示变量的命令:
1:set 输出所有变量:包括全局变量和局部变量
2:env 只显示全局变量
3:declare 输出所有的变量、函数、整数和已经导出的变量
在使用shell脚本时一般直接使用系统默认的环境变量,不用自己定义,在使用定时任务时建议在脚本中重新定义
消除普通和环境变量:
unset 变量名
总结:
1.变量名要大写
2.变量可以在自身的shell和子shell中使用
3.常用export来定义环境变量
4.env默认显示所有环境变量和其对应的值
5.书写crond定时任务时,脚本中要用到的环境变量最好先在所执行的shell脚本中重新定义
6.要使环境变量永久生效,则可以将其放在用户变量文件或全局变量文件
普通变量的定义方式
1:变量名=value
2:变量名=’value’
3:变量名=“value”
注:
仅仅限制当前用户的脚本中使用,当shell启动另一个脚本或退出,则本地变量失效
#!/bin/bash
a=192.168.10.1
b='192.16.10.1'
c="192.168.10.1"
echo "a=$a"
echo "b=$b"
echo "c=${c}"
a=192.168.10.1-$a
b='192.16.10.1-$a'
c="192.168.10.1-$a"
echo "a=$a"
echo "b=$b"
echo "c=${c}"
运行结果:
a=192.168.10.1
b=192.16.10.1
c=192.168.10.1
a=192.168.10.1-192.168.10.1
b=192.16.10.1-$a
c=192.168.10.1-192.168.10.1-192.168.10.1
注:
$a作为本地变量在第一行为192.168.10.1
linux,sed、grep中的经验(不含awk):
1、连续的数字或字符串内容不加引号
2、需要原样输出加单引号
3、其他(字符串中有空格或者其他字符)都加双引号
awk中变量的使用:
不管变量如何定义、赋值,除了加单引号以外,利用awk直接获取变量的输出,结果都是一样的。
因此通常会:先用echo加符号输出变量,然后通过管道给awk,进而控制输出结果
[root@mycentos ~]# ETT="hello"
[root@mycentos ~]# echo "$ETT" |awk '{print $0}'
hello
[root@mycentos ~]# echo '$ETT' |awk '{print $0}'
$ETT
[root@mycentos ~]# echo $ETT |awk '{print $0}'
hello
注:
当变量后面连接有其他字符的时候,必须给变量加上大括号{},例如:
dbname=hello
echo ${dbname}_world
链接:
http://oldboy.blog.51cto.com/2561410/760192
重要的参数
$0:脚本名称(有路径的话,路径也显示常用来提示用户输入时语法错误)
$n:脚本的第n个参数
$#:参数的总个数
$*:获取所有脚本所有参数,若加""时,将所有参数视为单个字符串,相当于"$1,$2,$3"
$@:获得所有脚本所有参数,若加""时,将所有参数视为不同的字符串,相当于"$1""$2""$3"
$? :上个命令执行成功则返回0,失败则返回一个非0数
脚本中:exit 数值 ==>此数字会给$?
函数中:return 数值 ==>此数字给$?
注:
1.$* 和$@不加""时完全一样,加上后不一样
$* 和$@的联系与区别
[root@mycentos ~]# set -- "i am " boy girl #"--"表示清除后面参数变量
[root@mycentos ~]# echo $#
3
[root@mycentos ~]# echo $1
i am
[root@mycentos ~]# echo $2
boy
[root@mycentos ~]# echo $3
girl
[root@mycentos ~]# echo $*
i am boy girl
[root@mycentos ~]# for I in $* ;do echo $I;done
i
am
boy
girl
for I in $@;do echo $I;done
i
am
boy
girl
以上不加””的@是一样的
[root@mycentos ~]# for I in "$*" ;do echo $I;done #<==参数合二为一作为一个参数字符串
i am boy girl
[root@mycentos ~]# for I in "$@";do echo $I;done #<===这才是我们想要的,三个独立的参数
i am
boy
girl
#此例子表明加上""的*和@是不一样的
2.传参数时,若参数用""括起来,则相当于一个参数
参数多时的技巧
[root@mycentos ~]# echo \${1..15}
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
但是n大于9时,要加大括号。否则会出现金庸新著的问题
例如:${10} ${11} ${12}
四:算数运算符
(()):整数运算的常用运算符
let:用于整数运算,类似于(())
expr:可用于整数运算,还有其他的额外功能
$[] :整数运算
bc :适合整数,也适合小数
awk:适合整数和小数
(())运算符
算数比较:
((i=i+1))
echo $((i=i+1)) #==>得到i的数值
[root@mycentos ~]# echo $((2+1))
3
[root@mycentos ~]# i=1
[root@mycentos ~]# echo $((i=i+1))
2
[root@mycentos ~]# num=$((a=8-2**3+4%3))
[root@mycentos ~]# echo $num
1
(())还可以用于逻辑比较:1是真,0是假
[root@mycentos ~]# num=$((8>10 && 5== 5))
[root@mycentos ~]# echo $num
0
(())在执行命令时不用加$符号,直接使用((6%2))即可,但是如果需要输出,就要加$,echo $((6%2))
let运算符
let 赋值表达式 == ((赋值表达式))
let i=i+1 等同于((i=i+1)),后者效率更高
[root@mycentos ~]# i=1
[root@mycentos ~]# let i=i+9
[root@mycentos ~]# echo $i
10
expr运算符
用法:
1:运算符号以及计算的数字左右都应该至少一个空格
2:使用乘号时,必须转义
一.基础用法:
[root@mycentos ~]# expr 1 + 1
2
[root@mycentos ~]# I=10
[root@mycentos ~]# expr $I + 2
12
二.检测变量值或字符串是否是整数:
expr $1 + 1 &> /dev/null
[ $? -eq 0 ]&&echo int ||echo chars
注:
1.此方法是将一个未知量和一个已知整数相加,若返回值是0,则是整数,否则就不是整数
2. [ -n "$(echo $1|sed 's#[0-9]##g')" ] #检测非空(返回值非0)则是
此方式是将原来参数去处数字后,看是否是空字符串,若是则原来的参数是整数,否则就不是。
三.计算字符串长度:
[root@myredhat ~]# HELLO="world"
[root@myredhat ~]# expr length "$HELLO"
5
实战题目:
请编写shell脚本,打印下列字符数不大于4的单词
I am a good student in linux
#!/bin/bash
for I in i am a good student in linux
do
if [ $(expr length "$I") -le 4 ] #expr length来取得变量的字符长度
then
echo $I
fi
done
$[]运算符
$[]进行整数的运算时, $[]===$(())
bc(linux下的交互性计算器)的用法
[root@mycentos ~]# echo 3+3 | bc
6
[root@mycentos ~]# echo 3.3 + 5.5 | bc
8.8
[root@mycentos ~]# echo "scale=2;100/3"|bc ##scale表示保留多少位小数
33.33
实战题目:
通过一条命令输出1+2+3+4+5+6+7+8+9+10,并且计算其结果
1. [root@mycentos shell_dir]# seq -s "+" 10|bc #-s 表示以什么作为数字之间的分隔符
55
2.
[root@mycentos ~]# echo {1..10}
1 2 3 4 5 6 7 8 9 10
[root@mycentos ~]# echo {1..10}| tr ' ' "+"
1+2+3+4+5+6+7+8+9+10
[root@mycentos ~]# echo {1..10}| tr ' ' "+"|bc
55
awk运算符(小数时推荐)
[root@mycentos ~]# echo "3.7 2.11"|awk '{print $1-$2}'
1.59
[root@mycentos ~]# echo "200 890"|awk '{print ($1-$2/$2)}'
199
[root@mycentos ~]# echo "200 890"|awk '{print ($1-$2)/$2}'
-0.775281
实战题目:用shell编写一个2位数的四则运算
1 #!/bin/bash
2
3 print_usage(){ ##出现错误时就输出提示
4 printf "usage:$0 num1 {+-*/} num2\n"
5 exit 1
6 }
7 num1=$1
8 op=$2
9 num2=$3
10
11 if [ $# -ne 3 ]#依次必须输入三个
12 then
13 print_usage
14 fi
15
16 if [ -n "$(echo $num1|sed 's#[0-9]##g')" ]##检验是否是整数:将数字全部去除,检测剩下的是否是空字符串
17 then
18 print_usage
19 fi
20
21 if [ "$op" != "+" ]&&[ "$op" != "-" ]&&[ "$op" != "*" ]&&[ "$op" != "/" ]##符号不对的话输出提示
22 then
23 print_usage
24 fi
25
26 if [ -n "$(echo $num2|sed 's#[0-9]##g')" ]
27 then
28 print_usage
29 fi
30
31 echo ${num1}${op}${num2}=$((${num1}${op}${num2}))