认识与学习 BASH

BASH

硬件、核心与 Shell

  『什么是 Shell 』?相信只要摸过计算机,对于操作系统 (不论是 Linux 、Unix 或者是 Windows) 有点概念的朋友们大多听过这个名词,因为只要有『操作系统』那么就离不开 Shell 这个东西。不过,在讨论 Shell 之前,我们先来了解一下计算机的运作状况吧! 举个例子来说:当你要计算机传输出来『音乐』的时候,你的计算机需要什么东西呢?

  1. 硬件:当然就是需要你的硬件有『声卡芯片』这个配备,否则怎么会有声音;
  2. 核心管理:操作系统的核心可以支持这个芯片组,当然还需要提供芯片的驱动程序啰;
  3. 应用程序:需要使用者 (就是你) 输入发生声音的指令啰!

  这就是基本的一个输出声音所需要的步骤!也就是说,你必须要『输入』一个指令之后, 『硬件』才会透过你下达的指令来工作!那么硬件如何知道你下达的指令呢?那就是 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=$' 	
' <== 预设的分隔符
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』后面省略
    • :显示时间,为 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 的操作环境

路径与指令搜寻顺序

指令运作的顺序可以这样看:

  1. 以相对/绝对路径执行指令,例如『 /bin/ls 』或『 ./ls 』;
  2. 由 alias 找到该指令来执行;
  3. 由 bash 内建的 (builtin) 指令来执行;
  4. 透过 $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 其实只会读取这两个配置文件:

  1. /etc/profile:这是系统整体的设定,你最好不要修改这个文件;
  2. ~/.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 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.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) 分别传送到其他的文件或装置去,而分别传送所
用的特殊字符则如下所示:

  1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
  2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
  3. 标准错误输出(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 等。
原文地址:https://www.cnblogs.com/chengmf/p/12638964.html