【Linux学习八】脚本编程

环境
  虚拟机:VMware 10
  Linux版本:CentOS-6.5-x86_64
  客户端:Xshell4
  FTP:Xftp4

一、多层bash
#.和source都是当前bash

[root@node1 ~]# echo $$
1578

sh01.sh:
echo $$

[root@node1 ~]# . sh01.sh
1578
[root@node1 ~]# source sh01.sh
1578

#在调用bash 进入子bash
[root@node1 ~]# bash sh01.sh
1593

 

pstree:

 

sh02.sh:

#!/bin/bash
echo $$
pstree

 

[root@node1 ~]# ./sh02.sh
1594
init─┬─auditd───{auditd}
├─crond
├─master─┬─pickup
│ └─qmgr
├─6*[mingetty]
├─rsyslogd───3*[{rsyslogd}]
├─sshd───sshd───bash───sh02.sh───pstree
└─udevd───2*[udevd]

#!/bin/bash 等同于开启一个子bash,如果不写这一行 默认开启一个bash

注意:搞清父子bash,不同bash执行结果可能不同。

二、重定向
输出重定向操作符
>:重定向 会覆盖
>>:重定向 追加
标准输出重定向:
ls / 1>1.out
标准错误输出重定向:
ls /abc 2>2.out
将标准输出和错误输出重定向到同一个文件里:
先将标准输出定向到文件,然后将标准错误输出重定向到标准输出(左边不能有空格),错误信息会先打印
ls / /abc 1>ls.out 2>&1
或者
ls / /abc >& ls.out
或者
ls / /abc &> ls.out

输入重定向
<<<:从一个字符读数据
<<:将标志之间的换行符之前的内容输入
<:从一个文件读取数据

[root@node1 /]# read aaa<<<abc.txt
[root@node1 /]# echo $aaa
abc.txt

#对换行符敏感
[root@node1 /]# read bbb<<AABB
> mmm
> nnn
> ddd
> AABB
[root@node1 /]# echo $bbb
mmm

[root@node1 /]# cat 0<abc.txt
hello world

[root@node1 fd]# ll
total 0
lrwx------. 1 root root 64 Dec 24 02:38 0 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 1 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 2 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 255 -> /dev/pts/0
#创建百度TCP连接 重定向到输入8文件
[root@node1 fd]# exec 8<> /dev/tcp/www.baidu.com/80
[root@node1 fd]# ll
total 0
lrwx------. 1 root root 64 Dec 24 02:38 0 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 1 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 2 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 02:56 255 -> /dev/pts/0
lrwx------. 1 root root 64 Dec 24 03:38 8 -> socket:[32425]
#通过8输入文件 创建到百度HTTP请求
[root@node1 fd]# echo -e "GET / HTTP/1.0\n" 1>&8
#通过8输入文件 查看百度http请求返回
[root@node1 fd]# cat 0<&8

 

三、变量
本地:
  当前shell拥有
  生命周期随shell

局部:
  只能local用于函数

位置:  

$1,$2,${11}
脚本
函数

 特殊:  

$#:位置参数个数
$*:参数列表,双引号引用为一个字符串
$@:参数列表,双引号引用为单独的字符串
$$:当前shell的PID:接收者
   $BASHPID:真实
   管道
$?:上一个命令退出状态
   0:成功
   非0:失败

 

[root@node1 /]# aaa=(1 2 3)
[root@node1 /]# echo ${aaa[*]}
1 2 3
[root@node1 /]# echo ${aaa[@]}
1 2 3
管道:
(1)管道会在|两侧各开启一个子bash,不会影响父bash的值
[root@node1 /]# a=1
[root@node1 /]# a=2|echo ok
ok
[root@node1 /]# echo $a
1
(2)管道里面会继承父bash里的变量 但在文件里就不会继承 需要使用export先导出
[root@node1 /]# b=111
[root@node1 /]# a=2 | echo $b
111

sh04.sh:
echo $c

[root@node1 ~]# c=10
[root@node1 ~]# ./sh04.sh

[root@node1 ~]# export c
[root@node1 ~]# ./sh04.sh
100

# $BASHPID是真实pid
[root@node1 ~]# echo $$
1639
[root@node1 ~]# echo $$ | more
1639
[root@node1 ~]# echo $BASHPID | more
6599

 五、退出状态和逻辑判断

退出状态
echo $?
逻辑判断
command1 && command2
command1 || command2

添加用户示例:

#! /bin/bash
[ ! $# -eq 1 ] && echo "args error!!!" && exit 2
id $1 >&/dev/null && echo "user exist" && exit 3
useradd $1 >&/dev/null && echo $1 | passwd --stdin $1 >&/dev/null && echo "user add success" && exit 4
echo "i don't know ,user add fail" && exit 5

 

六、表达式
1.算术表达式
let 算术运算表达式
let C=$A+$B
$[算术表达式]
C =$[$A+$B]
$((算术表达式))
C=$(($A+$B))
expr 算术表达式
注意:表达式中各操作数及运算符之间要有空格。而且要使用命令引用
C=`expr $A + $B`
help let

2.条件表达式
(1)[ expression ]
(2)test expression
(3)[[ expression ]]
help test


七、流程控制

if:
[root@node1 ~]# if test 3 -eq 3; then echo 3=3 ;fi
3=3

while:
[root@node1 ~]# while test $a -le 5;do echo $a;((a++));done
1
2
3
4
5

for:
[root@node1 ~]# for ((a=1;a<=5;a++));do echo $a;done
1
2
3
4
5
[root@node1 ~]# for i in 1 2 3 4 5;do echo $i;((i++));done
1
2
3
4
5
[root@node1 ~]# seq 5
1
2
3
4
5
[root@node1 ~]# for i in `seq 5`;do echo $i;((i++));done
1
2
3
4
5

 

IFS:内部域分隔符,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

#! /bin/bash
#先保存原分隔符 修改为换行符
oldIFS=$IFS
IFS=$'\n'
#遍历 
for i in `du -a $1 | sort -nr`;
do
    filename=`echo $i | awk {print $2}`
    if [ -f $filename ];
    then
        echo $filename;
        break;
    fi;
done
#分隔符改回默认值
IFS=$oldIFS        

 

四种读取文件的方式:

#! /bin/bash
num=0
oldIFS=$IFS
IFS=$'\n'
for i in `cat file.txt`;do
    echo $i;
    ((num++))
done
echo "num:$num"
IFS=$oldIFS
echo "----------------------"
num=0
lines=`cat file.txt | wc -l`
for((i=1;i<=lines;i++));do
    line=`head -$i file.txt | tail -1`
    echo $line
    ((num++))
done
echo "num:$num"
echo "-------------------"
num=0
while read line;do
    echo $line
    ((num++))
done <file.txt
echo "num:$num"
echo "----------------"
num=0
cat file.txt | while read line;do
    echo $line
    ((num++))
done
echo "num:$num"

 

posted @ 2018-12-24 20:43  cac2020  阅读(333)  评论(0编辑  收藏  举报