一、Shell脚本

1.Shell脚本的建立

由Linux命令、shell命令、程序结构控制语句和注释等内容组成。

脚本第一行

#!/bin/bash
#!字符称为幻数,内核会根据它后面的解释器来确定该用什么程序解释脚本

bash与sh的区别

sh为bash的软连接,多数情况下无区别

[xiaoda@codis-178 ~]$ ll /bin/sh
lrwxrwxrwx. 1 root root 4 Mar 4 2016 /bin/sh -> bash
[xiaoda@codis-178 ~]$ ll /bin/bash
-rwxr-xr-x. 1 root root 1009968 Nov 17 2014 /bin/bash

检查bash是否有漏洞

[root@codis-178 ~]# env x='() { :;}; echo be careful' bash -c "echo this is a test"
this is a test

如果返回以下两行,则尽快升级

be careful

this is a test

若不指定解释器,则用对应解释器执行脚本

bash test.sh

python test.py

expect test.exp

2.脚本注释

解释器看不到,不会执行

可跟在脚本命令的后面,与命令在同一行

尽量不要用中文

3.shell脚本的执行

Shell编程基础及变量-LMLPHP

(1)查找系统环境变量ENV,该变量指定了环境文件,加载顺序/etc/profile ->.bash_profile->.bashrc->/etc/bashrc

(2)执行脚本

(3)自上而下,从左到右依次执行(脚本嵌套时,先执行自脚本)

4.执行脚本的方式

(1)bash script-name 或 sh script-name

(2)path/script-name 或 ./script-name

(3)source script-name 或 . script-name

(4)sh<script-name 或 cat script-name|sh

示例:

已知以下命令及返回结果,请问echo $user的返回结果是

cat test.sh

user='whoami'

sh test.sh

echo $user

a.当前用户

b.oldboy

c.无内容输出

答案是:c

解释:

sh和bash执行脚本会启动新的子shell,执行完后退回到父shell,因此变量或函数值无法保留。

结论:

  • 子shell脚本会直接继承父shell脚本的变量、函数等,反之不可
  • 若想反过来继承,要用source 或 "." 在父shell中事先加载子shell

二、变量

1.变量特性

shell中不区分变量的类型(整数、小数、字符串等)

2.变量类型

(1)环境变量(全局)

export内置命令导出的变量(用户名、路径、目录)

名字采用大写形式

set命令输出所有变量(全局和局部)

env命令只显示全局

$HOME   #用户家目录
$UID #当前用户的UID
$PWD #当前工作目录的绝对路径
$SHELL #当前shell
$USER #当前用户

环境变量初始化及生效顺序

Shell编程基础及变量-LMLPHP

  • 登录系统,加载主环境变量文件/etc/profile
  • 执行/etc/profile.d目录下的脚本
  • 运行$HOME/.bash_profile用户环境变量文件
  • 在用户环境变量文件中会去找$HOME/.bashrc,如果有这个文件则执行,没有找/etc/bashrc全局环境变量文件

(2)普通变量(局部)

由字母、数字、下划线组成

可以用单引号或双引号引起来

[xiaoda@codis-178 ~]$ a=192.168.16.1
[xiaoda@codis-178 ~]$ b='192.168.16.1'
[xiaoda@codis-178 ~]$ c="192.168.16.1"
[xiaoda@codis-178 ~]$ echo "a=$a"
a=192.168.16.1
[xiaoda@codis-178 ~]$ echo "b=$b"
b=192.168.16.1
[xiaoda@codis-178 ~]$ echo "c=$c"
c=192.168.16.1
[xiaoda@codis-178 ~]$ echo "c=${c}"
c=192.168.16.1
[xiaoda@codis-178 ~]$ a=192.168.16.1-$a
[xiaoda@codis-178 ~]$ b='192.168.16.1-$a'
[xiaoda@codis-178 ~]$ c="192.168.16.1-$a"
[xiaoda@codis-178 ~]$ echo "a=$a"
a=192.168.16.1-192.168.16.1
[xiaoda@codis-178 ~]$ echo "b=$b"
b=192.168.16.1-$a
[xiaoda@codis-178 ~]$ echo "c=${c}"
c=192.168.16.1-192.168.16.1-192.168.16.1

把命令的结果作为变量的内容进行赋值

[xiaoda@codis-178 ~]$ CMD=$(date + %F)
date: extra operand `%F'
Try `date --help' for more information.
[xiaoda@codis-178 ~]$ CMD=$(date +%F)
[xiaoda@codis-178 ~]$ echo $CMD
2017-07-04
[xiaoda@codis-178 ~]$ echo $(date +%F).tar.gz
2017-07-04.tar.gz
[xiaoda@codis-178 ~]$ echo $(CMD).tar.gz
-bash: CMD: command not found
.tar.gz
[xiaoda@codis-178 ~]$ echo $CMD.tar.gz
2017-07-04.tar.gz
[xiaoda@codis-178 ~]$ echo ${CMD}.tar.gz
2017-07-04.tar.gz

3.变量输出

单引号:内容原样输出,强引用

双引号:如果内容有命令、变量、转移符等,会解析出结果再输出,弱引用

反引号:引用命令

[xiaoda@codis-178 ~]$ echo 'today is date'
today is date
[xiaoda@codis-178 ~]$ echo 'today is `date`'
today is `date`
[xiaoda@codis-178 ~]$ echo "today is date"
today is date
[xiaoda@codis-178 ~]$ echo "today is `date`"
today is Tue Jul 4 15:34:38 CST 2017
[xiaoda@codis-178 ~]$ echo "today is $(date)"
today is Tue Jul 4 15:34:49 CST 2017

调用变量

[xiaoda@codis-178 ~]$ OLDBOY=testchars
[xiaoda@codis-178 ~]$ echo $OLDBOY
testchars
[xiaoda@codis-178 ~]$ echo '$OLDBOY'
$OLDBOY
[xiaoda@codis-178 ~]$ echo "$OLDBOY"
testchars

其他调用方式

[xiaoda@codis-178 ~]$ cat grep.log
testchars
oldboy
[xiaoda@codis-178 ~]$ grep "$OLDBOY" grep.log
testchars
[xiaoda@codis-178 ~]$ grep '$OLDBOY' grep.log
[xiaoda@codis-178 ~]$ grep $OLDBOY grep.log
testchars [xiaoda@codis-178 ~]$ ETT=123 [xiaoda@codis-178 ~]$ awk 'BEGIN {print "$ETT"}'
$ETT
[xiaoda@codis-178 ~]$ awk 'BEGIN {print $ETT}' [xiaoda@codis-178 ~]$ awk 'BEGIN {print '$ETT'}'
123
[xiaoda@codis-178 ~]$ awk 'BEGIN {print "'$ETT'"}'
123

Shell编程基础及变量-LMLPHP

05-28 21:57