认识与学习 BASH
BASH
硬件、核心与 Shell
『什么是 Shell 』?相信只要摸过计算机,对于操作系统 (不论是 Linux 、Unix 或者是 Windows) 有点概念的朋友们大多听过这个名词,因为只要有『操作系统』那么就离不开 Shell 这个东西。不过,在讨论 Shell 之前,我们先来了解一下计算机的运作状况吧! 举个例子来说:当你要计算机传输出来『音乐』的时候,你的计算机需要什么东西呢?
- 硬件:当然就是需要你的硬件有『声卡芯片』这个配备,否则怎么会有声音;
- 核心管理:操作系统的核心可以支持这个芯片组,当然还需要提供芯片的驱动程序啰;
- 应用程序:需要使用者 (就是你) 输入发生声音的指令啰!
这就是基本的一个输出声音所需要的步骤!也就是说,你必须要『输入』一个指令之后, 『硬件』才会透过你下达的指令来工作!那么硬件如何知道你下达的指令呢?那就是 kernel (核心) 的控制工作了!也就是说,我们必须要透过『 Shell 』将我们输入的指令与 Kernel 沟通,好让 Kernel 可以控制硬件来正确无误的工作! 基本上,我们可以透过底下这张图来说明一下:
查询指令是否为 Bash shell 的内建命令:type
- type [-tpa] name
- 选项与参数:
- :不加任何选项与参数时,type 会显示出 name 是外部指令还是 bash 内建指令
- -t :当加入 -t 参数时,type 会将 name 以底下这些字眼显示出他的意义;
- file :表示为外部指令;
- alias :表示该指令为命令别名所设定的名称;
- builtin :表示该指令为 bash 内建的指令功能;
- -p :如果后面接的 name 为外部指令时,才会显示完整文件名;
- -a :会由 PATH 变量定义的路径中,将所有含 name 的指令都列出来,包含 alias
指令的下达与快速编辑按钮
Shell 的变量功能
『变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数!』
变量的取用与设定:echo,变量设定规则,unset
在 bash 当中,当一个变量名称尚未被设定时,预设的内容是『空』的。
变量的设定规则
- 变量与变量内容以一个等号『=』来连结,如下所示:
『myname=VBird』 - 等号两边不能直接接空格符,如下所示为错误:
『myname = VBird』或『myname=VBird Tsai』 - 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:
『2myname=VBird』 - 变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但
- 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
『var="lang is $LANG"』则『echo $var』可得『lang is zh_TW.UTF-8』 - 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』
- 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:
- 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, , 空格符, '等)变成一般字符,如:
『myname=VBird\ Tsai』 - 在一串指令的执行中,还需要藉由其他额外的指令所提供的信息时,可以使用反单引号或 『$ (指令)』。例如想要取得核心版本的设定:『version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64』
- 若该变量为扩增变量内容时,则可用 "$变量名称" 或 \({变量} 累加内容,如下所示: 『PATH="\)PATH":/home/bin』或『PATH=${PATH}:/home/bin』
- 若该变量需要在其他子程序执行,则需要以 export 来使变量变成环境变量:
『export PATH』 - 通常大写字符为系统默认变量,自行设定变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ;
- 取消变量的方法为使用 unset :『unset 变量名称』例如取消 myname 的设定:
『unset myname』
用 env 观察环境变量与常见环境变量说明
[dmtsai@study ~]$ env
HOSTNAME=study.centos.vbird <== 这部主机的主机名
TERM=xterm <== 这个终端机使用的环境是什么类型
SHELL=/bin/bash <== 目前这个环境下,使用的 Shell 是哪一个程序?
HISTSIZE=1000 <== 『记录指令的笔数』在 CentOS 默认可记录 1000 笔
OLDPWD=/home/dmtsai <== 上一个工作目录的所在
LC_ALL=en_US.utf8 <== 由于语系的关系,鸟哥偷偷丢上来的一个设定
USER=dmtsai <== 使用者的名称啊!
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... <== 一些颜色显示
MAIL=/var/spool/mail/dmtsai <== 这个用户所取用的 mailbox 位置
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
PWD=/home/dmtsai <== 目前用户所在的工作目录 (利用 pwd 取出!)
LANG=zh_TW.UTF-8 <== 这个与语系有关,底下会再介绍!
HOME=/home/dmtsai <== 这个用户的家目录啊!
LOGNAME=dmtsai <== 登入者用来登入的账号名称
_=/usr/bin/env <== 上一次使用的指令的最后一个参数(或指令本身)
- HOME
代表用户的家目录。还记得我们可以使用 cd ~ 去到自己的家目录吗?或者利用 cd 就可以直接回到用户家目录了。那就是取用这个变量啦~ 有很多程序都可能会取用到这个变量的值! - SHELL
告知我们,目前这个环境使用的 SHELL 是哪支程序? Linux 预设使用 /bin/bash 的啦! - HISTSIZE
这个与『历史命令』有关,亦即是, 我们曾经下达过的指令可以被系统记录下来,而记录的『笔数』则是由这个值来设定的。 - MAIL
当我们使用 mail 这个指令在收信时,系统会去读取的邮件信箱文件 (mailbox)。 - PATH
就是执行文件搜寻的路径啦~目录与目录中间以冒号(:)分隔,由于文件的搜寻是依序由 PATH 的变量内的目录来查询,所以,目录的顺序也是重要的喔。 - LANG
这个重要!就是语系数据啰~很多讯息都会用到他, 举例来说,当我们在启动某些 perl 的程序语言文件时,他会主动的去分析语系数据文件, 如果发现有他无法解析的编码语系,可能会产生错误喔!一般来说,我们中文编码通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,这两个编码偏偏不容易被解译出来,所以,有的时候,可能需要修订一下语系数据。 这部分我们会在下个小节做介绍的! - RANDOM
这个玩意儿就是『随机随机数』的变量啦!目前大多数的 distributions 都会有随机数生成器,那就是/dev/random 这个文件。 我们可以透过这个随机数文件相关的变量 ($RANDOM) 来随机取得随机数值喔。在 BASH 的环境下,这个 RANDOM 变量的内容,介于 0 ~ 32767 之间,所以,你只要 echo $RANDOM 时,系统就会主动的随机取出一个介于 0~ 32767 的数值。万一我想要使用 0~9 之间的数值呢?呵呵~利用declare 宣告数值类型, 然后这样做就可以了。
用 set 观察所有变量 (含环境变量与自定义变量)
[dmtsai@study ~]$ set
BASH=/bin/bash <== bash 的主程序放置路径
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(1)-release' <== 这两行是 bash 的版本啊!
COLUMNS=90 <== 在目前的终端机环境下,使用的字段有几个字符长度
HISTFILE=/home/dmtsai/.bash_history <== 历史命令记录的放置文件,隐藏档
HISTFILESIZE=1000 <== 存起来(与上个变量有关)的文件之指令的最大纪录笔数。
HISTSIZE=1000 <== 目前环境下,内存中记录的历史命令最大笔数。
IFS=$' \t\n' <== 预设的分隔符
LINES=20 <== 目前的终端机下的最大行数
MACHTYPE=x86_64-redhat-linux-gnu <== 安装的机器类型
OSTYPE=linux-gnu <== 操作系统的类型!
PS1='[\u@\h \W]\$ ' <== PS1 就厉害了。这个是命令提示字符,也就是我们常见的
[root@www ~]# 或 [dmtsai ~]$ 的设定值啦!可以更动的!
PS2='> ' <== 如果你使用跳脱符号 (\) 第二行以后的提示字符也
$ <== 目前这个 shell 所使用的 PID
? <== 刚刚执行完指令的回传值。
...
- PS1:(提示字符的设定)
- \d :可显示出『星期 月 日』的日期格式,如:"Mon Feb 2"
- \H :完整的主机名。举例来说,鸟哥的练习机为『study.centos.vbird』
- \h :仅取主机名在第一个小数点之前的名字,如鸟哥主机则为『study』后面省略
- \t :显示时间,为 24 小时格式的『HH:MM:SS』
- \T :显示时间,为 12 小时格式的『HH:MM:SS』
- \A :显示时间,为 24 小时格式的『HH:MM』
- @ :显示时间,为 12 小时格式的『am/pm』样式
- \u :目前使用者的账号名称,如『dmtsai』;
- \v :BASH 的版本信息,如鸟哥的测试主机版本为 4.2.46(1)-release,仅取『4.2』显示
- \w :完整的工作目录名称,由根目录写起的目录名称。但家目录会以 ~ 取代;
- \W :利用 basename 函数取得工作目录名称,所以仅会列出最后一个目录名。
- # :下达的第几个指令。
- $ :提示字符,如果是 root 时,提示字符为 # ,否则就是 $ 啰~
[dmtsai@study ~]$ cd /home
[dmtsai@study home]$ PS1='[\u@\h \w \A #\#]\$ '
[dmtsai@study /home 17:02 #85]$
- $:(关于本 shell 的 PID)
钱字号本身也是个变量喔!这个咚咚代表的是『目前这个 Shell 的线程代号』,亦即是所谓的 PID(Process ID).想要知道我们的 shell 的 PID ,就可以用:『 echo $$ 』即可!出现的数字就是你的 PID 号码。 - ?:(关于上个执行指令的回传值)
这个变数是:『上一个执行的指令所回传的值』, 上面这句话的重点是『上一个指令』与『回传值』两个地方。当我们执行某些指令时,这些指令都会回传一个执行后的代码。一般来说,如果成功的执行该指令,则会回传一个 0 值,如果执行过程发生错误,就会回传『错误代码』才对!一般就是以非为 0 的数值来取代。
[dmtsai@study ~]$ echo $SHELL
/bin/bash <==可顺利显示!没有错误!
[dmtsai@study ~]$ echo $?
0 <==因为没问题,所以回传值为 0
[dmtsai@study ~]$ 12name=VBird
bash: 12name=VBird: command not found... <==发生错误了!bash 回报有问题
[dmtsai@study ~]$ echo $?
127 <==因为有问题,回传错误代码(非为 0)
- export: 自定义变量转成环境变量『 该变量是会被子程序所继续引用,分享自己的变量设定给后来呼叫的文件或其他程序』
为什么环境变量的数据可以被子程序所引用呢?这是因为内存配置的关系!理论上是这样的:
- 当启动一个 shell,操作系统会分配一记忆区块给 shell 使用,此内存内之变量可让子程序取用
- 若在父程序利用 export 功能,可以让自定义变量的内容写到上述的记忆区块当中(环境变量);
- 当加载另一个 shell 时 (亦即启动子程序,而离开原本的父程序了),子 shell 可以将父 shell 的环境变量所在的记忆区块导入自己的环境变量区块当中。
变量键盘读取 read
- read [-pt] variable
- 选项与参数:
- -p :后面可以接提示字符!
- -t :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!
范例一:让用户由键盘输入一内容,将该内容变成名为 atest 的变量
[dmtsai@study ~]$ read atest
This is a test <==此时光标会等待你输入!请输入左侧文字看看
[dmtsai@study ~]$ echo ${atest}
This is a test <==你刚刚输入的数据已经变成一个变量内容!
数组 array
- var[index]=content
宣告变量的类型 declare / typeset
- declare [-aixr] variable
- 选项与参数:
- -a :将后面名为 variable 的变量定义成为数组 (array) 类型
- -i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
- -x :用法与 export 一样,就是将后面的 variable 变成环境变量;
- -r :将变量设定成为 readonly 类型,该变量不可被更改内容,也不能 unset
与文件系统及程序的限制关系:ulimit
- ulimit [-SHacdfltu] [配额]
- 选项与参数:
- -H :hard limit ,严格的设定,必定不能超过这个设定的数值;
- -S :soft limit ,警告的设定,可以超过这个设定值,但是若超过则有警告讯息。在设定上,通常 soft 会比 hard 小,举例来说,soft 可设定为 80 而 hard设定为 100,那么你可以使用到 90 (因为没有超过 100),但介于 80~100 之间时,系统会有警告讯息通知你!
- -a :后面不接任何选项与参数,可列出所有的限制额度;
- -c :当某些程序发生错误时,系统可能会将该程序在内存中的信息写成文件(除错用),这种文件就被称为核心文件(core file)。此为限制每个核心文件的最大容量。
- -f :此 shell 可以建立的最大文件容量(一般可能设定为 2GB)单位为 Kbytes
- -d :程序可使用的最大断裂内存(segment)容量;
- -l :可用于锁定 (lock) 的内存量
- -t :可使用的最大 CPU 时间 (单位为秒)
- -u :单一用户可以使用的最大程序(process)数量。
变量内容的删除、取代与替换 (Optional)
命令别名与历史命令
命令别名设定:alias,unalias
『alias 的定义规则与变量定义规则几乎相同』,所以你只要在 alias 后面加上你的 {『别名』='指令 选项...' }
历史命令:history
- history [n]
- history [-c]
- history [-raw] histfiles
-选项与参数:- n :数字,意思是『要列出最近的 n 笔命令行表』的意思!
- -c :将目前的 shell 中的所有 history 内容全部消除
- -a :将目前新增的 history 指令新增入 histfiles 中,若没有加 histfiles ,则预设写入 ~/.bash_history
- -r :将 histfiles 的内容读到目前这个 shell 的 history 记忆中;
- -w :将目前的 history 记忆内容写入 histfiles 中!
在正常的情况下,历史命令的读取与记录是这样的:
-
当我们以 bash 登入 Linux 主机之后,系统会主动的由家目录的 ~/.bash_history 读取以前曾经下过的指令,那么 ~/.bash_history 会记录几笔数据呢?这就与你 bash 的 HISTFILESIZE 这个变量设定值有关了!
-
假设我这次登入主机后,共下达过 100 次指令,『等我注销时, 系统就会将 101~1100 这总共 1000 笔历史命令更新到 ~/.bash_history 当中。』 也就是说,历史命令在我注销时,会将最近的 HISTFILESIZE 笔记录到我的纪录文件当中啦!
-
当然,也可以用 history -w 强制立刻写入的!那为何用『更新』两个字呢? 因为 ~/.bash_history 记录的笔数永远都是 HISTFILESIZE 那么多,旧的讯息会被主动的拿掉! 仅保留最新的!
-
!number
-
!command
-
!!
-
选项与参数:
- number :执行第几笔指令的意思;
- command :由最近的指令向前搜寻『指令串开头为 command』的那个指令,并执行;!! :就是执行上一个指令(相当于按↑按键后,按 Enter)
Bash Shell 的操作环境
路径与指令搜寻顺序
指令运作的顺序可以这样看:
- 以相对/绝对路径执行指令,例如『 /bin/ls 』或『 ./ls 』;
- 由 alias 找到该指令来执行;
- 由 bash 内建的 (builtin) 指令来执行;
- 透过 $PATH 这个变量的顺序搜寻到的第一个指令来执行。
bash 的进站与欢迎讯息: /etc/issue, /etc/motd
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 其实只会读取这两个配置文件:
- /etc/profile:这是系统整体的设定,你最好不要修改这个文件;
- ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:属于使用者个人设定,你要改自己的数据,就写入这里!
/etc/profile (login shell 才会读)
每个使用者登入取得 bash 时一定会读取的配置文件这个文件设定的变量主要有:
- PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统指令目录;
- MAIL:依据账号设定好使用者的 mailbox 到 /var/spool/mail/账号名;
- USER:根据用户的账号设定此一变量内容;
- HOSTNAME:依据主机的 hostname 指令决定此一变量内容;
- HISTSIZE:历史命令记录笔数。CentOS 7.x 设定为 1000 ;
- umask:包括 root 默认为 022 而一般用户为 002 等!
/etc/profile 可不止会做这些事而已,他还会去呼叫外部的设定数据:
- /etc/profile.d/*.sh
其实这是个目录内的众多文件!只要在 /etc/profile.d/ 这个目录内且扩展名为 .sh ,另外,使用者能够具有 r 的权限, 那么该文件就会被 /etc/profile 呼叫进来。在 CentOS 7.x 中,这个目录底下的文件规范了 bash 操作接口的颜色、 语系、ll 与 ls 指令的命令别名、vi 的命令别名、which的命令别名等等。如果你需要帮所有使用者设定一些共享的命令别名时, 可以在这个目录底下自行建立扩展名为 .sh 的文件,并将所需要的数据写入即可喔! - /etc/locale.conf
这个文件是由 /etc/profile.d/lang.sh 呼叫进来的!这也是我们决定 bash 预设使用何种语系的重要配置文件! 文件里最重要的就是 LANG/LC_ALL 这些个变量的设定啦!我们在前面的 locale 讨论过这个文件!自行回去瞧瞧先! - /usr/share/bash-completion/completions/*
记得我们上头谈过 [tab] 的妙用吧?除了命令补齐、档名补齐之外,还可以进行指令的选项/参数补齐功能!那就是从这个目录里面找到相对应的指令来处理的! 其实这个目录底下的内容是由/etc/profile.d/bash_completion.sh 这个文件载入的啦!
只要记得,bash 的 login shell 情况下所读取的整体环境配置文件其实只有 /etc/profile
~/.bash_profile (login shell 才会读)
在 login shell 的 bash 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
其实 bash 的 login shell 设定只会读取上面三个文件的其中一个, 而读取的顺序则是依照上面的顺
序。
source :读入环境配置文件的指令
source 配置文件档名
范例:将家目录的 ~/.bashrc 的设定读入目前的 bash 环境中
[dmtsai@study ~]$ source ~/.bashrc <==底下这两个指令是一样的!
[dmtsai@study ~]$ . ~/.bashrc
~/.bashrc (non-login shell 会读)
root@study ~]# cat ~/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i' <==使用者的个人设定
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then <==整体的环境设定
. /etc/bashrc
fi
/etc/bashrc 帮我们的 bash 定义出底下的数据:
- 依据不同的 UID 规范出 umask 的值;
- 依据不同的 UID 规范出提示字符 (就是 PS1 变量);
- 呼叫 /etc/profile.d/*.sh 的设定
其他相关配置文件
- /etc/man_db.conf
这个文件乍看之下好像跟 bash 没相关性,但是对于系统管理员来说,却也是很重要的一个文件!这的文件的内容『规范了使用 man 的时候, man page 的路径到哪里去寻找!』所以说的简单一点,这个文件规定了下达 man 的时候,该去哪里查看数据的路径设定!那么什么时候要来修改这个文件呢?如果你是以 tarball 的方式来安装你的数据,那么你的 manpage 可能会放置在 /usr/local/softpackage/man 里头,那个 softpackage 是你的套件名称, 这个时候你就得以手动的方式将该路径加到 /etc/man_db.conf 里头,否则使用 man 的时候就会找不到相关的说明档啰。 - ~/.bash_history
还记得我们在历史命令提到过这个文件吧?预设的情况下, 我们的历史命令就记录在这里啊!而这个文件能够记录几笔数据,则与 HISTFILESIZE 这个变数有关啊。每次登入 bash 后,bash 会先读取这个文件,将所有的历史指令读入内存, 因此,当我们登入 bash 后就可以查知上次使用过哪些指令啰。至于更多的历史指令, 请自行回去参考喔! - ~/.bash_logout
这个文件则记录了『当我注销 bash 后,系统再帮我做完什么动作后才离开』的意思。 你可以去读取一下这个文件的内容,预设的情况下,注销时, bash 只是帮我们清掉屏幕的讯息而已。 不过,你也可以将一些备份或者是其他你认为重要的工作写在这个文件中 (例如清空暂存盘), 那么当你离开 Linux 的时候,就可以解决一些烦人的事情啰!
终端机的环境设定: stty, set
stty [-a]
选项与参数:
-a :将目前所有的 stty 参数列出来;
范例一:列出所有的按键与按键内容
[dmtsai@study ~]$ stty -a
speed 38400 baud; rows 20; columns 90; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 1; time = 0;
....(以下省略)....
如果出现 ^ 表示 [Ctrl] 那个按键的意思。举例来说, intr = ^C 表示利用 [ctrl] +c 来达成的。几个重要的代表意义是:
-
intr : 送出一个 interrupt (中断) 的讯号给目前正在 run 的程序 (就是终止啰!);
-
quit : 送出一个 quit 的讯号给目前正在 run 的程序;
-
erase : 向后删除字符,
-
kill : 删除在目前指令列上的所有文字;
-
eof : End of file 的意思,代表『结束输入』。
-
start : 在某个程序停止后,重新启动他的 output
-
stop : 停止目前屏幕的输出;
-
susp : 送出一个 terminal stop 的讯号给正在 run 的程序。
-
set [-uvCHhmBx]
-
选项与参数:
- -u :预设不启用。若启用后,当使用未设定变量时,会显示错误讯息;
- -v :预设不启用。若启用后,在讯息被输出前,会先显示讯息的原始内容;
- -x :预设不启用。若启用后,在指令被执行前,会显示指令内容(前面有 ++ 符号)
- -h :预设启用。与历史命令有关;
- -H :预设启用。与历史命令有关;
- -m :预设启用。与工作管理有关;
- -B :预设启用。与刮号 [] 的作用有关;
- -C :预设不启用。若使用 > 等,则若文件存在时,该文件不会被覆盖。
bash 默认的组合键给他汇整如下:
通配符与特殊符号
bash 环境中的特殊符号:
数据流重导向
一般来说,如果你要执行一个指令,通常他会是这样的:
数据流重导向可以将 standard output(简称 stdout) 与 standard error output (简称 stderr) 分别传送到其他的文件或装置去,而分别传送所
用的特殊字符则如下所示:
- 标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
- 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
- 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
- 1> :以覆盖的方法将『正确的数据』输出到指定的文件或装置上;
- 1>>:以累加的方法将『正确的数据』输出到指定的文件或装置上;
- 2> :以覆盖的方法将『错误的数据』输出到指定的文件或装置上;
- 2>>:以累加的方法将『错误的数据』输出到指定的文件或装置上;
命令执行的判断依据: ; , &&, ||
- cmd ; cmd (不考虑指令相关性的连续指令下达)
管线命令 (pipe)
这个管线命令『 | 』仅能处理经由前面一个指令传来的正确信息,也就是 standard output 的信息,对于stdandard error 并没有直接处理的能力
- 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
- 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。
cut 是将一行讯息当中,取出某部分我们想要的
- cut -d'分隔字符' -f fields <==用于有特定分隔字符
- cut -c 字符区间 <==用于排列整齐的讯息
- 选项与参数:
- -d :后面接分隔字符。与 -f 一起使用;
- -f :依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
- -c :以字符 (characters) 的单位取出固定字符区间;
grep则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来
- grep [-acinv] [--color=auto] '搜寻字符串' filename
- 选项与参数:
- -a :将 binary 文件以 text 文件的方式搜寻数据
- -c :计算找到 '搜寻字符串' 的次数
- -i :忽略大小写的不同,所以大小写视为相同
- -n :顺便输出行号
- -v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
- --color=auto :可以将找到的关键词部分加上颜色的显示喔!
sort 以依据不同的数据型态来排序
- sort [-fbMnrtuk] [file or stdin]
- 选项与参数:
- -f :忽略大小写的差异,例如 A 与 a 视为编码相同;
- -b :忽略最前面的空格符部分;
- -M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
- -n :使用『纯数字』进行排序(默认是以文字型态来排序的);
- -r :反向排序;
- -u :就是 uniq ,相同的数据中,仅出现一行代表;
- -t :分隔符,预设是用 [tab] 键来分隔;
- -k :以那个区间 (field) 来进行排序的意思
uniq 将重复的资料仅列出一个显示
- uniq [-ic]
- 选项与参数:
- -i :忽略大小写字符的不同;
- -c :进行计数;
wc 计算输出的讯息的整体数据
- wc [-lwm]
- 选项与参数:
- -l :仅列出行;
- -w :仅列出多少字(英文单字);
- -m :多少字符;
双向重导向:tee
- tee [-a] file
- 选项与参数:
- -a :以累加 (append) 的方式,将数据加入 file 当中!
tr 删除一段讯息当中的文字,或者是进行文字讯息的替换!
- tr [-ds] SET1 ...
- 选项与参数:
- -d :删除讯息当中的 SET1 这个字符串;
- -s :取代掉重复的字符!
col简单的处理将 [tab] 按键取代成为空格键!
- col [-xb]
- 选项与参数:
- -x :将 tab 键转换成对等的空格键
join (加入/参加)
- join [-ti12] file1 file2
- 选项与参数:
- -t :join 默认以空格符分隔数据,并且比对『第一个字段』的数据,如果两个文件相同,则将两笔数据联成一行,且第一个字段放在第一个!
- -i :忽略大小写的差异;
- -1 :这个是数字的 1 ,代表『第一个文件要用那个字段来分析』的意思;
- -2 :代表『第二个文件要用那个字段来分析』的意思。
在使用 join 之前,你所需要处理的文件应该要事先经过排序 (sort) 处理!
paste 『将两行贴在一起,且中间以 [tab] 键隔开』
- paste [-d] file1 file2
- 选项与参数:
- -d :后面可以接分隔字符。预设是以 [tab] 来分隔的!
- - :如果 file 部分写成 - ,表示来自 standard input 的资料的意思
expand 将 [tab] 按键转成空格键
- expand [-t] file
- 选项与参数:
- -t :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。 我们也可以自行定义一个 [tab] 按键代表多少个字符呢!
分区命令: spli
- split [-bl] file PREFIX
- 选项与参数:
- -b :后面可接欲分区成的文件大小,可加单位,例如 b, k, m 等;
- -l :以行数来进行分区。
- PREFIX :代表前导符的意思,可作为分区文件的前导文字。
参数代换: xargs
- xargs [-0epn] command
- 选项与参数:
- -0 :如果输入的 stdin 含有特殊字符,例如 `, , 空格键等等字符时,这个 - -0 参数可以将他还原成一般字符。这个参数可以用于特殊状态!
- -e :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到这个字符串时, 就会停止继续工作!
- -p :在执行每个指令的 argument 时,都会询问使用者的意思;
- -n :后面接次数,每次 command 指令执行时,要使用几个参数的意思。当 xargs 后面没有接任何的指令时,默认是以 echo 来进行输出。
重点回顾
- 由于核心在内存中是受保护的区块,因此我们必须要透过『 Shell 』将我们输入的指令与 Kernel 沟通,好让 Kernel 可以控制硬件来正确无误的工作
- 学习 shell 的原因主要有:文字接口的 shell 在各大 distribution 都一样;远程管理时文字接口速度较快;shell 是管理 Linux 系统非常重要的一环,因为 Linux 内很多控制都是以 shell 撰写的。
- 系统合法的 shell 均写在 /etc/shells 文件中;
- 用户默认登入取得的 shell 记录于 /etc/passwd 的最后一个字段;
- bash 的功能主要有:命令编修能力;命令与文件补全功能;命令别名设定功能;工作控制、前景背景控制;程序化脚本;通配符
- type 可以用来找到执行指令为何种类型,亦可用于与 which 相同的功能;
- 变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数据
- 变量主要有环境变量与自定义变量,或称为全局变量与局部变量
- 使用 env 与 export 可观察环境变量,其中 export 可以将自定义变量转成环境变量;
- set 可以观察目前 bash 环境下的所有变量;
- $? 亦为变量,是前一个指令执行完毕后的回传值。在 Linux 回传值为 0 代表执行成功;
- locale 可用于观察语系资料;
- 可用 read 让用户由键盘输入变量的值
- ulimit 可用以限制用户使用系统的资源情况
- bash 的配置文件主要分为 login shell 与 non-login shell。login shell 主要读取 /etc/profile 与 ~/.bash_profile,non-login shell 则仅读取 ~/.bashrc
- 在使用 vim 时,若不小心按了 [crtl]+s 则画面会被冻结。你可以使用 [ctrl]+q 来解除冻结
- 通配符主要有: *, ?, [] 等等
- 数据流重导向透过 >, 2>, < 之类的符号将输出的信息转到其他文件或装置去;
- 连续命令的下达可透过 ; && || 等符号来处理
- 管线命令的重点是:『管线命令仅会处理 standard output,对于 standard error output 会予以忽略』 『管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。』
- 本章介绍的管线命令主要有:cut, grep, sort, wc, uniq, tee, tr, col, join, paste, expand, split, xargs 等。