linux读书摘要--BASH

来源:互联网 发布:恶心段子 知乎 编辑:程序博客网 时间:2024/04/28 22:51

声明:本文章为《鸟哥的Linux私房菜》读书摘要!


什么是Shell

    操作系统其实是一组软件,由于这组软件在控制整个硬件与管理系统的活动监测, 如果这组软件能被用户随意的操作,若使用者应用不当,将会使得整个系统崩溃。但是我们总是需要让用户操作系统的,所以就有了在操作系统上面发展的应用程序。用户可以透过应用程序来指挥核心, 让核心达成我们所需要的硬件任务我们可以发现应用程序其实是在最外层,就如同鸡蛋的外壳一样,因此这个咚咚也就被称呼为壳程序(shell) 。


    其实壳程序的功能只是提供用户操作系统的一个接口,因此这个壳程序需要可以呼叫其他软件才好。我们在第四章到第九章提到过很多指令,包括man, chmod, chown, vi, fdisk, mkfs等等指令,这些指令都是独立的应用程序, 但是我们可以透过壳程序(就是指令列模式)来操作这些应用程序,让这些应用程序呼叫核心来运作所需的工作。也就是说,只要能够操作应用程序的接口都能够称为壳程序。狭义的壳程序指的是指令列方面的软件,包括本章要介绍的bash等。 广义的壳程序则包括图形接口的软件。
    目前我们的Linux (CentOS 7.x为例)有多少我们可以使用的shells。你可以检查一下/etc/shells这个文件,至少就有底下这几个可以用的shells
    /bin/sh (已经被/bin/bash所取代)
    /bin/bash (就是Linux预设的 shell)
    /bin/tcsh (整合C Shell,提供更多的功能)
    /bin/csh (已经被/bin/tcsh所取代) 

Bash shell的功能
    bashGNU计划中重要的工具软件之一,目前也是Linux distributions的标准shell 。
    命令编修能力 (history)只要在指令列按『上下键』就可以找到前/后一个输入的指令。这些指令存储在你的家目录的.bash_history 。 不过,需要留意是,~/.bash_history记录的是前一次登入以前所执行过的指令, 而至于这一次登入所执行的指令都被暂存在内存中,当你成功的注销系统后,该指令记忆才会记录到.bash_history当中。最大的好处就是可以『查询曾经做过的举动!』 如此可以知道你的执行步骤,那么就可以追踪你曾下达过的指令,以作为除错的重要流程。但是也有可能被黑客利用。 
    命令与文件补全功能([tab]按键的好处)
    命令别名设定功能(alias)  alias vi=‘vim’
   工作控制、前景背景控制(job control, foreground, background)使用前、背景的控制可以让工作进行的更为顺利!至于工作控制(jobs)的用途则更广, 可以让我们随时将工作丢到背景中执行!而不怕不小心使用了[Ctrl] + c来停掉该程序!真是好样的!此外,也可以在单一登录的环境中,达到多任务的目的
    程序化脚本(shell scripts)Linux底下的shell scripts则发挥更为强大的功能,可以将你平时管理系统常需要下达的连续指令写成一个文件, 该文件并且可以透过对谈交互式的方式来进行主机的侦测工作。
    通配符(Wildcard)举例来说,想要知道 /usr/bin 底下有多少以X为开头的文件吗?使用:『ls -l /usr/bin/X*』就能够知道


type
利用 type 这个指令来观察某个指令是来自于外部指令(指的是其他非bash所提供的指令)还是内建在bash当中的呢?


Shell的变量功能
    什么是变量?变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数据。用一个简单的"字眼"来取代另一个比较复杂或者是容易变动的数据。就是类似于宏定义。
    变量的取用与设定:echo,变量设定规则, unset
    变数的取用: echo :可以利用echo这个指令来取用变量, 但是,变量在被取用时,前面必须要加上钱字号『$』才行 。

     如何『设定』或者是『修改』 某个变量的内容啊?很简单啦!用『等号(=)』连接变量与他的内容就好啦!举例来说: 我要将myname这个变量名称的内容设定为VBird  。


   bash当中,当一个变量名称尚未被设定时,预设的内容是『空』的。 另外变量在设定时,还是需要符合某些规定的,否则会设定失败
    1. 变量与变量内容以一个等号『=』来连结,如下所示:
myname=VBird
    2. 等号两边不能直接接空格符,如下所示为错误:
myname = VBird』或『myname=VBird Tsai
    3. 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:
2myname=VBird
    4. 变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但
  双引号内的特殊字符如 $等,可以保有原本的特性,如下所示:
var="lang is $LANG"』则『echo $var』可得『lang is zh_TW.UTF-8
  单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:
var='lang is $LANG'』则『echo $var』可得『lang is $LANG
    5. 可用跳脱字符『\将特殊符号([Enter], $, \,空格符, ')变成一般字符,如:
myname=VBird\ Tsai
    6. 在一串指令的执行中,还需要藉由其他额外的指令所提供的信息时,可以使用反单引号『`指令`』或 『$(指令)。特别注意,那个`是键盘上方的数字键1左边那个按键,而不是单引号! 例如想要取得核心版本的设定:
version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64
    7. 若该变量为扩增变量内容时,则可用"$变量名称"${变量}累加内容,如下所示:
PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin
    8. 若该变量需要在其他子程序执行,则需要以export来使变量变成环境变量
export PATH
    9. 通常大写字符为系统默认变量,自行设定变量可以使用小写字符,方便判断(纯粹依照使用者兴趣与嗜好)
    10. 取消变量的方法为使用unset:『unset变量名称』例如取消myname的设定:
unset myname


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


    1.先进行反单引号内的动作『uname -r』并得到核心版本为3.10.0-229.el7.x86_64
    2.
将上述的结果带入原指令,故得指令为:『 cd /lib/modules/3.10.0-229.el7.x86_64/kernel/


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

   HOME代表用户的家目录。有很多程序都可能会取用到这个变量的值!
    SHELL告知我们,目前这个环境使用的SHELL是哪支程序?Linux预设使用/bin/bash的啦
    HISTSIZE这个与『历史命令』有关, 我们曾经下达过的指令可以被系统记录下来,而记录的『笔数』则是由这个值来设定的。
    PATH就是执行文件搜寻的路径 。目录与目录中间以冒号(:)分隔
    RANDOM这个玩意儿就是『随机随机数』的变量,即/dev/random这个文件BASH的环境下,这个RANDOM变量的内容,介于0~32767之间,所以,你只要echo $RANDOM时,系统就会主动的随机取出一个介于0~32767的数值。万一我想要使用0~9之间的数值呢?利用declare宣告数值类型, 然后这样做就可以 。


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


    基本上,在Linux预设的情况中,使用{大写的字母}来设定的变量一般为系统内定需要的变量
   PS1(提示字符的设定)
    这是 PS1 (数字的1不是英文字母),这个东西就是我们的『命令提示字符』喔! 当我们每次按下[Enter]按键去执行某个指令后,最后要再次出现提示字符时, 就会主动去读取这个变数值了。上头PS1内显示的是一些特殊符号,这些特殊符号可以显示不同的信息, 每个distributionsbash默认的PS1变量内容可能有些许的差异,不要紧,『习惯你自己的习惯』就好了。 你可以用man bash (3)去查询一下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时,提示字符为#,否则就是$啰~


    $(关于本shellPID)
   钱字号本身也是个变量喔!这个咚咚代表的是『目前这个Shell的线程代号』,亦即是所谓的PID(Process ID)。 更多的程序观念,我们会在第四篇的时候提及。想要知道我们的shellPID,就可以用:『echo $$』即可!出现的数字就是你的PID号码。
?(关于上个执行指令的回传值)
    上一个执行的指令所回传的值』, 上面这句话的重点是『上一个指令』与『回传值』两个地方。当我们执行某些指令时, 这些指令都会回传一个执行后的代码。一般来说,如果成功的执行该指令,则会回传一个0,如果执行过程发生错误,就会回传『错误代码』才对

    OSTYPE, HOSTTYPE, MACHTYPE(主机硬件与核心的等级)
    export: 自定义变量转成环境变量
    env set现在知道有所谓的环境变量与自定义变量,那么这两者之间有啥差异呢?其实这两者的差异在于『该变量是否会被子程序所继续引用
    子程序仅会继承父程序的环境变量, 子程序不会继承父程序的自定义变量啦!所以你在原本bash的自定义变量在进入了子程序后就会消失不见,一直到你离开子程序并回到原本的父程序后,这个变量才会又出现!

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

    如果其他的语系变量都未设定, 且你有设定LANG或者是LC_ALL时,则其他的语系变量就会被这两个变量所取代。无论如何,如果发生一些乱码的问题,那么设定系统里面保有的语系编码, 例如:en_USen_US.utf8等等的设定,应该就OK的啦系统是列出目前Linux主机内保有的语系文件, 这些语系文件都放置在:/usr/lib/locale/这个目录中。
    你当然可以让每个使用者自己去调整自己喜好的语系,但是整体系统默认的语系定义在 /etc/locale.conf 当中。




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


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

    要读取来自键盘输入的变量,就是用read这个指令了。这个指令最常被用在shell script的撰写当中,想要跟使用者对谈?用这个指令就对了。底下先来瞧一瞧read的相关语法吧!


总结1:所以说在自定义变量时,如果想要在内容中添加空格(等特殊字符)有以下几种方法:

1、使用双引号或单引号空格括起来

2、使用反斜杠(\)跳脱特殊字符如单引号,空格等

3、使用read功能输入空格


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

    由于在默认的情况底下,bash对于变量有几个基本的定义:
变量类型默认为『字符串』,所以若不指定变量类型,则1+2为一个『字符串』而不是『计算式』。 所以上述第一个执行的结果才会出现那个情况的;bash环境中的数值运算,预设最多仅能到达整数形态,所以1/3结果是0

总结2:我们总想着在界面输入数学算式就给出结果但是实际上并不能。真正的做法是:1、如上所示,声明变量为int型,然后就能计算。2、就是利用bc这个linux带的计算器啦


数组(array)变量类型 

   bash里头,数组的设定方式是:
var[index]=content 


数组的变量类型比较有趣的地方在于『读取』,一般来说,建议直接以${数组}的方式来读取 

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

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

变量内容的删除与取代

上面这个范例很有趣的!他的重点可以用底下这张表格来说明:

    因为在PATH这个变量的内容中,每个目录都是以冒号『:』隔开的, 所以要从头删除掉目录就是介于斜线(/)到冒号(:)之间的数据!但是PATH中不止一个冒号(:)啊! 所以# ##就分别代表:
    # :符合取代文字的『最短的』那一个;
    ##:符合取代文字的『最长的』那一个 

如果想要『从后面向前删除变量内容』呢?

取代功能

总结

变量的测试与内容替换 

   在某些时刻我们常常需要『判断』某个变量是否存在,若变量存在则使用既有的设定,若变量不存在则给予一个常用的设定。
在上面的范例中,重点在于减号『-』后面接的关键词!基本上你可以这样理解:
username可能已经被设定为『空字符串』了!果真如此的话,那你还可以使用底下的范例来给予username的内容成为root 
    在大括号内有没有冒号『:』的差别是很大的!加上冒号后,被测试的变量未被设定或者是已被设定为空字符串时, 都能够用后面的内容(本例中是使用root为内容)来替换与设定 。

范例练习


命令别名与历史命令

命令别名设定:alias, unalias
    alias的定义规则与变量定义规则几乎相同

如果要取消命令别名的话,那么就使用unalias 
    命令别名是『新创一个新的指令, 你可以直接下达该指令』的,至于变量则需要使用类似『echo』指令才能够呼叫出变量的内容

历史命令:history
    如何查询我们曾经下达过的指令呢?就使用history

在正常的情况下,历史命令的读取与记录是这样的:
    当我们以bash登入Linux主机之后,系统会主动的由家目录的~/.bash_history读取以前曾经下过的指令,那么~/.bash_history会记录几笔数据呢?这就与你bashHISTFILESIZE这个变量设定值有关了!
    假设我这次登入主机后,共下达过100次指令,『等我注销时, 系统就会将101~1100这总共1000笔历史命令更新到~/.bash_history当中。』 也就是说,历史命令在我注销时,会将最近的HISTFILESIZE笔记录到我的纪录文件当中啦!
    当然,也可以用history -w强制立刻写入的!那为何用『更新』两个字呢? 因为~/.bash_history记录的笔数永远都是HISTFILESIZE那么多,旧的讯息会被主动的拿掉! 仅保留最新的!

history这个历史命令可以利用相关的功能来帮我们执行命令 

    同一账号同时多次登入的history写入问题。由于多重登入有这样的问题,所以很多朋友都习惯单一bash登入,再用工作控制 来切换不同工作! 这样才能够将所有曾经下达过的指令记录下来,也才方便未来系统管理员进行指令的debug 。

Bash Shell的操作环境:

路径与指令搜寻顺序 


    如果一个指令(例如ls)被下达时, 到底是哪一个ls被拿来运作? 我们可以来看一下指令的运作顺序

    1.以相对/绝对路径执行指令,例如『/bin/ls』或『./ls』;
    2. alias找到该指令来执行;
    3. bash内建的(builtin)指令来执行;
    4. 透过 $PATH这个变量的顺序搜寻到的第一个指令来执行。

设定echo的命令别名为echo -n,然后再观察echo执行的顺序

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

在终端机接口 (tty1 ~ tty6)登入的时候,会有几行提示的字符串 。那就是进站画面!那些字符在/etc/issue里面啊

如何来编辑修改这个东西做出我们自己喜欢的画面呢?可以看看下面各代码的含义进行自主的添加



    你要注意的是,除了 /etc/issue之外还有个/etc/issue.net呢!这是啥?这个是提供给telnet这个远程登录程序用的。 当我们使用telnet连接到主机时,主机的登入画面就会显示/etc/issue.net而不是/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才会读) 

   这个配置文件可以利用使用者的标识符(UID)来决定很多重要的变量数据, 这也是每个使用者登入取得bash时一定会读取的配置文件
    这个文件设定的变量主要有:
PATH:会依据UID决定PATH变量要不要含有sbin的系统指令目录;
MAIL:依据账号设定好使用者的mailbox/var/spool/mail/账号名;
USER:根据用户的账号设定此一变量内容;
HOSTNAME:依据主机的hostname指令决定此一变量内容;
HISTSIZE:历史命令记录笔数。CentOS 7.x设定为1000;(通过set或者env指令也可以查看系统设定)
umask:包括root默认为022而一般用户为002等!
/etc/profile 可不止会做这些事而已,他还会去呼叫外部的设定数据喔!
/etc/profile.d/*.sh
其实这是个目录内的众多文件!只要在 /etc/profile.d/这个目录内且扩展名为.sh,另外,使用者能够具有r的权限, 那么该文件就会被/etc/profile呼叫进来。
/etc/locale.conf
这个文件是由 /etc/profile.d/lang.sh呼叫进来的!这也是我们决定bash预设使用何种语系的重要配置文件! 
/usr/share/bash-completion/completions/*
记得我们上头谈过 [tab]的妙用吧?除了命令补齐、档名补齐之外,还可以进行指令的选项/参数补齐功能!那就是从这个目录里面找到相对应的指令来处理的! 其实这个目录底下的内容是由/etc/profile.d/bash_completion.sh这个文件载入的啦!
~/.bash_profile (login shell才会读)
bash 在读完了整体环境设定的/etc/profile并藉此呼叫其他配置文件后,接下来则是会读取使用者的个人配置文件。 在login shell bash环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:
1. ~/.bash_profile
2. ~/.bash_login
3. ~/.profile

    其实 bashlogin shell设定只会读取上面三个文件的其中一个, 而读取的顺序则是依照上面的顺序。也就是说,如果~/.bash_profile存在,那么其他两个文件不论有无存在,都不会被读取。


    这个文件内有设定PATH这个变量喔!而且还使用了exportPATH变成环境变量呢! 由于PATH/etc/profile当中已经设定过,所以在这里就以累加的方式增加用户家目录下的~/bin/为额外的执行文件放置目录。这也就是说,你可以将自己建立的执行档放置到你自己家目录下的~/bin/目录啦! 那就可以直接执行该执行档而不需要使用绝对/相对路径来执行该文件。

    最后,我们来看看整个 login shell的读取流程: 

实线的的方向是主线流程,虚线的方向则是被呼叫的配置文件!


source:读入环境配置文件的指令
    由于/etc/profile~/.bash_profile都是在取得login shell的时候才会读取的配置文件,所以, 如果你将自己的偏好设定写入上述的文件后,通常都是得注销再登入后,该设定才会生效。 如果想直接读取配置文件而不注销登入,那就得要利用source这个指令了!


~/.bashrc (non-login shell会读)
    当你取得non-login shell时,该bash配置文件仅会读取~/.bashrc而已啦!那么预设的~/.bashrc内容是如何? 

    特别注意一下,由于root的身份与一般使用者不同,鸟哥是以root的身份取得上述的数据, 如果是一般使用者的~/.bashrc会有些许不同。看一下,你会发现在root~/.bashrc中其实已经规范了较为保险的命令别名了。 此外,咱们的CentOS 7.x还会主动的呼叫/etc/bashrc这个文件喔!为什么需要呼叫/etc/bashrc呢? 因为/etc/bashrc帮我们的bash定义出底下的数据:
    依据不同的UID规范出umask的值;
    依据不同的UID规范出提示字符(就是PS1变量)
    呼叫/etc/profile.d/*.sh的设定

    事实上还有一些配置文件可能会影响到你的 bash操作的,

/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 (setting tty 终端机的意思)呢!stty也可以帮助设定终端机的输入按键代表意义。

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

set还可以帮我们设定整个指令输出/输入的环境。 例如记录历史命令、显示错误内容等等。 

通配符与特殊符号

特殊符号

数据流重导向

    数据流重导向就是将某个指令执行后应该要出现在屏幕上的数据, 给他传输到其他的地方,例如文件或者是装置(例如打印机之类的)
    指令执行过程中的数据传输情况


standard outputstandard error output 

    标准输出指的是『指令执行所回传的正确的讯息』,而标准错误输出可理解为『指令执行失败后,所回传的错误讯息』
    数据流重导向可以将standard output(简称stdout)standard error output (简称stderr)分别传送到其他的文件或装置去,而分别传送所用的特殊字符则如下所示: 

1.标准输入(stdin):代码为0,使用<<<
2. 标准输出 (stdout):代码为1,使用>>>
3. 标准错误输出(stderr):代码为2,使用2>2>>
1.该文件(本例中是~/rootfile)若不存在,系统会自动的将他建立起来,但是
2. 当这个文件存在的时候,那么系统就会先将这个文件内容清空,然后再将数据写入!
3. 也就是若以 >输出到一个已存在的文件中,那个文件就会被覆盖掉啰!
    如果我想要将数据累加而不想要将旧的数据删除,那该如何是好?利用两个大于的符号 (>>)就好啦!以上面的范例来说,你应该要改成『ll / >> ~/rootfile』即可。

1> :以覆盖的方法将『正确的数据』输出到指定的文件或装置上;
1>>:以累加的方法将『正确的数据』输出到指定的文件或装置上;
2> :以覆盖的方法将『错误的数据』输出到指定的文件或装置上;
2>>:以累加的方法将『错误的数据』输出到指定的文件或装置上;



    注意喔,此时『屏幕上不会出现任何讯息』!因为刚刚执行的结果中,有Permission的那几行错误信息都会跑到list_error这个文件中,至于正确的输出数据则会存到list_right这个文件中

/dev/null垃圾桶黑洞装置与特殊写法

    如果我知道错误讯息会发生,那么如何要将错误讯息忽略掉而不显示或储存呢?,这个/dev/null可以吃掉任何导向这个装置的信息。我们一以上面范例为例。



再想象一下,如果我要将正确与错误数据通通写入同一个文件去呢?

    上述表格第一行错误的原因是,由于两股数据同时写入一个文件,又没有使用特殊的语法, 此时两股数据可能会交叉写入该文件内,造成次序的错乱

standard input< <<
将原本需要由键盘输入的数据,改由文件内容来取代 (这个东西可以和read做对比,read是实现通过键盘输入的功能)


    由于加入>cat后,所以那个catfile会被主动的建立,而内容就是刚刚键盘上面输入的那两行数据了。 

总结3:这样看来,不仅我们之前学的nano、vi可以用来建立新文件,用cat也可以建立新文件,在要求不高的情况下,cat等编辑方式更加简单呢。

    唔!那我能不能用纯文本文件取代键盘的输入,也就是说,用某个文件的内容来取代键盘的敲击呢?可以的!如下所示:

总结4:刚才cat刚抢了nano与vi的饭碗,没想到是cat又与cp有了“冲突”,真是多才多艺的cat呀。不要忘记cat的本来功能哟

    <<代表的是『结束的输入字符』的意思!举例来讲:『我要用cat直接将输入的讯息输出到catfile中, 且当由键盘输入eof 时,该次输入就结束』,那我可以这样做:

使用命令进行输出重导向的原因:

屏幕输出的信息很重要,而且我们需要将他存下来的时候;
背景执行中的程序,不希望他干扰屏幕正常的输出结果时;
一些系统的例行命令 (例如写在/etc/crontab中的文件)的执行结果,希望他可以存下来时;
一些执行命令的可能已知错误讯息时,想以『2> /dev/null』将他丢掉时;
错误讯息与正确讯息需要分别输出时。

命令执行的判断依据:; , &&, ||
    cmd ; cmd (不考虑指令相关性的连续指令下达) 



    Linux底下的指令都是由左往右执行

    Linux 底下的指令都是由左往右执行,整条指令的执行流程如下所示。Linux 底下的指令都是由左往右执行 上方的线段为不存在/tmp/abc时所进行的指令行为,下方的线段则是存在/tmp/abc所在的指令行为。


    Linux 底下的指令都是由左往右执行 由于指令是一个接着一个去执行的,因此,如果真要使用判断,那么这个&&||的顺序就不能搞错。一般来说,假设判断式有三个,也就是:command1 && command2 || command3


管线命令 (pipe) 

   管线命令『|』仅能处理经由前面一个指令传来的正确信息,也就是standard output的信息,对于stdandard error并没有直接处理的能力 

    在每个管线后面接的第一个数据必定是『指令』喔!而且这个指令必须要能够接受standard input的数据才行,这样的指令才可以是为『管线命令』,例如less, more, head, tail等都是可以接受standardinput的管线命令啦。至于例如ls, cp, mv等就不是管线命令了!因为ls, cp, mv并不会接受来自stdin的数据。 也就是说,管线命令主要有两个比较需要注意的地方:
    管线命令仅会处理standard output,对于standard error output 会予以忽略
    管线命令必须要能够接受来自前一个指令的数据成为standard input继续处理才行。

    想一想,如果你硬要让 standard error可以被管线命令所使用。其实就是透过上一小节的数据流重导向即可! 让2>&1加入指令中~就可以让2> 变成 1>啰!
 
撷取命令:cut, grep 
    撷取讯息通常是针对『一行一行』来分析的, 
    cut主要的用途在于将『同一行里面的数据进行分解!』最常使用在分析一些数据或文字数据的时候!不过,cut 在处理多空格相连的数据时,可能会比较吃力一点,所以某些时刻可能会使用 awk来取代的! 


排序命令:sort, wc, uniq

    sort是很有趣的指令,他可以帮我们进行排序,而且可以依据不同的数据型态来排序喔!


uniq
    如果我排序完成了,想要将重复的资料仅列出一个显示,可以怎么做呢?

    这个指令用来将『重复的行删除掉只显示一个』,举个例子来说, 你要知道这个月份登入你主机的用户有谁,而不在乎他的登入次数,那么就使用上面的范例,(1)先将所有的数据列出;(2)再将人名独立出来;(3)经过排序;(4)只显示一个! 由于这个指令是在将重复的东西减少,所以当然需要『配合排序过的文件』来处理啰!

wc
    如果我想要知道/etc/man_db.conf这个文件里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以利用wc这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!

双向重导向:tee 
   万一我想要将这个数据流的处理过程中将某段讯息存下来,应该怎么做? 利用tee就可以啰
   tee可以让standard output转存一份到文件内并将同样的数据继续送到屏幕去处理!

字符转换命令:tr, col, join, paste, expand
tr
    tr 可以用来删除一段讯息当中的文字,或者是进行文字讯息的替换!

col

join
    此外,需要特别注意的是,在使用join之前,你所需要处理的文件应该要事先经过排序(sort) 处理!否则有些比对的项目会被略过呢!特别注意了! 

paste
    这个 paste 就要比join简单多了!相对于 join 必须要比对两个文件的数据相关性, paste 就直接『 将两行贴在一起,且中间以[tab]键隔开』而已

expand
    这玩意儿就是在将 [tab]按键转成空格键啦~可以这样玩:

分区命令:split
    如果你有文件太大,导致一些携带式装置无法复制的问题,嘿嘿!找 split就对了他可以帮你将一个大文件,依据文件大小或行数来分区。

参数代换:xargs
    xargs 是在做什么的呢?就以字面上的意义来看,x是加减乘除的乘号, args 则是 arguments (参数)的意思,所以说,这个玩意儿就是在产生某个指令的参数的意思xargs可以读入 stdin的数据,并且以空格符或断行字符作为分辨,将stdin的资料分隔成为 arguments。 因为是以空格符作为分隔,所以,如果有一些档名或者是其他意义的名词内含有空格符的时候,xargs 可能就会误判了。
    在man xargs里面就有三四个小范例,您可以自行参考一下内容。 此外,xargs真的是很好用的一个玩意儿!您真的需要好好的参详参详!会使用xargs的原因是, 很多指令其实并不支持管线命令,因此我们可以透过xargs 来提供该指令引用standard input之用!举例来说,我们使用如下的范例来说明: 



    管线命令在bash的连续的处理程序中是相当重要的!另外,在log file的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个指令的stdout作为这次的stdin, 某些指令需要用到文件名(例如tar)来进行处理时,该 stdin stdout可以利用减号"-"来替代, 举例来说:
    上面这个例子是说:『我将/home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到stdout; 经过管线后,将tar -cvf - /home传送给后面的tar -xvf - 』。后面的这个- 则是取用前一个指令的stdout, 因此,我们就不需要使用filename 了!这是很常见的例子喔!注意注意!

1 0
原创粉丝点击