2015-08-03摘自鸟哥

什么是变量?

那么,什么是『变量』呢?简单的说,就是让某一个特定字符串代表不固定的内容就是了。举个大家在国中都会学到的数学例子,
那就是:『 y = ax + b 』这东西,在等号左边的(y)就是变量,在等号右边的(ax+b)就是变量内容。
要注意的是,左边是未知数,右边是已知数喔!
讲的更简单一点,我们可以『用一个简单的 "字眼"
来取代另一个比较复杂或者是容易变动的数据』。这有什么好处啊?最大的好处就是『方便!』。

最后我们就简单的对『什么是变量』作个简单定义好了: 『变量就是以一组文字或符号等,来取代一些配置或者是一串保留的数据!』, 例如:我配置了『myname』就是『VBird』,所以当你读取 myname 这个变量的时候,系统自然就会知道!哈!那就是 VBird 啦! 那么如何『显示变量』呢?这就需要使用到 echo 这个命令啦!

影响 bash 环境操作的变量

某些特定变量会影响到 bash 的环境喔!举例来说,我们前面已经提到过很多次的那个 PATH 变量! 你能不能在任何目录下运行某个命令,与 PATH 这个变量有很大的关系。例如你下达 ls 这个命令时,系统就是透过 PATH 这个变量里面的内容所记录的路径顺序来搜寻命令的呢!如果在搜寻完 PATH 变量内的路径还找不到 ls 这个命令时, 就会在屏幕上显示『 command not found 』的错误信息了。

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

  • 变量的取用: echo
[root@www ~]# echo $variable
[root@www ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@www ~]# echo ${PATH}

变量的取用就如同上面的范例,利用 echo 就能够读出,只是需要在变量名称前面加上 $ , 或者是以 ${变量} 的方式来取用都可以!当然啦,那个 echo 的功能可是很多的, 我们这里单纯是拿 echo 来读出变量的内容而已,更多的 echo 使用,请自行给他 man echo 吧! ^_^

例题:

请在屏幕上面显示出您的环境变量 HOME 与 MAIL:

答:

echo $HOME 或者是 echo ${HOME}
echo $MAIL 或者是 echo ${MAIL}

现在我们知道了变量与变量内容之间的相关性了,好了,那么我要如何『配置』或者是『修改』
某个变量的内容啊?很简单啦!用『等号(=)』连接变量与他的内容就好啦!举例来说:
我要将 myname 这个变量名称的内容配置为 VBird ,那么:

[root@www ~]# echo $myname
<==这里并没有任何数据~因为这个变量尚未被配置!是空的!
[root@www ~]# myname=VBird
[root@www ~]# echo $myname
VBird <==出现了!因为这个变量已经被配置了!

瞧!如此一来,这个变量名称 myname 的内容就带有 VBird 这个数据啰~ 而由上面的例子当中,我们也可以知道: 在 bash 当中,当一个变量名称尚未被配置时,默认的内容是『空』的。 另外,变量在配置时,还是需要符合某些规定的,否则会配置失败喔! 这些守则如下所示啊!

  • 变量的配置守则
    1. 变量与变量内容以一个等号『=』来连结,如下所示:

      『myname=VBird』
    2. 等号两边不能直接接空格符,如下所示为错误:

      『myname = VBird』或『myname=VBird Tsai』
    3. 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:

      『2myname=VBird』
    4. 变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但
      • 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
        『var="lang is $LANG"』则『echo $var』可得『lang is en_US』
      • 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
        『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』
    5. 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, \, 空格符,
      '等)变成一般字符;
    6. 在一串命令中,还需要藉由其他的命令提供的信息,可以使用反单引号『`命令`』或
      『$(命令)』。特别注意,那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号!
      例如想要取得核心版本的配置:
      『version=$(uname -r)』再『echo
      $version』可得『2.6.18-128.el5』
    7. 若该变量为扩增变量内容时,则可用 "$变量名称" 或 ${变量} 累加内容,如下所示:
      『PATH="$PATH":/home/bin』
    8. 若该变量需要在其他子程序运行,则需要以 export 来使变量变成环境变量:
      『export PATH』
    9. 通常大写字符为系统默认变量,自行配置变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ;
    10. 取消变量的方法为使用 unset :『unset
      变量名称』例如取消 myname 的配置:
      『unset myname』
    11. 什么是『子程序』呢?就是说,在我目前这个 shell 的情况下,去激活另一个新的 shell ,新的那个 shell 就是子程序啦!在一般的状态下,父程序的自定义变量是无法在子程序内使用的。但是透过 export 将变量变成环境变量后,就能够在子程序底下应用了!

环境变量的功能

环境变量=全局变量
自定义变量=局部变量

  1. 用 env 观察环境变量与常见环境变量说明(环境变量)
  2. 用 set 观察所有变量 (含环境变量与自定义变量)
    • [root@iZ288fgkcpkZ lianxi]# set
      BASH=/bin/bash
      ............................(略)
      SSH_TTY=/dev/pts/
      TERM=xterm
      UID=
      nange=zhaoyingnan主要是看这,我自己设置的也会显示
      [root@iZ288fgkcpkZ lianxi]#

      PS1:(提示字符的配置)

      这是 PS1 (数字的 1 不是英文字母),这个东西就是我们的『命令提示字符』喔!
      当我们每次按下 [Enter] 按键去运行某个命令后,最后要再次出现提示字符时,
      就会主动去读取这个变量值了。上头 PS1 内显示的是一些特殊符号,这些特殊符号可以显示不同的信息,
      每个 distributions 的 bash 默认的 PS1 变量内容可能有些许的差异,不要紧,『习惯你自己的习惯』就好了。
      你可以用 man bash (注3)去查询一下 PS1 的相关说明,以理解底下的一些符号意义。

        • \d :可显示出『星期 月 日』的日期格式,如:"Mon Feb 2"
        • \H :完整的主机名。举例来说,鸟哥的练习机为『www.vbird.tsai』
        • \h :仅取主机名在第一个小数点之前的名字,如鸟哥主机则为『www』后面省略
        • \t :显示时间,为 24 小时格式的『HH:MM:SS』
        • \T :显示时间,为 12 小时格式的『HH:MM:SS』
        • \A :显示时间,为 24 小时格式的『HH:MM』
        • \@ :显示时间,为 12 小时格式的『am/pm』样式
        • \u :目前使用者的账号名称,如『root』;
        • \v :BASH 的版本信息,如鸟哥的测试主板本为 3.2.25(1),仅取『3.2』显示
        • \w :完整的工作目录名称,由根目录写起的目录名称。但家目录会以 ~ 取代;
        • \W :利用 basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
        • \# :下达的第几个命令。
        • \$ :提示字符,如果是 root 时,提示字符为 # ,否则就是 $ 啰~

3. export: 自定义变量转成环境变量

  谈了 env 与 set 现在知道有所谓的环境变量与自定义变量,那么这两者之间有啥差异呢?其实这两者的差异在于『 该变量是否会被子程序所继续引用』啦!

[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan

[root@iZ288fgkcpkZ lianxi]# bash

[root@iZ288fgkcpkZ lianxi]# echo $nange

#在子程序里是空的哦

[root@iZ288fgkcpkZ lianxi]# exit
exit

[root@iZ288fgkcpkZ lianxi]# export nange这样就可以了

[root@iZ288fgkcpkZ lianxi]# bash

[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan

[root@iZ288fgkcpkZ lianxi]# exit

[root@iZ288fgkcpkZ lianxi]#

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

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

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

  • read

  要读取来自键盘输入的变量,就是用 read 这个命令了。

[root@www ~]# read [-pt] variable
选项与参数:
-p :后面可以接提示字符!
-t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦! 范例一:让用户由键盘输入一内容,将该内容变成名为 atest 的变量
[root@www ~]# read atest
This is a test <==此时光标会等待你输入!请输入左侧文字看看
[root@www ~]# echo $atest
This is a test <==你刚刚输入的数据已经变成一个变量内容! 范例二:提示使用者 30 秒内输入自己的大名,将该输入字符串作为名为 named 的变量内容
[root@www ~]# read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai <==注意看,会有提示字符喔!
[root@www ~]# echo $named
VBird Tsai <==输入的数据又变成一个变量的内容了! 

  

  • declare / typeset

  declare 或 typeset 是一样的功能,就是在『宣告变量的类型』。如果使用 declare 后面并没有接任何参数,那么 bash 就会主动的将所有的变量名称与内容通通叫出来,就好像使用 set 一样啦!

[root@www ~]# declare [-aixr] variable
选项与参数:
-a :将后面名为 variable 的变量定义成为数组 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset 范例一:让变量 sum 进行 100+300+50 的加总结果
[root@www ~]# sum=100+300+50
[root@www ~]# echo $sum
100+300+50 <==咦!怎么没有帮我计算加总?因为这是文字型态的变量属性啊!
[root@www ~]# declare -i sum=100+300+50
[root@www ~]# echo $sum
450 <==瞭乎??

  

由于在默认的情况底下, bash 对于变量有几个基本的定义:

  • 变量类型默认为『字符串』,所以若不指定变量类型,则 1+2 为一个『字符串』而不是『计算式』。 所以上述第一个运行的结果才会出现那个情况的;
  • bash 环境中的数值运算,默认最多仅能到达整数形态,所以 1/3 结果是 0
    范例二:将 sum 变成环境变量
    [root@www ~]# declare -x sum
    [root@www ~]# export | grep sum
    declare -ix sum="450" <==果然出现了!包括有 i 与 x 的宣告! 范例三:让 sum 变成只读属性,不可更动!
    [root@www ~]# declare -r sum
    [root@www ~]# sum=tesgting
    -bash: sum: readonly variable <==老天爷~不能改这个变量了! 范例四:让 sum 变成非环境变量的自定义变量吧!
    [root@www ~]# declare +x sum <== 将 - 变成 + 可以进行『取消』动作
    [root@www ~]# declare -p sum <== -p 可以单独列出变量的类型
    declare -ir sum="450" <== 看吧!只剩下 i, r 的类型,不具有 x 啰!
  • 变量的测试与内容替换

  在某些时刻我们常常需要『判断』某个变量是否存在,若变量存在则使用既有的配置,若变量不存在则给予一个常用的配置。

  

[root@iZ288fgkcpkZ lianxi]# echo $nange
zhaoyingnan
[root@iZ288fgkcpkZ lianxi]# unset nange;sName=${nange=wuchang}
[root@iZ288fgkcpkZ lianxi]# echo $nange
wuchang
[root@iZ288fgkcpkZ lianxi]# echo $wuchang [root@iZ288fgkcpkZ lianxi]# echo $sName
wuchang
[root@iZ288fgkcpkZ lianxi]#
变量配置方式 str 没有配置 str 为空字符串 str 已配置非为空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr} str=expr
var=expr
str 不变
var=
str 不变
var=$str
var=${str:=expr} str=expr
var=expr
str=expr
var=expr
str 不变
var=$str
var=${str?expr} expr 输出至 stderr var= var=$str
var=${str:?expr} expr 输出至 stderr expr 输出至 stderr var=$str

认识与学习 BASH的更多相关文章

  1. 第十一章、认识与学习BASH

    第十一章.认识与学习 BASH 最近升级日期:2009/08/25 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 ...

  2. 第十一章、认识与学习 BASH

    第十一章.认识与学习 BASH 1. 认识 BASH 这个 Shell 1.1 硬件.核心与 Shell 1.2 为何要学文字接口的 shell 1.3 系统的合法 shell 与 /etc/shel ...

  3. 鸟哥的Linux私房菜-第10/11/12/13章(vim程序编辑器、学习bash、正则表达式与文件格式化处理、学习Shell Scripts)

    第10章 vim程序编辑器 可以将vim看做vi的进阶版本,vim可以用颜色或底线等方式来显示出一些特殊的信息. 为何要学习vim?因为: a. 所有的 Unix Like 系统都会内建 vi 文书编 ...

  4. 认识与学习BASH①——鸟叔的Linux私房菜

    文章目录 认识与学习BASH① 认识BASH 壳程序 多种shells Bash shell 的功能 type :查询指令是否为Bash shell 的内置指令 指令的换行输入和快速删除 Shell的 ...

  5. 快速学习Bash

    作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. Shell是Linux下经典的文本互动方式,而Bash是现在最常用的一种Shell.我在这里总结了Bash ...

  6. Linux学习笔记之认识与学习Bash

    什么是shell:shell是一个翻译器,将所敲的命令翻译成CPU能理解的语言,之后CPU再去执行,CPU执行后返回给shell,shell再翻译成我们所能理解的语言并显示:终端并不是shell,而是 ...

  7. 认识和学习BASH alias 给长命令起别名 unalias 取消该别名

    此图反映了shell所在的位置与作用. 既然Shell与KDE和application等都是用户与Kernel的接口,那为什么还要学习呢?书中也给出了答案. 通用性,可以这样理解,也就是所谓的跨平台机 ...

  8. 【CentOS】学习Bash

    一.特性 命令历史  history , !! , !$ , !字符 , !n (n为第几条命令) Tab可以补全文件路径或者命令 alias a="b",  unalias a ...

  9. 学习bash

    工作8年,前6年基本是Windows环境下,也就是个鼠标党:两年前换工作开始用linux,也就开始了领略了命令行的强大,无论是直接在命令行组合命令,也还写几行简单的shell脚本,其能完成的功能往往令 ...

随机推荐

  1. {"集合已修改;可能无法执行枚举操作。"}

    无论是向集合中添加元素还是从集合中删除元素,都会导致集合内部的变化,特别是集合遍历器的变化.例如 List<,,,,}; foreach(int x in list) { list.Remove ...

  2. Oracle基础 各种语句的定义格式

    Oracle内建数据类型 一. 字符数据 1. char(size) 2. varchar2(size) 最常用,最大长度4000字节 3. nvhar(size).nvarchar(size) 4. ...

  3. csharp: Flash Player play *.flv file in winform

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. android dp

    http://www.see-say.com/viewnews-47657.html http://cn.club.vmall.com/thread-970026-1-1.html http://ww ...

  5. python函数和常用模块(一),Day3

    set集合 函数 三元运算 lambda表达式 内置函数1 文件操作 set集合 创建 se = {"123", "456"} # 直接创建一个集合 se = ...

  6. 微软Asp.net MVC5生命周期流程图

           .NET WEB Development blog 发布了Asp.net MVC5生命周期文档, 这个文档类似Asp.net应用程序生命周期,您以前开发ASP.NET WEB应用程序应该 ...

  7. ASP.NET WebAPI 12 Action的执行

    Action的激活大概可以分为如下两个步骤:Action对应方法的调用,执行结果的协商.在WebAPI中由HttpActionInvoker(System.Web.Http.Controllers)进 ...

  8. mysql并发insert deadlock分析以及解决,无delete/update/for update

    关于并发insert操作发生deadlock这个情况,一直有很多争议,而且网上的帖子所有的例证和模拟其实不一定反映了真实的情况,例如:https://www.percona.com/blog/2012 ...

  9. winform里面网页显示指定内容

    今天有个同事问了一下我,怎么在winform里面打开网页啊?我们都是基于C/S的开发,很少接触winform,所以我当时就懵了,实在不知道怎么回答,所以索性说不知道.但是我又想了想,这个应该是个很简单 ...

  10. android studio :com.android.support:appcompat-v7:21.+ 报错

    android studio :com.android.support:appcompat-v7:21.+ 报错: 在project——>app——>build.gradle修改: app ...