shell--变量

 

1.什么是shell变量

  • 变量是暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中。通过正确的调用内存空间中变量的名字就可以取出变量对应的数据,使用变量可以使程序开发更加的简单。
  • shell中的变量是不区分类型的这一点不同于其他的编程语言,shell不支持浮点型,只支持整型和字符型。默认情况下为字符型
  • 变量类型分为环境变量和普通变量

2. 变量定义方法

普通变量只会在当前Shell使用的情况下使用,如果启动另一个shell环境则该变量无效

2.1 直接赋值

2.1.1 普通的定义方法=表示赋值==表示等于

变量名=value    #普通的定义方法,当内容为简单连续的数字时可以使用
变量名='value' #输出变量内容时单引号里面写什么,就会输出什么
变量名="value"  #输出变量会对双引号中的变量进行解析

2.1.2 把一个命令的结果作为变量

变量名=`date`  #把命令用反引号引用    
变量名=$()       #吧命令用$()括起来

2.1.3 打印变量的方法,变量名前接$符号,变量名接字符的时候要用大括号括起来

[root@test ~]# hello=hi
[root@test ~]# echo ${hello}Boy
hiBoy
[root@test ~]# echo $helloBoy
  • 变量名只能由字母、数字、下划线组成。并且以字母开头
  • 变量名避免和系统存在的变量和命令重复

2.2  传参(传递参数借助位置参数)

传参请参见4.1位置变量

2.3  交互式设置变量(可以使用read命令)

#read命令的几个参数
read   
    -p :添加提示语句
    -t  :设置超时时间
    -s  : 关闭回显

参考脚本:

#!/bin/bash
read -t 5 -p "请输入你的姓名" name if [ $? -ne 0 ]; then exit 1 fi read -t 5 -s -p "请输入你的密码" password if [ $? -ne 0 ]; then exit 1 fi echo "你的姓名是:$name 你的密码为:$password"

3.环境变量

  • 环境变量一般指用export内置命令导出的变量,用于shell的使用环境,可以用来确定登陆用户名、命令路径终端类型....
  • 环境变量可以在命令行中设置和创建
  • 根据系统规范,所有环境变量的名字均采用大写格式
  • 部分环境变量不仅在shell编程方面使用,并且用在linux系统管理方面

3.1定义和清除环境变量

#定义环境变量
【声明变量名】=【变量的值】  #变量赋值
export 【变量名】              #声明环境变量
export 【声明变量名】=【变量的值】 #合并书写格式
#例
[root@test ~]# word=hello
[root@test ~]# export word
[root@test ~]# echo $word
hello

查看系统中环境变量可使用env命令

[root@test ~]# env
XDG_SESSION_ID=59
HOSTNAME=test
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.0.1 4889 22
SSH_TTY=/dev/pts/0
word=hello
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=zh_CN.utf8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=10.0.0.1 4889 10.0.0.168 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

清楚变量和清楚其他变量的方法一样unset命令

[root@test ~]# echo $word
hello
[root@test ~]# unset word
[root@test ~]# echo $word

3.2几个重要的环境变量

3.2.1 PWD和OLDPWD

PWD环境变量用来存储路径信息OLDPWD存储旧的工作目录,当使用cd命令时,系统会更新PWD值并将当前PWD值给OLDPWD

[root@test ~]# echo $PWD
/root
[root@test ~]# cd /
[root@test /]# echo $PWD
/
[root@test /]# echo $OLDPWD
/root

3.2.2 PATH

PATH是linux中非常重要的环境变量,它用于帮助shell找到命令所在地

[root@test /]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

3.2.3 HOME

记录当前用户的家目录,由/etc/passwd文件决定,如下图的add用户

#显示HOME变量
[root@test /]# echo $HOME
/root
[root@test /]# su - add
[add@test ~]$ echo $HOME
/home/add

3.2.4 SHELL

 保存默认的SHELL值,表示当前使用那个Shell如果有必要使用另一个Shell则需要重置SHELL变量

#显示SHELL变量
[add@test ~]$ echo $SHELL
/bin/bash

3.2.5 USER和UID

保存用户信息的环境变量,USER表示已登录用户的名字。UID表示已登录用户的ID由/etc/passwd文件决定

#打印USER和UID变量
[root@test /]# echo $USER $UID
root 0
[root@test /]# su - add
[add@test ~]$ echo $USER $UID
add 1000

3.2.6 PPID

PPID是创建当前进程的进程号,即当前进程的父进程号

3.2.7 PS1和PS2

PS1和PS2称为提示符变量,用于设置提示符格式

[add@test ~]$ echo $PS1
[u@h W]$
[add@test ~]$ echo $PS2
>

如果想要设置为喜欢的格式请参加下表:

3.2.8 IFS

IFS用于指定Shell域分隔符,默认为空格

3.3 几个环境变量配置文件

全局生效:/etc/profile  /etc/nashrc

只对某一用户生效: $HOME/.bash_profile $HOME/.bashrc

特殊目录:/etc/profile.d

在用户注销后执行:$HOME/.bash_logout

4.特殊变量

4.1位置变量

4.1.1 $n变量中的n表示数字

#加入$1测试
[root@test scripts]# cat test.sh 
#!/bin/bash
echo $1
[root@test scripts]# sh test.sh hello
hello
[root@test scripts]# sh test.sh hello word
hello
#加入$1和$2测试
[root@test scripts]# cat test.sh 
#!/bin/bash
echo $1
echo $2
[root@test scripts]# sh test.sh hello
hello

[root@test scripts]# sh test.sh hello word
hello
word
#测试$加数字的范围,可以看到$后面接的数字只能到9超过后会出错
[root@test scripts]# cat test.sh 
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@test scripts]# sh test.sh {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5
#在超过9的数字用{}括起来可以解决问题
[root@test scripts]# cat test.sh 
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@test scripts]# sh test.sh {a..z}
a b c d e f g h i j k l m n o

4.1.2 $0表示本脚本的路径

[root@test shell]# cat test.sh
#!/bin/bash
echo $0
[root@test shell]# sh test.sh 
test.txt
[root@test shell]# cd /
[root@test /]# sh /shell/test.txt 
/shell/test.txt
##可以看到使用全路径执行脚本的话显示的结果也是全路径

参考系统的/etc/init.d/network中$0的用法

可以执行该脚本测试:

[root@test /]# sh /etc/init.d/network
用法:/etc/init.d/network {start|stop|status|restart|reload|force-reload}

可以看到$0提示的信息是绿色的字体位置

4.1.3 $#表示传递参数的数量

#传递参数的数量
[root@test shell]# cat test.sh #
!/bin/bash echo $1 $2 $3 $3 $5 echo $# [root@test shell]# sh test.sh {a..z} a b c c e 26

例:根据传入参数的个数判断,若为两个则原样输出,否则提示

方法一:

[root@test shell]# cat test1.sh 
#!/bin/bash
[ $# -ne 2 ] && {    #&&条件达成时候执行&&之后
echo '不为两个参数'   #显示信息
exit 1               #不满足条件后也就是返回值为1时候退出脚本
}
echo $1 $2
[root@test shell]# sh test1.sh hello 
不为两个参数
[root@test shell]# sh test1.sh hello word
hello word

方法二:

[root@test shell]# cat test2.sh 
#!/bin/bash
if [ $# -ne 2 ]; then
   echo "$0需要两个值"
   exit 1
fi
echo $1 $2
[root@test shell]# sh test2.sh hello
test2.sh需要两个值
[root@test shell]# sh test2.sh hello word
hello word

4.1.4 $*和$@特殊变量功能及区别

 $*表示所有的位置参数,被作为一个单词。注意:$*必须被引用

$@

与$*同义,但是每个参数都是一个独立的引用字符串,每个参数都是一个独立的存在

注:

要实现差异必须使用"双引号"包含起来感谢网友@拿节电池

参考博客:http://blog.csdn.net/zhejiang9/article/details/7887569

来自@鸟哥的解释:

$*:代表【"$1c$2c$3c$4"】其中c为分隔字元。预设为空白键

$@代表【“$1” “$2” “$3” “$4”】之意,每个变量是独立的

[root@test shell]# set -- "I AM" very good
[root@test shell]# echo $*
I AM very good
[root@test shell]# echo $@
I AM very good
[root@test shell]# for i in $*;do echo $i ;done
I
AM
very
good
[root@test shell]# for i in $@;do echo $i ;done
I
AM
very
good
[root@test shell]# for i in "$*";do echo $i ;done
I AM very good
[root@test shell]# for i in "$@";do echo $i ;done
I AM
very
good

4.2 进程变量

4.2.1 $?获取上一个指令的执行状态的返回值0为成功,非0为失败

#获取返回值
[root@test ShellScripts]# cat test.sh #
!/bin/bash echo hello word echo $? [root@test ShellScripts]# sh test.sh hello word 0

4.2.2 $$ 获取当前执行shell脚本的进程号码

[root@test ShellScripts]# cat test.sh
#!/bin/bash
echo hello word 
echo $$
[root@test ShellScripts]# sh test.sh
hello word
2582

4.2.3 $! 获取上一个在后台工作的进程的进程号

[root@test ShellScripts]# cat test.sh 
#!/bin/bash
echo hello word 
echo $$
[root@test ShellScripts]# sh test.sh &
[1] 2634
[root@test ShellScripts]# hello word
2634

[1]+  完成                  sh test.sh
[root@test ShellScripts]# echo $!
2634

4.2.4 $_ 获得上一条命令的最后一个参数

[root@test ShellScripts]# cat test1.sh 
#!/bin/bash
[ $# -ne 2 ] && {
echo '不足两个参数' 
exit 1
}
echo $1 $2
echo $*
echo $@
[root@test ShellScripts]# sh test1.sh hello word
hello word
hello word
hello word
[root@test ShellScripts]# echo $_
word

小结:

[root@test ShellScripts]# cat  AllValues.sh 
#!/bin/bash
echo "--------------"
  echo "这个文件是 :$0"
  echo "第1个值: $1"
  echo "第2个值: $2"
  echo "第3个值: $3"
  echo "第4个值: $4"
  echo "第5个值: $5"
  echo "第6个值: $6"
  echo "第7个值: $7"
  echo "第8个值: $8"
  echo "第9个值: $9"
  echo "第10个值: ${10}"
  echo "上一个字符为: $_"
echo "---------------"
for i in "$*" 
      do echo "$i"
  done
echo "--------------"
for l in "$@" 
      do echo "$l"
  done
echo "--------------"
  echo "全部传参数为 :$#"
  echo "该脚本的pid: $$"
  echo "他的返回值: $?"
  echo "上一个进程的pid: $!"
[root@test ShellScripts]# sh AllValues.sh "nginx httpd tomcat" nfs rsync ansible zabbix php mysql jdk  memcache keepalived 
--------------
这个文件是 :AllValues.sh
第1个值: nginx httpd tomcat
第2个值: nfs
第3个值: rsync
第4个值: ansible
第5个值: zabbix
第6个值: php
第7个值: mysql
第8个值: jdk
第9个值: memcache
第10个值: keepalived
上一个字符为: 第10个值: keepalived
---------------
nginx httpd tomcat nfs rsync ansible zabbix php mysql jdk memcache keepalived
--------------
nginx httpd tomcat
nfs
rsync
ansible
zabbix
php
mysql
jdk
memcache
keepalived
--------------
全部传参数为 :10
该脚本的pid: 2727
他的返回值: 0
上一个进程的pid: 
原文地址:https://www.cnblogs.com/ExzaiTin/p/7965474.html