您的位置:首页 > 运维架构 > Shell

【鸟哥的linux私房菜-学习笔记】Bash shell的变量功能及操作环境

2015-10-30 17:32 549 查看

shell

只要能够操作应用程序的接口都能够称为shell

用户->shell->核心->硬件

查看系统下有哪些可用的shell:/etc/shells

(linux下常用的是bash)

用户登陆时,系统会默认给一个shell,配置信息记录在 /etc/passwd 这个文件内。

bash shell的功能

history

用户曾经下达过的命令几乎都会被记录下来。记录档案在家目录内的 .bash_history 中! 不过,需要留意的是,~/.bash_history 记录的是前一次登陆以前所运行过的命令, 而至于这一次登陆所运行的命令都被缓存在内存中,当你成功的注销系统后,该命令记忆才会记录到 .bash_history 当中。

这样子,一来方便我们重复之前的指令,二来帮助我们查询曾经的举动,便于除错,不过也有可能会被黑客所利用!

命令与文件补齐功能([tab])

[Tab] 接在一串命令的第一个字的后面,则为命令补全;
[Tab] 接在一串命令的第二个字以后时,则为文件补齐。


好处: 1)少打很多字; 2)确定输入的数据是正确的

命令别名配置功能(alias)

例子:alias lm=’ls -al’ 则之后只需要下达命令lm即可进行ls -al操作。

工作控制、前景背景控制: (job control, foreground, background)

可达到多任务的目的。

程序化脚本: (shell scripts)

可以将你平时管理系统常需要下达的连续命令写成一个文件, 该文件并且可以透过对谈交互式的方式来进行主机的侦测工作!也可以藉由 shell 提供的环境变量及相关命令来进行设计。

通配符

举例来说,想要知道 /usr/bin 底下有多少以 X 为开头的文件吗?使用:『 ls -l /usr/bin/X* 』就能够知道了。

辨别是否Bash shell 的内建命令: type

shell的变量功能

变量的可变性与方便性

举例来说,我们每个账号的邮件信箱默认是以 MAIL 这个变量来进行存取的, 当 dmtsai 这个使用者登陆时,他便会取得 MAIL 这个变量,而这个变量的内容其实就是 /var/spool/mail/dmtsai, 那如果 vbird 登陆呢?他取得的 MAIL 这个变量的内容其实就是 /var/spool/mail/vbird 。

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

变量的取用: echo

变量在被取用时,前面必须要加上『 $ 』才行

例子: echo $HOME 或者 echo ${HOME}

变量的配置守则

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

『myname=VBird』

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

『myname = VBird』或『myname=VBird Tsai』

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

『2myname=VBird』

变量内容若有空格符可使用双引号『”』或单引号『’』将变量内容结合起来,但

双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:

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

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

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

** 单引号与双引号的最大不同在于双引号仍然可以保有变量的内容,但单引号内仅能是一般字符 ,而不会有特殊符号。

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

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

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

**在一串命令中,在 ` 之内的命令将会被先运行,而其运行出来的结果将做为外部的输入信息。

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

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

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

『export PATH』

通常大写字符为系统默认变量,自行配置变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ;

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

『unset myname』

**一般的状态下,父程序的自定义变量是无法在子程序内使用的。但是透过 export 将变量变成环境变量后,就能够在子程序底下应用了

环境变量的功能

env:观察环境变量 (environment)

主要环境变量的功能:

HOME

代表用户的家目录。还记得我们可以使用 cd ~ 去到自己的家目录吗?或者利用 cd 就可以直接回到用户家目录了。那就是取用这个变量啦~ 有很多程序都可能会取用到这个变量的值!

SHELL

告知我们,目前这个环境使用的 SHELL 是哪支程序? Linux 默认使用 /bin/bash。

HISTSIZE

这个与『历史命令』有关,亦即是, 我们曾经下达过的命令可以被系统记录下来,而记录的『笔数』则是由这个值来配置的。

MAIL

当我们使用 mail 这个命令在收信时,系统会去读取的邮件信箱文件 (mailbox)。

PATH

就是运行文件搜寻的路径啦~目录与目录中间以冒号(:)分隔, 由于文件的搜寻是依序由 PATH 的变量内的目录来查询,所以,目录的顺序也是重要的。

LANG

这是语系数据~很多信息都会用到他, 举例来说,当我们在启动某些 perl 的程序语言文件时,他会主动的去分析语系数据文件, 如果发现有他无法解析的编码语系,可能会产生错误喔!一般来说,我们中文编码通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,这两个编码偏偏不容易被解译出来,所以,有的时候,可能需要修订一下语系数据。

RANDOM

这个玩意儿就是『随机随机数』的变量。

set:观察所有变量 (含环境变量与自定义变量)

几个重要的:

PS1:(提示字符的配置)

如可将默认的 [root@www ~]# 可修改为[root@www /home/dmtsai 16:50 #12]#

$:(关于本 shell 的 PID)

想要知道我们的 shell 的 PID ,就可以用:『 echo $$ 』即可

?:(关于上个运行命令的回传值)

当我们运行某些命令时, 这些命令都会回传一个运行后的代码。一般来说,如果成功的运行该命令, 则会回传一个 0 值,如果运行过程发生错误,就会回传『错误代码』才对

OSTYPE, HOSTTYPE, MACHTYPE:(主机硬件与核心的等级)

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

环境变量与自定义变量的差异在于『 该变量是否会被子程序所继续引用』

子程序仅会继承父程序的环境变量, 不会继承父程序的自定义变量。

export 变量:分享自己的变量配置给后来呼叫的文件或其他程序

影响显示结果的语系变量 (locale)

变量的有效范围

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

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


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

read

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

declare / typeset

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

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

变量类型默认为『字符串』,所以若不指定变量类型,则 1+2 为一个『字符串』而不是『计算式』。
bash 环境中的数值运算,默认最多仅能到达整数形态,所以 1/3 结果是 0;


数组 (array) 变量类型

在 bash 里头,数组的配置方式是:

var[index]=content


一般来说,建议直接以 ${数组} 的方式来读取

与文件系统及程序的限制关系: ulimit

我们的 bash 是可以『限制用户的某些系统资源』的,包括可以开启的文件数量, 可以使用的 CPU 时间,可以使用的内存总量等等。

**想要复原 ulimit 的配置最简单的方法就是注销再登陆,否则就是得要重新以 ulimit 配置才行! 不过,要注意的是,一般身份使用者如果以 ulimit 配置了 -f 的文件大小, 那么他『只能继续减小文件容量,不能添加文件容量!』

变量内容的删除、取代与替换

变量内容的删除与取代

变量配置方式说明
${变量#关键词}若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除
${变量##关键词}若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除
${变量%关键词}若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除
${变量%%关键词}若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除
${变量/旧字符串/新字符串}若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』
${变量//旧字符串/新字符串}若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』

变量的测试与内容替换

变量配置方式str 没有配置str 为空字符串str 已配置非为空字符串
var=${str-expr}var=exprvar=var=$str
var=${str:-expr}var=exprvar=exprvar=$str
var=${str+expr}var=var=exprvar=expr
var=${str:+expr}var=var=var=expr
var=${str=expr}str=expr var=exprstr 不变 var=str 不变 var=$str
var=${str:=expr}str=expr var=exprstr=expr var=exprstr 不变 var=$str
var=${str?expr}expr 输出至 stderrvar=var=$str
var=${str:?expr}expr 输出至 stderrexpr 输出至 stderrvar=$str

命令别名与历史命令

命令别名配置: alias, unalias

历史命令:history

如果我想要运行上一个命令, 除了使用上下键之外,我可以直接以『 !! 』 来下达上个命令的内容,此外, 我也可以直接选择下达第 n 个命令,『 !n 』来运行,也可以使用命令标头,例如 『 !vi 』来运行最近命令开头是 vi 的命令列!

同一账号同时多次登陆的 history 写入问题

当同一账户同时登录多个bash接口时,最后注销的那个 bash 才会是最后写入的数据。其他 bash 的命令操作就不会被记录下来了 (其实有被记录,只是被后来的最后一个 bash 所覆盖升级了) 。

无法记录时间

历史命令还有一个问题,那就是无法记录命令下达的时间。由于这 1000 笔历史命令是依序记录的, 但是并没有记录时间,所以在查询方面会有一些不方便。(其实可以透过 ~/.bash_logout 来进行 history 的记录,并加上 date 来添加时间参数)

bash 的进站与欢迎信息: /etc/issue, /etc/motd

issue 内的各代码意义:

\d 本地端时间的日期;

\l 显示第几个终端机接口;

\m 显示硬件的等级 (i386/i486/i586/i686…);

\n 显示主机的网络名称;

\o 显示 domain name;

\r 操作系统的版本 (相当于 uname -r)

\t 显示本地端时间的时间;

\s 操作系统的名称;

\v 操作系统的版本。

除了 /etc/issue 之外还有个 /etc/issue.net,它是提供给 telnet 这个远程登录程序用的。

如果您想要让使用者登陆后取得一些信息,例如您想要让大家都知道的信息, 那么可以将信息加入到 /etc/motd 里面去!例如:当登陆后,告诉登陆者, 系统将会在某个固定时间进行维护工作。

bash 的环境配置文件

bash配置文件又可以分为全体系统的配置文件以及用户个人偏好配置文件。要注意的是, 前面谈到的命令别名、自定义的变量,在你注销 bash 后就会失效,所以你想要保留你的配置, 就得要将这些配置写入配置文件才行。

login 与 non-login shell

login shell:取得 bash 时需要完整的登陆流程的,就称为 login shell。举例来说,你要由 tty1 ~ tty6 登陆,需要输入用户的账号与密码,此时取得的 bash 就称为『 login shell 』;

non-login shell:取得 bash 接口的方法不需要重复登陆的举动,举例来说,(1)你以 X window 登陆 Linux 后, 再以 X 的图形化接口启动终端机,此时那个终端接口并没有需要再次的输入账号与密码,那个 bash 的环境就称为 non-login shell了。(2)你在原本的 bash 环境下再次下达 bash 这个命令,同样的也没有输入账号密码, 那第二个 bash (子程序) 也是 non-login shell 。

一般来说,login shell 其实只会读取这两个配置文件:

1./etc/profile:这是系统整体的配置,你最好不要修改这个文件;

2.~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人配置,你要改自己的数据,就写入这里。

/etc/profile (login shell 才会读)

这个文件配置的变量主要有:

PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统命令目录;
MAIL:依据账号配置好使用者的 mailbox 到 /var/spool/mail/账号名;
USER:根据用户的账号配置此一变量内容;
HOSTNAME:依据主机的 hostname 命令决定此一变量内容;
HISTSIZE:历史命令记录笔数。CentOS 5.x 配置为 1000 ;


**/etc/profile 还会呼叫出其他的配置文件

~/.bash_profile (login shell 才会读)

在 login shell 的 bash 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:

~/.bash_profile
~/.bash_login
~/.profile


其实 bash 的 login shell 配置只会读取上面三个文件的其中一个, 而读取的顺序则是依照上面的顺序。



login shell 的配置文件读取流程

source :读入环境配置文件的命令

~/.bashrc (non-login shell 会读)

除了~/.bashrc,CentOS还会主动的呼叫 /etc/bashrc 这个文件, 因为 /etc/bashrc 帮我们的 bash 定义出底下的数据:

依据不同的 UID 规范出 umask 的值;
依据不同的 UID 规范出提示字符 (就是 PS1 变量);
呼叫 /etc/profile.d/*.sh 的配置


其他相关配置文件

/etc/man.config :规范了使用 man 的时候, man page 的路径到哪里去寻找

~/.bash_history:历史命令

~/.bash_logout:当我注销 bash 后,系统再帮我做完什么动作后才离开

终端机的环境配置: stty, set

stty -a :列出目前环境中所有的按键列表。

如果出现 ^ 表示 [Ctrl] 那个按键的意思。举例来说, intr = ^C 表示利用 [ctrl] + c 来达成的。几个重要的代表意义是:

eof   : End of file 的意思,代表『结束输入』。
erase : 向后删除字符,
intr  : 送出一个 interrupt (中断) 的讯号给目前正在 run 的程序;
kill  : 删除在目前命令列上的所有文字;
quit  : 送出一个 quit 的讯号给目前正在 run 的程序;
start : 在某个程序停止后,重新启动他的 output
stop  : 停止目前屏幕的输出;
susp  : 送出一个 terminal stop 的讯号给正在 run 的程序。


通配符与特殊符号

通配符

符号意义
*代表『 0 个到无穷多个』任意字符
?代表『一定有一个』任意字符
[ ]同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd]代表『一定有一个字符, 可能是 a, b, c, d 这四个任何一个』
[ - ]若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如[0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的!
[^ ]若中括号内的第一个字符为指数符号 (^) ,那表示『反向选择』,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思。
特殊符号

符号内容
#批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不运行
\跳脱符号:将『特殊字符或通配符』还原成一般字符
|管线 (pipe):分隔两个管线命令的界定(后两节介绍);
;连续命令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同)
~用户的家目录
$取用变量前导符:亦即是变量之前需要加的变量取代值
&工作控制 (job control):将命令变成背景下工作
!逻辑运算意义上的『非』 not 的意思!
/目录符号:路径分隔的符号
>, >>数据流重导向:输出导向,分别是『取代』与『累加』
<, <<数据流重导向:输入导向 (这两个留待下节介绍)
’ ‘单引号,不具有变量置换的功能
” “具有变量置换的功能!
` `两个『 ` 』中间为可以先运行的命令,亦可使用 $( )
( )在中间为子 shell 的起始与结束
{ }在中间为命令区块的组合!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: