The Bash Shell 变量(初级)

The Bash Shell 变量(初级)

@(Share)[shell]

[TOC]

###前言
我有一个想法,希望通过学习脚本来实现blog的自动创建及发布等操作,
zm推荐shell,pj建议js

常见bash熟悉的特性:

1
2
3
4
5
6
7
8
9
10
11
12
#$:(关于本 shell 的 PID)
#钱字号本身也是个变量喔!这个咚咚代表的是『目前这个 Shell 的线程代号』,亦即是所谓的 PID (Process ID)。 更多的程序观念,我们会在第四篇的时候提及。想要知道我们的 shell 的 PID ,就可以用:『 echo $$ 』即可!出现的数字就是你的 PID 号码。
XcodeYangdeMBP2:~ xcodeyang$ echo $$
10337
#?:(关于上个运行命令的回传值)
#问号也是一个特殊的变量?在 bash 里面这个变量可重要的很! 这个变量是:『上一个运行的命令所回传的值』, 上面这句话的重点是『上一个命令』与『回传值』两个地方。当我们运行某些命令时, 这些命令都会回传一个运行后的代码。一般来说,如果成功的运行该命令, 则会回传一个 0 值,如果运行过程发生错误,就会回传『错误代码』才对!一般就是以非为 0 的数值来取代。
XcodeYangdeMBP2:~ xcodeyang$ echo$
-bash: echo$: command not found
XcodeYangdeMBP2:~ xcodeyang$ echo $?
127 # <== error
XcodeYangdeMBP2:~ xcodeyang$ echo $?
0 # <== success
  • 命令编修能力 (history):
1
2
XcodeYangdeMBP2:~ xcodeyang$ echo $HISTSIZE
500
  • 命令与文件补全功能:

    [tab] 按键的好处

    • 一下和两下的区别
    • 命令与文件路径
1
2
3
4
5
6
7
8
XcodeYangdeMBP2:~ xcodeyang$ x
xar xcodebuild xgettext5.18.pl xmllint xslt-config
xargs xcodeproj xip xpath xsltproc
xattr xcrun xjc xpath5.16 xsubpp
xattr-2.6 xed xml2-config xpath5.18 xsubpp5.16
xattr-2.7 xgettext.pl xml2man xsanctl xsubpp5.18
xcode-select xgettext5.16.pl xmlcatalog xscertadmin xxd
XcodeYangdeMBP2:~ xcodeyang$ x
  • 命令别名配置功能: (alias)
1
2
3
4
5
6
7
XcodeYangdeMBP2:~ xcodeyang$ alias xcodedaniel='ls'
XcodeYangdeMBP2:~ xcodeyang$ cd Documents/
XcodeYangdeMBP2:Documents xcodeyang$ xcodedaniel
GItHub Welcome.itmz bloodsugar 技术部分享
XcodeYangdeMBP2:Documents xcodeyang$ ls
GItHub Welcome.itmz bloodsugar 技术部分享
XcodeYangdeMBP2:Documents xcodeyang$

可变性与方便性

举例:MAIL 变量不同用户设置
yzp -> /var/spool/mail/yzp
cy -> /var/spool/mail/cy
pj -> /var/spool/mail/pj
zm -> /var/spool/mail/zm

1
2
XcodeYangdeMBP2:~ xcodeyang$ echo $USER
xcodeyang

###变量的取用与配置:echo, 变量配置守则, unset

变量的取用就如同上面的范例,利用 echo 就能够读出,只是需要在变量名称前面加上 $ , 或者是以 ${变量} 的方式来取用都可以

####变量的配置守则

  • 变量与变量内容以一个等号『=』来连结,如下所示:

    『yname=zhipingyang』

  • 等号两边不能直接接空格符,如下所示为错误:

    『myname = zhipingyang』或『myname=zhiping yang』

  • 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:

    『2myname=zhipingyang』

  • 变量内容若有空格符可使用双引号『”』或单引号『’』将变量内容结合起来,但
    双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:

    『var=”lang is $LANG”』则『echo $var』可得『lang is en_US』

  • 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:

    『var=’lang is $LANG’』则『echo $var』可得『lang is $LANG』

  • 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, \, 空格符, ‘等)变成一般字符;

    XcodeYangdeMBP2:~ xcodeyang$ myname=hello\ world

  • 在一串命令中,还需要藉由其他的命令提供的信息,可以使用反单引号『命令』或 『$(命令)』。特别注意,那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号! 例如想要取得核心版本的配置:

    『version=$(uname -r)』再『echo $version』可得『2.6.18-128.el5』

  • 若该变量为扩增变量内容时,则可用 “$变量名称” 或 ${变量} 累加内容,如下所示:

    『PATH=”$PATH”:/home/bin』

  • 若该变量需要在其他子程序运行,则需要以 export 来使变量变成环境变量:

    『export PATH』

  • 取消变量的方法为使用 unset :『unset 变量名称』例如取消 myname 的配置:

    『unset myname』

设置myname变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 例子一
XcodeYangdeMBP2:~ xcodeyang$ echo $myname
# <==这里并没有任何数据~因为这个变量尚未被配置!是空的!
XcodeYangdeMBP2:~ xcodeyang$ myname = Daniel
-bash: myname: command not found
XcodeYangdeMBP2:~ xcodeyang$ myname=Daniel
XcodeYangdeMBP2:~ xcodeyang$ echo $myname
Daniel
XcodeYangdeMBP2:~ xcodeyang$ bash
bash-3.2$ echo $myname
# <==这里并没有任何数据~因为这个变量是自定义变量(局部变量)
bash-3.2$ exit
exit
XcodeYangdeMBP2:~ xcodeyang$ export myname #修改成环境变量(全局变量)
XcodeYangdeMBP2:~ xcodeyang$ bash
bash-3.2$ echo $myname
Daniel
bash-3.2$ unset myname
bash-3.2$ echo $myname
bash-3.2$ exit
exit
XcodeYangdeMBP2:~ xcodeyang$ echo $myname
Daniel
XcodeYangdeMBP2:~ xcodeyang$
# 例子二
XcodeYangdeMBP2:~ xcodeyang$ echo $HOME
/Users/xcodeyang
XcodeYangdeMBP2:~ xcodeyang$ HOME=$HOME/home/bin
XcodeYangdeMBP2:xcodeyang xcodeyang$ echo $HOME
/Users/xcodeyang/home/bin
# myname=$mynameyes
# 如果没有双引号,name 的内容是 $nameyes 这个变量!
# tip:配错使用control+c取消继续,下面是正确的
# myname="$myname"yes
# myname=${myname}yes <==以此例较佳!
# 猜测一下,那个是对/错
myname="myname's name"
myname='myname's name'
myname=myname\'s\ name
1
2
3
4
5
6
7
8
9
XcodeYangdeMBP2:~ xcodeyang$ echo $name
yzp
XcodeYangdeMBP2:~ xcodeyang$ name="$name is daniel"
XcodeYangdeMBP2:~ xcodeyang$ echo $name
yzp is daniel
XcodeYangdeMBP2:~ xcodeyang$ name='$name is daniel'
XcodeYangdeMBP2:~ xcodeyang$ echo $name
$name is daniel
XcodeYangdeMBP2:~ xcodeyang$

环境变量的功能: env 与常见环境变量说明, set, export

bash 可不只有环境变量喔,还有一些与 bash 操作接口有关的变量,以及用户自己定义的变量存在的. set 除了环境变量之外, 还会将其他在 bash 内的变量通通显示出来哩!信息太多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
XcodeYangdeMBP2:~ xcodeyang$ newname=daniel
XcodeYangdeMBP2:~ xcodeyang$ name=xcodeyang
XcodeYangdeMBP2:~ xcodeyang$ export name
XcodeYangdeMBP2:~ xcodeyang$ env #<==看这里
TERM_PROGRAM=Apple_Terminal #使用{大写的字母}来配置的变量一般为系统内定需要的变量
SHELL=/bin/bash
TERM=xterm-256color
TMPDIR=/var/folders/1c/hw10tv792_92fz5cswgmzqmc0000gn/T/
Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.Zcy3n3bgYL/Render
TERM_PROGRAM_VERSION=361.1
TERM_SESSION_ID=A7EE49FA-7C48-49A4-BA91-8144FACFB146
name=xcodeyang #<==看这里
USER=xcodeyang
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.Sey2Soe8fS/Listeners
__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0
PATH=/Users/xcodeyang/.rbenv/shims:/Users/xcodeyang/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin
PWD=/Users/xcodeyang
XPC_FLAGS=0x0
RBENV_SHELL=bash
XPC_SERVICE_NAME=0
SHLVL=1
HOME=/Users/xcodeyang
LOGNAME=xcodeyang
LC_CTYPE=UTF-8
_=/usr/bin/env
XcodeYangdeMBP2:~ xcodeyang$

###变量的有效范围
环境变量=全局变量
自定义变量=局部变量

为什么环境变量的数据可以被子程序所引用呢?这是因为内存配置的关系!理论上是这样的:

  • 当启动一个 shell,操作系统会分配一记忆区块给 shell 使用,此内存内之变量可让子程序取用
  • 若在父程序利用 export 功能,可以让自定义变量的内容写到上述的记忆区块当中(环境变量);
  • 当加载另一个 shell 时 (亦即启动子程序,而离开原本的父程序了),子 shell 可以将父 shell 的环境变量所在的记忆区块导入自己的环境变量区块当中。

###变量键盘读取、数组与宣告: read, declare, array

我们上面提到的变量配置功能,都是由命令列直接配置的,那么,可不可以让用户能够经由键盘输入? 什么意思呢?是否记得某些程序运行的过程当中,会等待使用者输入 “yes/no” 之类的信息啊?

####read

1
2
3
4
5
6
7
8
9
10
11
12
13
14
XcodeYangdeMBP2:~ xcodeyang$ echo $name
zhipingyang
XcodeYangdeMBP2:~ xcodeyang$ read name
%^$$uhda asuh_uha!@#~ #关键是没有之前那样的语法格式限制
XcodeYangdeMBP2:~ xcodeyang$ echo $name
%^$$uhda asuh_uha!@#~
XcodeYangdeMBP2:~ xcodeyang$
#-p :后面可以接提示字符!
#-t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!
XcodeYangdeMBP2:~ xcodeyang$ read -p "Please keyin your age: " -t 30 agenum
Please keyin your age: 33
XcodeYangdeMBP2:~ xcodeyang$ echo $agenum
33
XcodeYangdeMBP2:~ xcodeyang$

declare / typeset

declare 或 typeset 是一样的功能,就是在『宣告变量的类型』

-a :将后面名为 variable 的变量定义成为数组 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#示例1:
XcodeYangdeMBP2:~ xcodeyang$ sum=10+20+30
XcodeYangdeMBP2:~ xcodeyang$ echo $sum
10+20+30 #<==默认类型是string
XcodeYangdeMBP2:~ xcodeyang$ declare -i sum=10+20+30
XcodeYangdeMBP2:~ xcodeyang$ echo $sum
60
XcodeYangdeMBP2:~ xcodeyang$ declare -i sum=1/3
XcodeYangdeMBP2:~ xcodeyang$ echo $sum
0 # <==bash 环境中的数值运算,默认最多仅能到达整数形态
XcodeYangdeMBP2:~ xcodeyang$
#示例2
XcodeYangdeMBP2:~ xcodeyang$ declare -ixr sum=20+30 #只读整型环境变量
XcodeYangdeMBP2:~ xcodeyang$ bash
bash-3.2$ echo $sum
50 #子程序里依然可以访问
bash-3.2$ exit
exit
XcodeYangdeMBP2:~ xcodeyang$ sum=30
-bash: sum: readonly variable #不可修改
XcodeYangdeMBP2:~ xcodeyang$
#示例3: 建议直接以 ${数组} 的方式来读取
XcodeYangdeMBP2:~ xcodeyang$ var[1]=$SHELL
XcodeYangdeMBP2:~ xcodeyang$ var[2]=$sum
XcodeYangdeMBP2:~ xcodeyang$ var[3]="helloworld"
XcodeYangdeMBP2:~ xcodeyang$ echo "${var[1]}, ${var[2]}, ${var[3]}"
/bin/bash, 50, helloworld
XcodeYangdeMBP2:~ xcodeyang$