二、Shell变量

 

 

1. 变量是什么?

一句话概括:变量是用来临时保存数据的,该数据是可以变化的数据。

 

 

 

2. 什么时候需要定义变量?

 如果某个内容需要多次使用,并且在代码中重复出现,那么可以用变量代表该内容。这样在修改内容的时候,仅仅需要修改变量的值。

在代码运作的过程中,可能会把某些命令的执行结果保存起来,后续代码需要使用这些结果,就可以直接使用这个变量。

 

 

3.变量如何定义?

 

变量名:用来临时保存数据的;名称固定,由系统设定或用户定义

变量值:就是临时的可变化的数据;根据用户设置、系统环境变化而变化

 

设置方法:变量名=变量值

 如下:

[root@MissHou ~]# A=hello            定义变量A
[root@MissHou ~]# echo $A            调用变量A,要给钱的,不是人民币是美元"$"
hello
[root@MissHou ~]# echo ${A}        还可以这样调用,不管你的姿势多优雅,总之要给钱
hello
[root@MissHou ~]# A=world            因为是变量所以可以变,移情别恋是常事
[root@MissHou ~]# echo $A            不管你是谁,只要调用就要给钱
world
[root@MissHou ~]# unset A            不跟你玩了,取消变量
[root@MissHou ~]# echo $A            从此,我单身了,你可以给我介绍任何人

 

4. 变量的定义规则

虽然可以给变量(变量名)赋予任何值;但是,对于变量名也是要求的

由数字/字母/下划线组成,区分大小写
不能以数字开头
等号两边不要有空格
不要使用关键字和特殊字符
多次给同一个变量赋值时,最后的值生效

 

 

㈠ 变量名区分大小写

 

[root@MissHou ~]# A=hello
[root@MissHou ~]# a=world
[root@MissHou ~]# echo $A
hello
[root@MissHou ~]# echo $a
world

 

㈡ 变量名不能有特殊符号

 

[root@MissHou ~]# *A=hello
-bash: *A=hello: command not found
[root@MissHou ~]# ?A=hello
-bash: ?A=hello: command not found
[root@MissHou ~]# @A=hello
-bash: @A=hello: command not found

特别说明:对于有空格的字符串给变量赋值时,要用引号引起来
[root@MissHou ~]# A=hello world
-bash: world: command not found
[root@MissHou ~]# A="hello world"
[root@MissHou ~]# A='hello world'

 

㈢ 变量名不能以数字开头

 

[root@MissHou ~]# 1A=hello
-bash: 1A=hello: command not found
[root@MissHou ~]# A1=hello
注意:不能以数字开头并不代表变量名中不能包含数字呦。

 

㈣ 等号两边不能有任何空格

 

[root@MissHou ~]# A =123
-bash: A: command not found
[root@MissHou ~]# A= 123
-bash: 123: command not found
[root@MissHou ~]# A = 123
-bash: A: command not found
[root@MissHou ~]# A=123
[root@MissHou ~]# echo $A
123

 

 

㈤ 变量名尽量做到见名知意

 

NTP_IP=10.1.1.1
DIR=/u01/app1
TMP_FILE=/var/log/1.log
...

 说明:一般变量名使用大写(小写也可以),不要同一个脚本中变量全是a,b,c等不容易阅读

 

(六) 命令的执行结果可以保存到变量

 

[root@server shell01]# kernel=`uname -r`
[root@server shell01]# echo $kernel
2.6.32-431.el6.x86_64
[root@server shell01]# name=$(uname -n)
[root@server shell01]# echo $name
server.itcast.cc

 

 

 

 

5. 变量的定义方式有哪些?

 

㈠ 基本方式

 

直接赋值给一个变量

[root@MissHou ~]# A=1234567
[root@MissHou ~]# echo $A
1234567
[root@MissHou ~]# echo ${A:2:4}        表示从A变量中第3个字符开始截取,截取4个字符
3456

 

说明:
$变量名 和 ${变量名}的异同
相同点:都可以调用变量
不同点:${变量名}可以只截取变量的一部分,而$变量名不可以

 

㈡ 命令执行结果赋值给变量

 

[root@MissHou ~]# B=`date +%F`
[root@MissHou ~]# echo $B
2019-04-16
[root@MissHou ~]# C=$(uname -r)
[root@MissHou ~]# echo $C
2.6.32-696.el6.x86_64

 

 

㈢ 交互式定义变量(read)

目的:让用户自己给变量赋值,比较灵活。

 

语法:read [选项] 变量名

常见选项:

 

-p    定义提示用户的信息
-n    定义字符数(限制变量值的长度)
-s    不显示(不显示用户输入的内容)
-t    定义超时时间,默认单位为秒(限制用户输入变量值的超时时间)

 

 

 


 

举例说明:

 

 

用法1:用户自己定义变量值
[root@MissHou ~]#name=harry [root@MissHou ~]# read name harry [root@MissHou ~]# echo $name harry [root@MissHou ~]# read -p "Input your name:" name Input your name:tom [root@MissHou ~]# echo $name tom

 

 

用法2:变量值来自文件

 

[root@MissHou ~]# cat 1.txt 
10.1.1.1 255.255.255.0

[root@MissHou ~]# read ip mask < 1.txt 
[root@MissHou ~]# echo $ip
10.1.1.1
[root@MissHou ~]# echo $mask
255.255.255.0

 

 

㈣ 定义有类型的变量(declare)

目的: 给变量做一些限制,固定变量的类型,比如:整型、只读

用法:declare 选项 变量名=变量值

常用选项:

 

选项    释义              举例
-i    将变量看成整数        declare -i A=123
-r    定义只读变量         declare -r B=hello
-a    定义普通数组;查看普通数组    
-A    定义关联数组;查看关联数组    
-x    将变量通过环境导出       declare -x AAA=123456 等于 export AAA=123456

 

 

 

举例说明:

 

 

[root@MissHou ~]# declare -i A=123
[root@MissHou ~]# echo $A
123
[root@MissHou ~]# A=hello
[root@MissHou ~]# echo $A
0

[root@MissHou ~]# declare -r B=hello
[root@MissHou ~]# echo $B
hello
[root@MissHou ~]# B=world
-bash: B: readonly variable
[root@MissHou ~]# unset B
-bash: unset: B: cannot unset: readonly variable

 

 


例子:

[root@server shell01]# a=10
[root@server shell01]# b=20
[root@server shell01]# echo $a+$b
10+20

[root@server shell01]# declare -i a=2
[root@server shell01]# declare -i b=4
[root@server shell01]# declare -i c=$a+$b
[root@server shell01]# echo $c
6

[root@server shell01]# AAAA=hello
[root@server shell01]# export AAAA
[root@server shell01]# env|grep AAAA
AAAA=hello
[root@server shell01]# declare -x BBBB=hello
[root@server shell01]# env|grep BBBB
BBBB=hello

 

 

 

6. 变量的分类

 

㈠ 本地变量

本地变量:当前用户自定义的变量。当前进程中有效,其他进程及当前进程的子进程无效。

 

㈡ 环境变量

环境变量:当前进程有效,并且能够被子进程调用。

 

env查看当前用户的环境变量
set查询当前用户的所有变量(临时变量与环境变量)
export //将当前变量变成环境变量 
export 变量名=变量值 或者 变量名=变量值;export 变量名

 

如果想设置环境变量,就要在给变量赋值之后或设置变量时使用export命令。带-x选项的declare内置命令也可完成同样的功能。

(注意:输出变量时不要在变量名前面加$)

 

①export 变量名=value

②变量名=value;export 变量名

③declare -x 变量名=value

 

提示:以上为三种设置环境变量的方法

例:

export NAME = zgy

declare -x NAME =zgy

NAME=zgy;export NAME

 

自定义全局环境变量实例:

[zgy@Web ~]$ . .bash_profile

[zgy@Web ~]$ echo $ZGY

zgy

[root@Web ~]# cat /etc/profile | grep ZGY

export ZGY='zgy'

[root@Web ~]# source /etc/profile 或. /etc/profile使其生效

[root@Web ~]# echo $ZGY

zgy

[root@Web ~]# env | grep ZGY

ZGY=zgy

 

 

 

查看变量:echo $变量名

 

 

如下:

 

[root@MissHou ~]# export A=hello        临时将一个本地变量(临时变量)变成环境变量
[root@MissHou ~]# env|grep ^A
A=hello

永久生效:
vim /etc/profile 或者 ~/.bashrc
export A=hello
或者
A=hello
export A

说明:系统中有一个变量PATH,环境变量
export PATH=/usr/local/mysql/bin:$PATH

 

 

环境变量用于定义shell的运行环境,保证shell命令的正确执行,shell通过环境变量来确定登陆用户名、命令路径、终端类型、登陆目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、shell脚本和各类应用。

  环境变量可以在命令行中设置,但用户退出时这些变量值也会丢失,因此最好在用户家目录下的.bash_profile文件中或全局配置/etc/bashrc,/etc/profile文件或者/etc/profile.d/中定义。将环境变量放入profile文件中,每次用户登录时这些变量值都会被初始化。

  传统上,所有环境变量均为大写。环境变量应用于用户进程前,必须用export命令导出。

  环境变量可用在创建他们的shell和从该shell派生的任意子shell或进程中。他们通常被称为全局变量以区别局部变量。通常,环境变量应该大写。环境变量是已经用export内置命令导出的变量。

 

  有些环境变量,比如HOME、PATH、SHELL、UID、USESR等,在用户登陆之前就已经被/bin/login程序设置好了。通常环境变量定义并保存在用户家目录下的.bash_profile文件中。

 

常见的环境变量

 

 

   
PWD    
PATH    
USER    
LOGNAME    
UID    
SHELL    
HOME    
PS1    
PS2    

 

 

㈢ 全局变量

 

 

全局变量:全局所有的用户和程序都能调用,且继承,新建的用户也默认能调用.

解读相关配置文件

 

 

文件名说明备注
$HOME/.bashrc 当前用户的bash信息,用户登录时读取 定义别名、umask、函数等
$HOME/.bash_profile 当前用户的环境变量,用户登录时读取  
$HOME/.bash_logout 当前用户退出当前shell时最后读取 定义用户退出时执行的程序等
/etc/bashrc 全局的bash信息,所有用户都生效  
/etc/profile 全局环境变量信息 系统和所有用户都生效
$HOME/.bash_history 用户的历史命令 history -w 保存历史记录 history -c 清空历史记录

 

 

 

**说明:**以上文件修改后,都需要重新source让其生效或者退出重新登录。

用户登录系统读取相关文件的顺序

 

        /etc/profile
        $HOME/.bash_profile
        $HOME/.bashrc
        /etc/bashrc
        $HOME/.bash_logout

 

 用户登录系统读取相关文件的顺序:
/etc/profile——>$HOME/.bash_profile——>$HOME/.bashrc——>/etc/bashrc——>$HOME/.bash_logout

 

㈣ 特殊变量

 

在shell中有两类特殊的变量,一类被称为位置变量,另一类被称为进程状态变量。下面列出位置变量和进程状态变量的具体内容:


 

1.位置参数

 

 

$0:获取当前执行Shell脚本的文件名字,如果执行脚本时候加了路径,那就包含脚本路径跟脚本名字一起输出
$n:获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9,用大括号括起来,例如${10};脚本后面的位置参数,$1表示第1个位置参数,依次类推
$#:获取当前shell命令行中参数的总个数



$*:获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于"$1$2$3",注意与$#的区别;脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开
$@:获取程序的所有参数"$1""$2""$3""...",这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。脚本后面所有参数,参数是独立的,也是全部输出
提示:$*和$@的区别?

 

$n实例:

(1)$1,$2....$9${10}${11}

(1)$1,$2....$9${10}${11}
[root@Web ~]# cat n.sh 
echo $1
[root@Web ~]# sh  n.sh boy zhaoyang
boy
[root@Web ~]# sh n.sh "boy zhaoyang"
boy zhaoyang

 

提示:加引号括起来表示为一个参数

 

[root@Web ~]# cat n.sh 
echo $1 $2
[root@Web ~]# sh n.sh boy zhanyang
boy zhanyang
[root@Web ~]# sh n.sh "boy zhanyang" luya
boy zhanyang luya

 

 

(2)$0取脚本的名称,包括路径

 

 

 

[root@Web ~]# cat n.sh 
echo $0 
[root@Web ~]# sh n.sh 
n.sh

 

 

提示:当要执行的脚本为全路径时$0也会带着路径。此时如果希望取出名称或路径,用下面的方法。

[root@Web ~]# cat dirname.sh 
dirname $0
[root@Web ~]# sh dirname.sh 
.
[root@Web ~]# basename /etc/inittab 
inittab
[root@Web ~]# cat 0.sh
dirname $0
basename $0
[root@Web ~]# sh 0.sh
.
0.sh

 

 

了解$*和$@的区别:
$*    :表示将变量看成一个整体
$@    :表示变量是独立的 

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

echo "======我是分割线======="

for i in "$*"
do
echo $i
done

[root@MissHou shell01]# bash 3.sh a b c
a
b
c
======我是分割线=======
a b c


注意:$*和​$@的区别

$*和$@都表示传递给函数或脚本的所有参数,不被双引号""包含时,都以$1 $2 …$n的形式输出所有参数。

1.编写脚本


#!/bin/bash

for i in $*
do
      echo "wo shi $i "
done

for j in $@
do      
        echo "wo shi $j"
done

 

2. 进行测试

[laozheng@linux2 bin]$ ./for.sh 1 2 3 4
wo shi 1
wo shi 2
wo shi 3
wo shi 4
wo shi 1
wo shi 2
wo shi 3
wo shi 4

 


我们可以发现不管是$*,还是$@,实际上都打印了4遍

但是当它们被双引号""包含时,"$*"会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;
"$@"会将各个参数分开,以"$1" "$2"…"$n"的形式输出所有参数

    
1.编写脚本

#!/bin/bash

for i in "$*"
do
      echo "wo shi $i "
done

for j in "$@"
do      
        echo "wo shi $j"
done

 

2. 进行测试

[laozheng@linux2 bin]$ ./for.sh 1 2 3 4
wo shi 1 2 3 4
wo shi 1
wo shi 2
wo shi 3
wo shi 4

 
我们可以清楚的发现"$*"将1 2 3 4作为一个整体返回,而"$@"则是将输入参数作为多个个体返回

 

难点理论与实战剖析

 

$*和$@的区别
$*: 获取当前shell的所有参数,将所有的命令行所有参数视为单个字符串,等同于"$1$2$3"
$@:将命令行每个参数视为单独的字符串,等同于"$1"、"$2"、"$3"。这是将参数传递给其他程序的最佳方式,
因为它会保留所有内嵌在每个参数里的任何空白。

 获取当前shell的所有参数,将所有的命令行参数视为单个字符

示例1:

 

[root@Web ~]# set -- "I am" handsome boy  #传入三个参数
[root@Web ~]# echo $#
3
[root@Web ~]# for i in $*;do echo $i;done  #循环打印这些参数,用$*,无引号
I
am
handsome
boy

 

示例2:

 

[root@Web ~]# for i in $@;do echo $i;done  #在没有双引号的情况下,这里的结果$*和$@是一样的
I
am
handsome
boy
[root@Web ~]# for i;do echo $i;done  #去掉in变量列表,相当于in “$@”
I am
handsome
boy

[root@Web ~]# for i in "$@";do echo $i;done  #在有双引号的情况下,参数里引号内容当作一个参数输出了,这才符合我们真正的参数需求,set -- "I am" handsome oldboy.
I am
handsome
boy
[root@Web ~]# for i in "$*";do echo $i;done   #加了双引号,$*表示一个字符串
I am handsome boy
[root@Web ~]# shift   #用shift去掉第一个参数
[root@Web ~]# echo $#
2
[root@Web ~]# for i in "$*";do echo $i;done  #再次打印只剩下后面两个参数了
handsome boy
[root@Web ~]# for i in "$@";do echo $i;done
handsome
boy

 

 

练习:写一个脚本

 

给脚本传递两个参数(整数)

显示此两者之和,之乘积

 

 

#!/bin/bash
#
if [ $# -lt 2 ]; then
  echo "Usage: cacl.sh ARG1 ARG2"
  exit 8
fi

echo "The sum is: $[$1+$2]."
echo "The prod is: $[$1*$2]."

 

 

2.进程状态变量

 

 

$$:获取当前shell的进程号(PID)
$!:执行上一个指令的PID
$_:在此之前执行的命令或脚本的最后一个参数

$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
 若退出状态值为0,表示命令运行成功
 若退出状态值为127,表示command not found
 若退出状态值为126,表示找到了该命令但无法执行(权限不够)
 若退出状态值为1&2,表示没有那个文件或目录
 

 

 

 举例:

 

[root@Web ~]# cat etiantian.sh 
echo '$0  获取当前执行的shell脚本的文件名,包括脚本路径:' $0
echo '$n 获取当前执行的shell脚本的第n个参数值,n=1..9:' '$1'=$1 '$2'=$2 "\$3=$3"   #当使用双引号时必须把两边括起来,并且要用反斜杠
echo '$* 获取当前shell的所有参数 "$1 $2 $3...注意与$#的区别:'$*
echo '$#:获取当前shell命令行中惨呼的总个数:' $#
echo '$@:这个程序的所有参数”$1””$2””$3””...”:' $@
echo '$$ 获取当前shell的进程号(PID):'$$
sleep 2
echo '$!:执行上一个指令的PID:' $!
echo '$? 获取执行上一个指令的返回值:' $?
echo '$_:在此之前执行的命令或脚本的最后一个参数:' $_

 

 

执行结果:

[root@Web ~]# sh etiantian.sh 参数1 参数2 参数3
'etiantian.sh 获取当前执行的shell脚本的文件名,包括脚本路径:' etiantian.sh
$n 获取当前执行的shell脚本的第n个参数值,n=1..9: $1=参数1 $2=参数2 $3=参数3
$* 获取当前shell的所有参数 "$1 $2 $3...注意与$#的区别:参数1 参数2 参数3
$#:获取当前shell命令行中参数的总个数: 3
$@:这个程序的所有参数”$1””$2””$3””...”: 参数1 参数2 参数3
$$ 获取当前shell的进程号(PID):5738
$!:执行上一个指令的PID:
$? 获取执行上一个指令的返回值: 0
$_:在此之前执行的命令或脚本的最后一个参数: 0

 


$?实例

[root@Web ~]# su - zgy
[zgy@Web ~]$ ll
总用量 8
-rwxrw-r--. 1 zgy zgy 14 4月  11 16:06 test.sh
-rw-rw-r--. 1 zgy zgy 14 4月  11 13:12 testsource.sh
[zgy@Web ~]$ echo $?
0
[zgy@Web ~]$ ll /root/
ls: 无法打开目录/root/: 权限不够
[zgy@Web ~]$ echo $?
2
[zgy@Web ~]$ ddd
-bash: ddd: command not found
[zgy@Web ~]$ echo $?
127
1)编译软件的时候判断成功与否
make 
make install
echo $?

 

 

退出状态及其含义:

 

 $?返回值参考:

 

0:表示运行成功

2:权限拒绝

1~125:表示运行失败,脚本命令、系统命令错误或参数传递错误

126:找到该命令了,但是无法执行

127:未找到要运行的命令

>128:命令被系统强制结束

 

 

提示:在脚本调用,一般用exit 0,函数return 0.

 


 

 

bash内部变量

有些内部命令在目录列表时是看不见的,它们由shell本身提供,常见的内部命令有:

echo,eval,exec.export,readonly,read,shift,wait,exit和点(.)

 

echo 变量名表

 

 

将变量名表指定的变量显示到标准输出

 

 

 

 

evalargs

 

 

读入参数args,并将它们组合成一个新的命令,然后执行

 

 

 

 

exec 命令参数

 

当shell执行带exec语句时,不会去创建新的子进程,而是转去执行指定的命令,当指定的命令执行完后时,该进程(也就是最初的shell)就终止了,所以shell程序中exec后面的语句将不再被执行

 

 

 

 

export变量名=value

shell可以用export把它的便利向下带入子shell,从而让子进程继承父进程中的环境变量。但子shell不能用export把它的变量向上带入父shell。

 

 

readonly 变量名

 

 

只读变量 用readonly显示所有只读变量

 

 

 

 

read 变量名表

 

从标准输入读字符串,传给指定变量

可以在函数中用local变量名的方式申请局部变量

 

 

shift 语句

Shift语句按如下方式重命名所有的位置参数变量,即$2成为$1,$3称为$2...在程序中每使用一个shift语句,都使所以的位置参数一次向左移动一个位置,并使位置参数$#减1,直到减到0为止。

 

 

内部变量实践:

1)shift命令实例

[root@Web ~]# cat n.sh

echo $1 $2

if [ $# -eq 2 ];then

    shift

echo $1

fi

[root@Web ~]# sh n.sh 1 2

1 2      #这里是echo $1 $2的结果

2        #这里是echo $1的结果但是是传参时$2的值

 

 

Shell变量的输入

Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入获得。

[语法格式]

  read [参数][变量名]

[常见参数]

-p prompt:设置提示信息

-t timeout:设置输入等待的时间,单位默认为秒

 

 

 

 

 

 

范例1:read的基本读入

[root@localhost ~]# read -p "please input two number:" a1 a2  #红色部分要有空格

please input two number:12 13

[root@localhost ~]# echo $a1 $a2

12 13

 

 

提示:上面read -p 的功能可以用echo和read实现

echo -n "please input two number:"

read a1 a2

 

 

以上两句和下面的命令相当(-t排除在外)

[root@localhost ~]# read -t 5 -p "please input two number:" a1 a2

 

 

范例2:实践考试题

把前面的加减乘除计算的脚本改成通过read方式读入整数变量:

原始脚本:

[root@localhost ~]# cat test.sh

#!/bin/bash

a=6

b=2

echo "a-b =$(($a-$b))"

echo "a+b =$(($a+$b))"

echo "a*b =$(($a*$b))"

echo "a/b =$(($a/$b))"

echo "a**b =$(($a**$b))"

echo "a%b =$(($a%$b))

 

 

 

 

答案:

[root@localhost ~]# cat read_01.sh

#!/bin/bash

read -t 10 -p "plus input two number:" a b

echo "a-b =$(($a-$b))"

echo "a+b =$(($a+$b))"

echo "a*b =$(($a*$b))"

echo "a/b =$(($a/$b))"

echo "a**b =$(($a**$b))"

echo "a%b =$(($a%$b))"

 

[root@localhost ~]# sh read_01.sh

plus input two number:6 2

a-b =4

a+b =8

a*b =12

a/b =3

a**b =36

a%b =0

 

 

 

范例3:利用echo命令替代和read -p的功能

[root@localhost ~]# cat g.sh

#!/bin/bash

echo -n "please input two number:"

read a b

echo "a-b =$(($a-$b))"

echo "a+b =$(($a+$b))"

echo "a*b =$(($a*$b))"

echo "a/b =$(($a/$b))"

echo "a**b =$(($a**$b))"

echo "a%b =$(($a%$b))"

 

[root@localhost ~]# sh g.sh

please input two number:10 5

a-b =5

a+b =15

a*b =50

a/b =2

a**b =100000

a%b =0

 

 

 

范例4:思考:如果读入的不是整数,或者参数个数不是2个,以上shell脚本的执行会有什么结果?如何解决这两个问题?

 

 

方法1:

[root@localhost test]# cat read01.sh

#!/bin/bash

while true

do

    read -t 10 -p "pls input two number:" a b

    expr $a + 0 >/dev/null 2>&1

    [ $? -ne 0 ] && continue

    expr $b + 0 >/dev/null 2>&1

    [ $? -ne 0 ] && continue || break

done

 

echo "a-b =$(( $a - $b ))"

echo "a+b =$(( $a + $b ))"

echo "a*b =$(( $a * $b ))"

echo "a/b =$(( $a * $b ))"

echo "a**b =$(( $a ** $b ))"

echo "a%b =$(( $a % $b ))"

 

 

 

方法2:命令行传参

[root@localhost test]# cat argv1.sh

#!/bin/bash

a="$1"

b="$2"

Usage() {

    echo "USAGE:sh $0 num1 num2"

    exit 1

}

if [ $# -ne 2 ];then

    Usage

fi    

 

expr $a + 0 >/dev/null 2>&1

[ $? -ne 0 ] && Usage

expr $b + 0 >/dev/null 2>&1

[ $? -ne 0 ] && Usage

 

echo "a-b =$(( $a - $b ))"

echo "a+b =$(( $a + $b ))"

echo "a*b =$(( $a * $b ))"

echo "a/b =$(( $a / $b ))"

echo "a**b =$(( $a ** $b ))"

echo "a%b =$(( $a % $b ))"

[root@localhost ~]# sh argv_01.sh kk yy

USAGE:sh argv_01.sh num1 num2

[root@localhost ~]# sh argv_01.sh kk 22

USAGE:sh argv_01.sh num1 num2

[root@localhost ~]# sh argv_01.sh 33 22

a-b =11

a+b =55

a*b =726

a/b =1

a**b =-7228359672964211007

a%b =11

[root@localhost ~]# sh argv_01.sh 6 4

a-b =2

a+b =10

a*b =24

a/b =1

a**b =1296

a%b =2

 

 

 

 

 

 

 

 

7.查看变量值和撤销变量

 

显示变量值

通过echo命令打印环境变量

echo $变量名或echo ${变量名}
$:通过指定变量名称引用变量值

 

例子:

$HOME:用户登录时进入的目录
 $UID:当前用户的UID(用户标识)相当于id -u
 $PWD:当前工作目录的绝对路径名
 $SHELL:当前SHELL
 $USER:当前用户
.....省略若干

 

例子2:

[root@Web ~]# echo $USER
root
[root@Web ~]# echo $PWD
/root
[root@Web ~]# echo $UID
0
[root@Web ~]# echo $SHELL
/bin/bash

 

 提示:在写shell脚本时可以直接使用上面的系统默认的环境变量。

 

例子3:

[root@MissHou shell01]# a=12345678
[root@MissHou shell01]# echo $a
12345678
[root@MissHou shell01]# echo ${a}
12345678
[root@MissHou shell01]# echo ${a:2:3}        a表示变量名;2表示从第3个字符开始;3表示后面3个字符
345

 

 

env(printenv)或set显示默认的环境变量

 

set | grep 变量名
env | grep 变量名   看不到自定义变量

 

 

unset消除本地变量和环境变量

 

unset 变量名

 

例子:

[zgy@Web ~]$ echo $USER
zgy
[zgy@Web ~]$ unset USER
[zgy@Web ~]$ echo $USER
                #此处为输出的空行

可以看到变量的内容显示为空了

 本地变量在用户当前的shell生存期的脚本中使用。例如,本地变量OLDBOY取值为ett098,这个值只在用户当前shell生存期中有意义。如果在shell中启动另一个进程或退出,本地变量OLDBOY值将无效。

 

8.变量名的设置规则

 

 

由数字/字母/下划线组成,区分大小写
不能以数字开头
等号两边不要有空格
不要使用关键字和特殊字符
多次给同一个变量赋值时,最后的值生效

 

普通字符串变量定义

变量名=value

变量名='value'

变量名="value"

 

 

 

 例1:下面的例子会输出什么结果。

 

a=192.168.1.2
b='192.168.1.2'
c="192.168.1.2"
echo "a=$a"
echo "b=$b"
echo "c=${c}"

提示:

1)$c和${c}在这里等同

2)需要在命令行实践以上内容

 

 

思考:想一想a,b,c各是什么结果

答案:

 

 

[zgy@Web ~]$ echo "a=$a"
a=192.168.1.2
[zgy@Web ~]$ echo "b=$b"
b=192.168.1.2
[zgy@Web ~]$ echo "c=${c}"
c=192.168.1.2

 

 

 

 

例2:想一想a,b,c各是什么结果?

 

 

a=192.168.1.2-$a
b='192.168.1.2-$a'
c="192.168.1.2-$a"
echo "a=$a"
echo "b=$b"
echo "c=${c}"

 

思考:再想一想a,b,c现在各是什么结果?为什么是这个结果?

 

zgy@Web ~]$ echo "a=$a"
a=192.168.1.2-192.168.1.2
[zgy@Web ~]$ echo "b=$b"
b=192.168.1.2-$a
[zgy@Web ~]$ echo "c=${c}"
c=192.168.1.2-192.168.1.2-192.168.1.2

 

提示:

 

 

1.第一种定义a变量的方式是直接定义变量内容,内容一般为简单连续的数字、字符串、路径名等。
2.第二种定义b变量的方式是通过单引号定义变量。这个方式的特点是:输出变量时引号里是什么就输出什么,即使内容中有变量也会把变量名原样输出。此法比较适合于定义显示纯字符串
3.第三种定义c变量方式是通过双引号定义变量。这个方式的特点是:输出变量时引号里的变量会经过解析后输出该变量内容,而不是把引号中变量名原样输出,适合于字符串中附带有变量的内容的定义。
习惯:数字不加引号,其他默认加双引号。

 

 

 

定义变量单引号、双引号与不加引号

 

有关单引号、双引号与不加引号的简要说明如下:

 

 

单引号:
可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么。
双引号:
把双引号内的内容输出来;如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终结果。
无引号:
把内容输出来,会将含有空格的字符串视为一个整体输出,如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终结果来,
如果字符串中带有空格等特殊字符,则不能完整的输出,需要改加双引号,一般连续的字符串,数字,路径等可以不加任何引号,不过最好用双引号替代之。

 

 

单引号、双引号与不加引号实践演示:

 

范例1:经过反引号的`date`命令测试

[root@localhost ~]# echo '`date`'   #单引号时看到什么就显示什么
`date`
[root@localhost ~]# echo "`date`"   #双引号时如果里面是变量,会先把变量解析成具体内容在显示
2015年 04月 11日 星期六 22:08:16 CST

[root@localhost ~]# echo `date`   #对于连续的字符串等内容一般不加引号也可,加双引号一般比较保险,推荐
2015年 04月 11日 星期六 22:08:46 CST

 

范例2:变量定义后,调用时测试

 

[root@localhost ~]# ZGY=testchars  #创建一个不带引号的变量
[root@localhost ~]# echo $ZGY  #不加引号,显示一个变量解析的内容
testchars
[root@localhost ~]# echo '$ZGY'  #单引号,显示一个变量本身
$ZGY
[root@localhost ~]# echo "$ZGY"   #双引号,显示一个变量内容,引号内可以是变量、字符串等
testchars

 

范例3:grep过滤字符串例子

[root@localhost ~]# cat >grep.log
testchars
zgy
[root@localhost ~]# grep "$ZGY" grep.log 
testchars
[root@localhost ~]# grep $ZGY grep.log 
testchars
[root@localhost ~]# grep '$ZGY' grep.log 
过滤双引号测试
[root@localhost ~]# cat >grep.log
\"
[root@localhost ~]# grep '\"' grep.log 
\"

 

特殊例子:awk调用shell变量引号例子

 

[root@localhost ~]# ETT=123
[root@localhost ~]# awk 'BEGIN{print '$ETT'}'
123
[root@localhost ~]# awk 'BEGIN {print "$ETT"}'
$ETT

 

提示:以上的结果正好的前面的结论相反。这是awk调用shell变量的特殊用法

 

[root@localhost ~]# ETT='abc'
[root@localhost ~]# awk 'BEGIN {print "$ETT"}'
$ETT
[root@localhost ~]# awk 'BEGIN {print '$ETT'}'

[root@localhost ~]# awk 'BEGIN {print "'$ETT'"}'
abc

 

提示:

这个例子更特殊了一点。

 

有关awk调用shell变量读者还可以参考http://blog.51cto.com/oldboy/760192

 

 

 一道实用linux运维问题的9种shell解答方法

 

问题为:

 

4)已知:/etc/hosts的内容为
192.168.1.11  oldboy11.etiantian.org
192.168.1.21  oldboy21.etiantian.org
192.168.1.31  oldboy31.etiantian.org
#192.168.1.111  oldboy111.etiantian.org
请用shell脚本实现,怎么才能在输入IP后找到/etc/hosts里对应的唯一的hostname?

 

 

解答:

 

法1)脚本过滤法

[root@old_boy scripts]# cat judgehost.sh   
#!/bin/bash  
echo "please input ip address:" 
read ip  
[ -n "`grep "$ip " /etc/hosts`" ] && \  #注意前面的过滤条件结尾带有空格。  
echo "The hostname is: `grep "$ip " /etc/hosts |awk '{print $2}'`" || \  
echo "The ip is invalid" 

 提示:
1)这是一个grep过滤加条件判断的实现语法:
2)条件判断语法为[ -n "ddd" ] && echo 1 || echo 0
3)[ -n "`grep "$ip " /etc/hosts`" ] && \  #注意前面的过滤条件结尾带有空格。这里啊,是为了排除下面的重复情况
 192.168.1.11  oldboy11.etiantian.org
 192.168.1.111  oldboy111.etiantian.org
----------------我是每种方法分隔符---------------
法2)脚本精确匹配法:

#!/bin/bash  
#author oldboy  
#qq 31333741  
#judge input  
if [ $# -ne 1 ]  
  then 
    echo "input error!" 
    exit 1  
fi  
 
flag=0  
exec < /etc/hosts  
while read line  
do  
 if [ "$1" = "`echo $line|awk '{print $1}'`" ]  
   then 
       flag=1  
       echo "the $1 's hostname is `echo $line|awk '{print $2}'`"   
       break;  
 fi  
done   
[ $flag -eq 0 ] && echo " sorrry,not find $1 's hostname!" 
     

提示:此题,请大家学习while的用法及设置flag的思路。
执行结果:
[root@old_boy scripts]# sh oldboy.sh 192.168.1.11
the 192.168.1.11 's hostname is oldboy11.etiantian.org
[root@old_boy scripts]# sh oldboy.sh 192.168.1.21
the 192.168.1.21 's hostname is oldboy21.etiantian.org
[root@old_boy scripts]# sh oldboy.sh 192.168.1.311
 sorrry,not find 192.168.1.311 's hostname!
----------------我是每种方法分隔符---------------
 

特别提示:下面的方法中,老男孩老师大量的使用了awk的不同方法来实现同样的功能,来告诉大家,awk是很强大的, 希望同学们能按照老师的教学要求精通之。

法3)awk精确匹配:
准备:
[root@old_boy scripts]# tail -4 /etc/hosts
192.168.1.11  oldboy11.etiantian.org
192.168.1.111  oldboy111.etiantian.org
192.168.1.21  oldboy21.etiantian.org
192.168.1.31  oldboy31.etiantian.org
脚本:

[root@old_boy scripts]# cat awkhost1.sh   
awk 'BEGIN {a="'$1'"} {if($1==a) print $2; }' /etc/hosts  

执行结果:
[root@old_boy scripts]# sh awkhost1.sh 192.168.1.21
oldboy21.etiantian.org
[root@old_boy scripts]# sh awkhost1.sh 192.168.1.31
oldboy31.etiantian.org
[root@old_boy scripts]# sh awkhost1.sh 192.168.1.11
oldboy11.etiantian.org
提示:注意a="'$1'"的用法,$1为命令行传参。awk程序中调用系统变量的方法a="'$1'"----------------我是每种方法分隔符---------------
法4)awk精确匹配法

[root@old_boy scripts]# cat awkhost2.sh   
awk '{if($1=="'$1'") print $2}' /etc/hosts  

执行结果:
[root@old_boy scripts]# awkhost2.sh 192.168.1.11
oldboy11.etiantian.org
[root@old_boy scripts]# awkhost2.sh 192.168.1.21
oldboy21.etiantian.org
[root@old_boy scripts]# awkhost2.sh 192.168.1.311
----------------我是每种方法分隔符---------------
法5)awk过滤法

[root@old_boy scripts]# cat awkhost4.sh   
awk '/'"${1} "'/''{print $2}' /etc/hosts  
执行结果:  
[root@old_boy scripts]# awkhost4.sh 192.168.1.21  
oldboy21.etiantian.org  
[root@old_boy scripts]# awkhost4.sh 192.168.1.11  
oldboy11.etiantian.org  
[root@old_boy scripts]# awkhost4.sh 192.168.1.31  
oldboy31.etiantian.org  
提示:除了语法外,这道题有个学问,就是过滤时传参结尾要带个空格,这样才能过滤重复IP的情况  
如:  
 192.168.1.11  oldboy11.etiantian.org  
 192.168.1.111  oldboy111.etiantian.org 

----------------我是每种方法分隔符---------------
法6)awk过滤法

[root@old_boy scripts]# cat awkhost5.sh   
awk '{if($1~/'$1'/) print $2}'  /etc/hosts ##如果文件第一列包含命令行第一个参数字符则打印第二列  
执行结果:  
[root@old_boy scripts]# awkhost5.sh 192.168.1.31  
oldboy31.etiantian.org  
[root@old_boy scripts]# awkhost5.sh 192.168.1.11  
oldboy11.etiantian.org  
oldboy111.etiantian.org ------>这里有bug了。  
[root@old_boy scripts]# awkhost5.sh 192.168.1.21  
oldboy21.etiantian.org  
改进下来排除bug:  
[root@old_boy scripts]# cat awkhost5-1.sh   
awk '{if($1~/'$1' /) print $2}'  /etc/hosts ==>用上面加空格的思路不对。  
[root@old_boy scripts]# cat awkhost5-1.sh   
awk '{if($1~/'$1'$/) print $2}'  /etc/hosts #增加一个正则表达式$  
执行结果:  
[root@old_boy scripts]# awkhost5-1.sh 192.168.1.21  
oldboy21.etiantian.org  
[root@old_boy scripts]# awkhost5-1.sh 192.168.1.11  
oldboy11.etiantian.org  
[root@old_boy scripts]# awkhost5-1.sh 192.168.1.31  
oldboy31.etiantian.org 

----------------我是每种方法分隔符---------------
法7)awk -v精确匹配法
 

命令行测试:  
[root@old_boy scripts]# awk -v p=192.168.1.21 '$1 == p{print $2}' /etc/hosts  
oldboy21.etiantian.org  
[root@old_boy scripts]# awk -v p=192.168.1.11 '$1 == p{print $2}' /etc/hosts  
oldboy11.etiantian.org  
[root@old_boy scripts]# awk -v p=192.168.1.11 '$1 == p {print $2}' /etc/hosts  
oldboy11.etiantian.org  
实际脚本: 
[root@old_boy scripts]# cat awkhost6.sh   
#!/bin/bash  
#p=$1  
#awk -v p="$p" '$1 == p{print $2}' /etc/hosts  
awk -v p="$1" '$1 == p{print $2}' /etc/hosts 

执行结果:
[root@old_boy scripts]# sh  awkhost6.sh  192.168.1.11
oldboy11.etiantian.org
[root@old_boy scripts]# sh  awkhost6.sh  192.168.1.21
oldboy21.etiantian.org
提示:
1)传参非awk程序,因此写法p="$1"
2)man awk
       -v var=val
       --assign var=val
              Assign the value val to the variable var, before execution of the program begins.   Such  vari-
              able values are available to the BEGIN block of an AWK program.
----------------我是每种方法分隔符---------------
法8:精确匹配简单的写法

[root@old_boy scripts]# cat awkhost9.sh   
awk  '$1 == "'$1'" {print $2}' /etc/hosts  
执行结果:  
[root@old_boy scripts]# sh awkhost9.sh  192.168.1.11  
oldboy11.etiantian.org  
[root@old_boy scripts]# sh awkhost9.sh  192.168.1.21  
oldboy21.etiantian.org  
[root@old_boy scripts]# sh awkhost9.sh  192.168.1.31  
oldboy31.etiantian.org  
特别提示:这里老男孩老师大量的使用了awk的不同方法来实现同样的功能,很强大吧,  
希望同学们能按照老师的教学要求精通之。 

----------------我是每种方法分隔符---------------
法9:学生的一个不成熟的实现法

#!/bin/bash  
b=/$PWD/wang.txt  
echo -n "plase input ip : " 
read a  
if [ $a == "192.168.1.11" ]  
        then 
cat $b | grep $a | awk -F ' ' '{print $2}' 
 
elif [ $a  == "192.168.1.21" ]   
        then 
cat $b | grep $a | awk -F ' ' '{print $2}' 
 
elif [ $a  == "192.168.1.31" ]  
        then 
cat $b | grep $a | awk -F ' ' '{print $2}' 
        else 
echo "plase input the correct IP address " && exit 1  
fi  
提示:大家看看问题在哪?脚本不通用。  
 

------老男孩老师改进后 

#!/bin/bash  
#author oldboy  
#qq 31333741  
hosts_file="$PWD/oldboy.txt" 
#judge file  
[ ! -f $hosts_file ] && echo "no test file!" && exit 1  
echo -n "plase input ip : " 
read ip  
#judge ip format  
[ "${#a}" -lt 8 ] && [ "`echo $ip|sed 's/[0-9]//g'`" != "..." ] && \  
echo "Plase input the correct IP address" && exit 1  
 
#start  
result1=$(grep "$ip" $hosts_file|awk '{print $1}')  
if [ "$ip" == "$result1" ]  
  then   
        grep "$ip" $hosts_file|awk '{print $2}' 
        exit 0  
else 
        echo  "Not find the hostname of $ip" 
        exit 1  
fi  
提示:此法不可取,画蛇添足了。  

 

 

 

9.自定义变量的建议

 

自定义变量的建议:

(1)纯数字(不带空格),定义方式可以不加引号(单或双),例如:

A.oldboy=33

B.NETWORKING=yes

(2)没特殊情况,字符串一般用双引号定义,特别是多个字符串中间有空格时,例如:

A.NFSD_MODULE="no load"

B.MyName="Oldboy is a handsome boy."

 

 

(3)变量内容需要原样输出时,要用单引号('')。

A.OLDBOY_NAME='OLDBOY'

 

变量的命名规范

1)变量命名要统一,使用全部大写字母,如APACHE_ERR_NUM;语义要清晰,能够正确表达变量内容的含义,过长的英文单词可采用前几个字符代替。多个单词连接使用”_”号连接,引用时,最好以${APACHE_ERR_NUM}加大括号或”${APACHE_ERR_NUM}”外面加双引号方式引用变量:

2)避免无含义字符或数字:例如下面的COUNT,并不知道其确切含义;

范例1:COUNT的不确切定义

COUNT=`grep keywords file`

if [ ${COUNT} -ne 22 ]

then

Echo ‘Do Something’

fi

 

 

3)全局变量和局部变量命名

A.脚本中的全局变量定义,如OLDBOY_HOME或OLDBOYHOME,在变量使用时,使用{}将变量括起或”${OLDBOY_HOME}”

范例2:操作系统函数库脚本内容全局变量截取例子

[root@Web ~]# cat /etc/init.d/functions

# -*-Shell-script-*-

#

# functions     This file contains functions to be used by most or all

#               shell scripts in the /etc/init.d directory.

#

TEXTDOMAIN=initscripts

 

B.脚本中局部变量定义:存在于脚本函数(function)中的变量称为局部变量,要以local方式进行声明,使之只在本函数作用域内有效,防止变量在函数中的命名与变量外部程序中变量重名造成持续异常。下面是函数中的变量定义例子:

范例3:函数内的变量定义

Function TestFunc()

{

local i

for((i=0;i<n;i++))

do

echo ‘do something’

done

}

 

 

范例4:操作系统函数库脚本内容局部函数变量截取例子

# Check if any of $pid (could be plural) are running

checkpid() {

        local i

 

        for i in $* ; do

                [ -d "/proc/$i" ] && return 0

        done

        return 1

}

 

4)变量合并:当某些变量或配置项要组合起来才有意义时,如文件的路径和文件名称,建议将要组合的变量合并到一起赋值给一个新的变量,这样既方便之后的调用,也为以后进行修改提供了方便。

范例5:自动化安装httpd的脚本变量合并定义

VERSION="2.2.22"

SOFTWARE_NAME="httpd"

SOFTWARE_FILENAME="${SOFTWARE_NAME}-${VERSION}.tar.gz"

 

5)变量定义总结:多学习模仿操作系统自带的/etc/init.d/functions函数库脚本的定义思路。

 

 

10.扩展赋值操作

 

 

 

 

三种定界符    注释
双引号""    允许扩展,通过$引用其他变量
单引号''    禁用扩展,即便$也视为普通字符
反撇号``    将命令的执行输出作为变量值  #执行命令本身的功能,$()与``等效,但$()更方便嵌套使用 

 

 

命令替换:

 $(COMMAND), 反引号:`COMMAND`

 

例子:把命令中某个子命令替换为其执行结果的过程

 

 

touch ./file-$(date +%F-%H-%M-%S).txt

  rootdata=`df -h | grep /dev/sda2 | awk '{print $4}' |  awk -F"G" '{print $1}'`

 

 写一个脚本,分别显示当前系统上所有默认shell为bash的用户和默认shell为/sbin/nologin的用户,并统计各类shell下的用户总数。显示结果形如:

BASH,3users,they are:
root,redhat,gentoo
NOLOGIN, 2users, they are:
bin,ftp

 

 

实现脚本:

#!/bin/bash
#
NUMBASH=`grep "bash$" /etc/passwd | wc -l`
BASHUSERS=`grep "bash$" /etc/passwd | cut -d: -f1`
BASHUSERS=`echo $BASHUSERS | sed 's@[[:space:]]@,@g'`

echo "BASH, $NUMBASH users, they are:"
echo "$BASHUSERS

 

 例子:

[root@Web ~]#ls
test.sh
[root@Web ~]#CMD=`ls`  
[root@Web ~]#echo $CMD
test.sh
[root@Web ~]#CMD1=$(pwd)
[root@Web ~]#echo $CMD1
/root

 

提示:

 

1、"CMD=`ls`"注意命令变量前后的字符``
2、在变量名前加$,可以取得此变量的值,使用echo命令可以显示变量的值,$A和${A}的写法不同,但功能是一样的,推荐使用后者的语法或"${A}"的用法。
3、${WEEK}day若变量和其他字符组成新的变量就必须给变量加上大括号。
4、养成将所有字符串变量用双引号括起来使用的习惯,将会减少很多编程时遇到的怪异的错误。具体使用方法如:"$A"或"${A}"的语法

 

 

 

生产环境常见应用:

 

 

1.对站点按天打包生成不同的文件名

 

 

[root@Web ~]# CMD=$(date +%F)
[root@Web ~]# echo $CMD
2015-04-12
[root@Web ~]# echo $(date +%F).tar.gz
2015-04-12.tar.gz
[root@Web ~]# H=$(uname -n)
[root@Web ~]# echo $H
Web
[root@Web ~]# tar zcf $H.tar.gz /etc/services 
tar: 从成员名中删除开头的“/”   #切换到目录下打包就不会出现这种情况
[root@Web ~]# ll Web.tar.gz 
-rw-r--r--. 1 root root 127319 4月  12 09:37 Web.tar.gz

 

 

 

 

11.变量的作用范围

 

局部变量

 

新定义的变量默认只在当前Shell环境中有效
无法在子Shell环境中使用

 

 定义本地变量

 

本地变量在用户当前的shell生存期的脚本中使用。例如,本地变量ZGY取值为ett098,这个值只在用户当前shell生存期中有意义。如果在shell中启动另一个进程或退出,本地变量ZGY值将无效。

 

 

全局变量

 

全局变量在当前Shell及子Shell环境中均有效
使用export可将局部变量声明为全局变量

 

 

export

 

 

 

                    注释
export 局部变量名[=变量值]    为局部变量添加全局属性
export -n 全局变量名      取消指定变量的全局属性

 

当变量被定义为全局变量后,变量能在当前的Shell和当前Shell的子Shell里使用。

 

站在用户登录的角度来说,SHELL的类型:

登录式shell:

 

正常通过某终端登录
su - USERNAME
su -l USERNAME

 

 

非登录式shell:

 

su USERNAME
图形终端下打开命令窗口
自动执行的shell脚本

 

 

 

bash的配置文件:

 

全局配置

 

/etc/profile
/etc/profile.d/*.sh
/etc/bashrc

 

个人配置

 

 

~/.bash_profile
~/.bashrc

 

 

profile类的文件:

 

设定环境变量
运行命令或脚本

 

 

bashrc类的文件:

 

设定本地变量
定义命令别名

 

登录式shell如何读取配置文件?

 

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile -->  ~/.bashrc --> /etc/bashrc

 

非登录式shell如何配置文件?

 

~/.bashrc --> /etc/basrc --> /etc/profile.d/*.sh

 

 

登录式shell,配置文件及次序:

 

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile -->  ~/.bashrc --> /etc/bashrc

 

非登录式shell

 

~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh

 

系统级配置文件对所有用户生效

 

/etc/profile
/etc/bashrc

 

用户级配置文件只针对用户生效(只针对某个用户生效。在这样的文件里配置可以执行脚本、定义变量、执行命令)

 

~/.bash_profile
~/.bashrc

 

图形模式  每打开一个新的终端时会调用哪些文件

 

/etc/bashrc 
~/.bashrc

 

posted @ 2018-04-24 21:31  钟桂耀  阅读(253)  评论(0编辑  收藏  举报