10.1 认识Bash这个Shell

硬件、核心与Shell

我们必须要透过『Shell 』将我们输入的指令与Kernel 沟通,好让Kernel 可以 控制硬件来正确无误的工作!

包括man, chmod, chown, vi, fdisk, mkfs 等等指令,这些指令都是独立的应用程序,但是我们可以透过壳程序(就是指令列模式) 来操作这些应用程序,让这些应用程序呼叫核心来运作所需的工作。

  • 狭义的壳程序指的是指令列方面的软件,包括本章要介绍的bash 等。
  • 广义的壳程序则包括图形接口的软件!

    为什么学习文字接口的shell

  1. 各家distributions 使用的bash都一样
  2. 远程管理:文字接口就是比较快
  3. 编写shell程序管理主机系统

    系统的合法shell 与/etc/shells 功能

  4. 系统某些服务在运作过程中,会去检查使用者能够使用的shells ,而这些shell 的查询就是藉由 /etc/shells

  5. 使用者什么时候可以取得shell 来工作呢?使用者预设会取得哪一个shell :记录在 /etc/passwd 这个文件

    image.png

    Bash shell的功能

  • 命令编修能力(history。指令记录在 ~/.bash_history
  • 命令与文件补全功能:([tab] 按键的好处。bash-completion软件。
  • 命令别名设定功能:(alias)
  • 工作控制、前景背景控制:(job control, foreground, background)(十六章)
  • 程序化脚本:(shell scripts)
  • 通配符:(Wildcard)。ls -l /usr/bin/X*

    查询指令是否为Bash shell 的内建命令:type

    指令快速编辑按钮

    image.png

    10.2 Shell的变量功能

    环境变量都是大写,PATH, HOME, SHELL,MAIL

    变量的取用、设定、 unset

    变量读取 echo

    echo ${PATH}
    echo $foo 如果foo未设定值,则结果为空或报错

    变量设定

    foo = bar

    变量的设定规则

    P429
    等号两侧无空格、英文开头、双引号/单引号、跳脱字符\、指令或$(指令)
    扩增变量 PATH ="$PATH:/home/bin"PATH=${PATH}:/home/bin
    export变量为环境变量。进入子程序的命令: bash

    什么是『子程序』呢?就是说,在我目前这个shell 的情况下,去启用另一个新的shell ,新的那个 shell 就是子程序啦!在一般的状态下,父程序的自定义变量是无法在子程序内使用的。但是透过 export 将变量变成环境变量后,就能够在子程序底下应用了

取消变量unset myname

变量的各种用途

各种符号规则的利用。映射指令/变量、定义工作目录简化输入等,

环境变量

用env 观察环境变量与常见环境变量说明

  • HOME
  • SHELL(使用的SHELL,linux预设/bin/bash)
  • HISTSIZE(历史命令)
  • LANG
  • MAIL
  • PATH
  • RANDOM

declare宣告类型
image.png

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

PS1

命令提示字符设定
反斜杠后的数据为PS1 的特殊功能,与bash 的变量设定没关系啦

  1. # /etc/bashrc
  2. #预设 [yanjing@study ~]$
  3. PS1='[\u@\h \W]\$ '
  4. #设定 [dmtsai@study /home/dmtsai 16:50 #12]$
  5. PS1='[\u@\h \w \A #\#]\$ '

$:(关于本shell 的PID)

当你登入Linux 并取得一个bash 之后,你的bash 就是一个独立的程序,这个程序的识别使用的是一个称为程序标识符,被称为PID 的就是。接下来你在这个bash 底下所下达的任何指令都是由这个bash 所衍生出来的

  1. echo $$

?:(关于上个执行指令的回传值)

image.png

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

image.png

  • 子程序仅会继承父程序的环境变量,子程序不会继承父程序的自定义变量
  • export 变量名 分享自己的变量设定给后来呼叫的文件或其他程序
  • 如果仅下达export 而没有接变量时,那么此时将会把所有的『环境变量』秀出来喔

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

    image.png
  1. 语系文件都放置在:/usr/lib/locale/
  2. 整体系统默认的语系定义在: /etc/locale.conf

LANG和LC_ALL
如果其他的语系变量都未设定,且你有设定LANG 或者是LC_ALL 时,则其他的语系变量就会被这两个变量所取代!这也是为什么我们在Linux 当中,通常说明仅设定 LANGLC_ALL 这两个变量而已。
要让LC_ALL 生效时,得要使用export 转成环境变量才行。
image.png

中文/乱码

如果设置LANG=en_Zh,在tty1 ~ tty6 的环境下,加装一些中文化接口的软件,才能够看到中文啊

big5和utf-8

正体中文语系至少支持了两种以上的编码,big5和utf-8 编码

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

read

  1. read -pt variable

declare/typeset

宣告变量的类型
image.png

数组(array) 变量类型

  1. echo "${var[1]}, ${var[2]}, ${var[3]}"

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

  1. ulimit [-SHacdfltu] [配额]
  2. # 列出你目前身份(假设为一般账号)的所有限制数据数值
  3. ulimit -a

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

将变量的内容进行微调

删除

  1. echo ${path#/*local/bin:}
  2. echo ${path##/*:}

替代

  1. echo ${path/sbin/SBIN}
  2. echo ${path//sbin/SBIN}

变量的测试与替换(默认值)

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

  1. # 如果username没有设定过,就给它一个默认值root,否则就是已经设定过的那个值
  2. username=${username-root}
  3. # 加上『: 』后若变量内容为空或者是未设定,都能够以后面的内容替换!
  4. username=${username:-root}

- 减号的测试并不会影响到旧变量的内容

= 将旧变量内容也一起替换掉

?如果旧变量不存在时,整个测试就告知我『有错误』

基本上这种变数的测试也能够透过shell script 内的if…then… 来处理,不过既然bash 有提供这么 简单的方法来测试变量,那我们也可以多学一些嘛!不过这种变量测试通常是在程序设计当中比较 容易出现

image.png

10.3 命令别名与历史命令

alias, unalias

history

  1. history
  2. history 3
  3. history -w 立刻写入
  4. echo ${HISTSIZE} # 默认历史记录写入条数
  5. !66 <==执行第66 笔指令
  6. !al <==执行最近以al 为开头的指令(上头列出的第67个)

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

记录的是同一份。
单一bash 登入,再用工作控制(job control, 第四篇会介绍) 来切换不同工作。

10.4 Bash Shell的操作环境

路径与指令搜寻顺序

  1. type -a ls # 查询ls的顺序

bash 的进站与欢迎讯息

bash 的环境配置文件

  • login:首次登入文字界面
  • non-login: X window登入或Bash子程序

    log shell配置文件

  1. /etc/profile:这是系统整体的设定,你最好不要修改这个文件;
    2. ~/.bash_profile 或~/.bash_login 或~/.profile:属于使用者个人设定,读取上面三个文件的其中一个
    呼叫流程如下:
    image.png
  • ~/.bash_profile:

    image.png

  • 需要注销:

由于/etc/profile 与~/.bash_profile 都是在取得login shell 的时候才会读取的配置文件,所以,如
果你将自己的偏好设定写入上述的文件后,通常都是得注销再登入后,该设定才会生效。

  • source/或小数点指令,读入环境配置文件的指令
  1. source ~/.bashrc
  2. . ~/.bashrc

~/.bashrc (non-login shell 会读,且只读它)

其它

/etc/man_db.conf , ~/bash_history , ~/bash_logout

终端机的环境设定 stty, set

  1. stty [-a] # 列出所有的按键和按键内容
  2. # intr = ^C 即ctrl+c
  3. stty intr ^d
  4. set [-uvCHmBx] # bash内置终端机设定值
  • Ctrl + C 终止目前的命令
  • Ctrl + D 输入结束(EOF),例如邮件结束的时候;
  • Ctrl + M 就是Enter 啦!
  • Ctrl + S 暂停屏幕的输出
  • Ctrl + Q 恢复屏幕的输出
  • Ctrl + U 在提示字符下,将整列命令删除
  • Ctrl + Z 『暂停』目前的命令

通配符与特殊符号

通配符

基本和正则表达式一致
image.png

  1. mkdir tmp/upper; cp -a /etc/[^a-z]* /tmp/upper # 复制到uppper文件夹下

特殊符号

image.png

10.5 数据流重导向(标准输入<<和输出>>)

数据流重导向就是将某个指令执行后应该要出现在屏幕上的数据,给他传输到其他的地方, 例如文件或者是装置(例如打印机之类的)!这玩意儿在Linux 的文本模式底下可重要的!尤其是如 果我们想要将某些数据储存下来时,就更有用了!

image.png

数据流重导向用法

ouput

  1. 标准输入(stdin) :代码为0 ,使用< 或<< ;
  2. 标准输出(stdout):代码为1 ,使用> 或>> ;
  3. 标准错误输出(stderr):代码为2 ,使用2> 或2>>

以> 输出到一个已存在的文件中,那个文件就会被覆盖掉;以>>则会追加

  1. ll / > ~/rootfile
  2. ll /home >> ~/rootfile
  3. find /home -name .bashrc > list-right 2> list_error
  4. find /home -name .bashrc 2> dev/null # 将错误的数据丢弃,屏幕上显示正确的数据
  5. find /home -name .bashrc > list 2>&1 # 将正确和错误信息写入同一个文件
  6. echo "error message" 2> dev/null 1>&2 # 把正确信息和错误信息一样丢弃

input

  1. cat > catfile # 创建catfile,键盘输入内容保存之
  2. cat > catfile < ~/.bashrc # 输入.bashrc的内容到catfile中
  3. cat > catfile << 'eof'# 遇到输入eof可以终止一次输入,而不必输入[crtl]+d

使用输出重导向的场景

保存、避免干扰屏幕、丢弃、分别输出等

命令执行的判断依据:; && ||

  1. ;按顺序执行多个
  2. &&、|| 和js编程语句类似,但是执行顺序始终是从左到右

    若前一个指令执行的结果为正确,在Linux 底下会回传一个$? = 0 的值

  1. ls temp/abc || mkdir temp/abc && touch temp/abc/hehe
  2. ls temp/vbidrding && echo "exist" || echo "not exist"

管线命令(管道)

  • 管线命令仅会处理standard output,对于standard error output 会予以忽略
  • 管线命令必须要能够接受来自前一个指令的数据成为standard input 继续处理才行

Bash - 图17