天天看点

10-认识与学习BASH

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1

Welcome to my github: https://github.com/gaoxiangnumber1

10.1认识 BASH这个Shell

10.1.1硬件、核心与 Shell

10.1.2为何要学文字接口的 shell?

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

  • Linux使用Bourne Again Shell,简称bash。/bin/bash是Linux默认的shell。

10.1.4 Bash shell 的功能

  • 记忆命令。

    ~/.bash_history

    记录本次登入前执行的指令,本次登入执行的指令暂存在内存;当成功注销后,本次的指令才会记录到.bash_history。按上下键就能找到前/后一个输入的指令。
  • tab命令/文件补全。

    [Tab]接在指令第一个字后时,为命令补全;

    [Tab]接在指令第二个字后时,为文件补齐。

  • 设定命令别名alias。输入

    alias

    得到目前设定的命令别名。
  • 工作job control、前景foreground、背景background控制。
  • 脚本shell scripts。
  • 通配符Wildcard。

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

  • 外部指令指。
type [-tpa] name           
  • 不加任何东西,显示name是外部指令(非bash提供)还是内建指令

    -t 显示以下形式:

    file

    为外部指令;

    alias

    表示该指令为命令别名设定的名称;

    builtin

    为内建指令

    -p 后接外部指令时显示完整文件名

    -a 列出所有在PATH定义的路径中、含name的指令,包含alias

  • 若type后接非程序,则not found。
xiang :~ $ type cd
cd is a shell builtin
xiang :~ $ type ps
ps is /bin/ps
xiang :~ $ type -t ps
file
xiang :~ $ type -p ps
/bin/ps
xiang :~ $ type -a ps
ps is /bin/ps
xiang :~ $ type xiang
bash: type: xiang: not found           

10.1.6 指令的下达与快速编辑按钮

  • \

    跳脱下一个紧接字符。指令太长用

    \[Enter]

    来将

    [Enter]

    键跳脱。

    组合键 功能

    Ctrl+u 从光标处向前删除指令串

    Ctrl+k 从光标处向后删除指令串

    Ctrl+a 让光标移动到整个指令串的最前面

    Ctrl+e 让光标移动到整个指令串的最后面

10.2 Shell的变量功能

10.2.1 什么是变量

  • 变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数据。

10.2.2 变量的读取与设定:echo,变量设定规则,unset

变量的读取echo

  • echo $变量

    echo ${变量}

    读取变量。
xiang :~ $ echo $HOME
/home/xiang
xiang :~ $ echo ${HOME}
/home/xiang           
  • =

    连接变量与对应内容来设定/修改变量。
xiang :~ $ echo $name #变量未被设定时,默认内容为空

xiang :~ $ name=xiang_gao
xiang :~ $ echo $name
xiang_gao           

变量的设定规则

  1. 变量与变量内容用

    =

    连接:

    name=xiang

  2. 等号两边不能直接接空格,错误:

    name = xiang

    name=xiang gao

  3. 变量名只能包含英文字母、数字,开头只能为字母。
  4. 变量内容若有空格可使用双引号

    "

    或单引号

    '

    将变量内容结合起来,但

    1.双引号内的特殊字符保留特性。

xiang :~ $ home="home is $HOME"
xiang :~ $ echo $home
home is /home/xiang           

2.单引号内的特殊字符不保留特性。

xiang :~ $ home="home is $HOME"
xiang :~ $ echo $home
home is $HOME           
  1. \

    将特殊符号(Enter、$、\、空格等)变成一般字符:

    name=xiang\ gao

  2. 指令

    ”或

    $(指令)

    的指令先执行,其执行结果将做为外部的输入信息。
xiang :~ $ version=$(uname -r)
xiang :~ $ echo $version
3.16.0-76-generic
xiang :~ $ content=`ls`
xiang :~ $ echo $content
Codes Desktop Gao           
  1. "$变量"

    ${变量}

    累加内容:

    PATH="$PATH":/home/bin

    PATH=${PATH}:/home/bin

  2. 父程序的自定义变量默认无法在子程序内使用,

    export 变量

    成为环境变量,则该变量可在子程序使用:

    export name

  3. 通常大写为系统默认变量,自行设定变量使用小写字符。
  4. unset 变量

    取消变量的设定:

    unset name

xiang:~ $ name=xiang's name       #失败。单/双引号必须成对。仅有一个单引号,
>                               #按下enter后,还可继续输入变量内容。
xiang:~ $ name="xiang's name" #成功。指令由左向右,先遇到的引号先有用,
                                #该单引号变成一般字符。
xiang:~ $ name='xiang's name' #失败。前两个单引号成对,后面多一个单引号。
xiang:~ $ name=xiang\'s\ name #成功。用\跳脱特殊字符。           
xiang:~ $ name=xiang
xiang:~ $ bash            #进入子程序
xiang:~ $ echo $name #子程序echo。没有设定的内容。

xiang:~ $ exit            #退出子程序
xiang:~ $ export name
xiang:~ $ bash            #进入子程序
xiang:~ $ echo $name #子程序echo
xiang                   #出现设定值
xiang:~ $ exit            #退出这个子程序           
#进入核心的模块目录
xiang:~ $ cd /lib/modules/`uname -r`/kernel
xiang:~ $ cd /lib/modules/$(uname -r)/kernel           
#得到每个example相关档名的权限
xiang:~ $ ls -ld `locate example`
xiang:~ $ ls -ld $(locate example)           

10.2.3环境变量的功能

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

  • env

    列出目前shell环境下所有环境变量与其内容。重要的:

    HOME 用户的家目录。

    SHELL 代表目前使用的SHELL是哪个程序。Linux默认使用/bin/bash。

    HISTSIZE 历史指令记录的条数。

    PATH 执行文件搜索的路径。目录间以

    :

    分隔。

    LANG 语系数据。

    RANDOM 通过

    $RANDOM

    得到随机数值,介于0~32767。

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

  • set列出bash内的所有变量:环境变量、与bash操作接口有关的变量、用户自定义变量。重要的:

    BASH bash主程序存放路径

    HISTFILE 记录历史命令的文件

    fileIZE 存起来的文件的指令的最大纪录条数

    HISTSIZE 目前环境下,内存中记录的历史命令最大条数。

    MACHTYPE 安装的机器类型

    OSTYPE 操作系统类型

    PS1 命令提示符,即

    [email protected] ~#

    xiang ~$

    的设定值

    PS2 使用跳脱符号\第二行以后的提示字符

    $ 目前shell的PID

    ? 刚执行完指令的返回值

PS1:提示字符的设定(数字1不是英文字母)

  • 每次按Enter执行指令后,再次出现提示字符时,读取该变量。PS1内的特殊意义:

    符号 显示

    \d

    星期 月 日

    \H 完整的主机名

    \h 主机名在第一个小数点前的名字

    \t 时间,24小时格式的HH:MM:SS

    \T 时间,12小时格式的HH:MM:SS

    \A 时间,24小时格式的HH:MM

    \@ 时间,12小时格式的am/pm

    \u 目前用户的账号名称

    \v BASH版本

    \w 由根目录写起的完整工作目录名称。家目录以

    ~

    取代

    \W 最后一个目录名。

    # 下达的第几个指令。

    $ 提示字符:root为#,否则为$

$:本shell的PID

  • echo $$

    得到shell的PID。

?:上个指令执行的返回值

  • 指令执行成功返回0,否则返回非0的错误代码。
xiang :~ $ echo $HOME
/home/xiang
xiang :~ $ echo $?
0
xiang :~ $ 12name=xiang
12name=xiang: command not found
xiang :~ $ echo $?
127
xiang :~ $ echo $?
0                   #上个指令执行`echo $?`,没有错误,所以是0           

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

  • 子程序仅继承父程序的环境变量。

    export 变量

    让自定义变量在子程序中使用。

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

10.2.5变量的有效范围

  • 环境变量=全局变量;自定义变量=局部变量

    为什么环境变量可被子程序引用:启动shell后,操作系统会分配一段内存给shell使用,此内存内的变量可让子程序读取。父程序利用export将自定义变量写到该内存中;当加载另一个shell时(即启动子程序,退出父程序),子shell可以将父shell环境变量所在的内存块导入自己的环境变量区块中。

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

read

read [-pt] variable           
  • 不加任何参数,只加变量名,会出现一个空白行等待输入。

    -p 后接提示字符。

    -t 后接等待的秒数。如果超时,该指令自动略过。

xiang :~ $ read name
gao xiang
xiang :~ $ echo $name
gao xiang
xiang :~ $ read -p "Please input your name:" -t 10 name 
Please input your name:gao xiang number one
xiang :~ $ echo $name
gao xiang number one
xiang :~ $ read -p "Please input your name:" -t 10 name 
Please input your name:xiang :~ $            

declare/typeset

declare [-aixr] variable           
  • -a 将variable定义成数组array类型

    -i 将variable定义成整数integer类型

    -x 将variable变成环境变量

    -r 将variable设定成read-only:不可被改变内容,也不能unset

xiang:~ $ sum=100+300+50
xiang:~ $ echo ${sum}
100+300+50              #没有计算,因为这是文字形式的变量
xiang:~ $ declare -i sum=100+300+50
xiang:~ $ echo ${sum}
450           
    1. 变量类型默认为字符串。
    2. bash中的数值运算,最多仅能达到整数,1/3结果是0。
xiang:~ $ declare -x sum      #将sum变成环境变量
xiang:~ $ export | grep sum
declare -ix sum="450"
xiang:~ $ declare -r sum      #让sum变成只读
xiang:~ $ sum=other
-bash:sum:read-only variable
#让sum变成非环境变量的自定义变量
xiang:~ $ declare +x sum      #将-变成+进行取消
xiang:~ $ declare -p sum      #-p单独列出变量类型
declare -ir sum="450"       #只剩i、r类型,不具有x           

数组array变量类型

  • bash设定数组的方式:

    var[index]=content

    var为数组名。
xiang :~ $ var[1]="gao"
xiang :~ $ var[2]="xiang"
xiang :~ $ var[3]="number one"
xiang :~ $ echo $var[1] $var[2] $var[3]
[1] [2] [3]
xiang :~ $ echo "${var[1]} ${var[2]} is ${var[3]}" #使用${数组}读取
gao xiang is number one
xiang :~ $ echo "${var[1]} ${var[2]} is ${var[3]}!"
gao xiang is number one!
xiang :~ $ echo ${var[1]} ${var[2]} is ${var[3]}!
gao xiang is number one!           

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

ulimit [-SHacdfltu] [配额]           
  • -H hard limit不能超过该设定值

    -S soft limit可以超过该设定值,若超过有警告

    -a 后面不接任何东西,列出所有的限制额度

    -c 当程序出错时,系统会将该程序在内存中的信息写成core file。此为每个核心文件的最大容量。

    -f 此shell可以建立的最大文件容量,单位为KB

    -d 程序可用的最大segment内存容量

    -l 可用于锁定lock的内存容量

    -t 可用的最大CPU时间,单位为秒

    -u 单一用户可用的最大process数量

xiang :~ $ ulimit -a
core file size          (blocks, -c) 0#0代表没限制
file size               (blocks, -f) unlimited
pending signals                 (-i) 31348
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31348
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited           
  • 一般身份若用

    ulimit -f

    设定文件大小,那么它只能继续减小容量,不能增加容量。

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

10.3命令别名与历史命令

10.3.1 命令别名设定:alias,unalias

  • alias {别名='指令 选项...' }

    输入

    alias

    得到目前的命令别名。
  • unalias取消命令别名。

10.3.2 历史命令history

history [n]
history [-c]
history [-raw] file           
  • 列出目前所有history内容

    n 列出最近n条指令

    -c 将目前shell所有的history内容消除

    -a 将目前新增的history指令写入file;若没有加file,默认写入~/.bash_history

    -r 将file内容读到目前shell的history中

    -w 将目前history的内容写入file

  • 用bash登入主机后,系统会自动从~/.bash_history(记录HISTFILESIZE条数据)读取历史指令。系统在注销时将最近HISTFILESIZE条指令记录至~/.bash_history(旧指令会被删除)。
!number     执行第number条指令
!command    由最近的指令向前搜寻指令串开头为command的指令并执行
!!          执行上一个指令           

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

  • 如果在多个bash都已同一身份登入,所有的bash都有自己的X条记录在内存中。因为等到注销时才会更新记录文件,所以最后注销的bash才是最后写入的数据。

10.4 Bash Shell的操作环境

10.4.1路径与指令搜索顺序

  • 指令运行的顺序:
    1. 执行相对/绝对路径指令。
    2. 执行alias找到的指令。
    3. 执行bash内建指令。
    4. 执行顺序搜索$PATH到的第一个指令。

10.4.2 bash进站与欢迎信息:/etc/issue、/etc/motd

  • 从终端机接口(tty1-tty6)登入时提示的字符串在/etc/issue中。
xiang :~ $ cat /etc/issue
Ubuntu 14.04.3 LTS \n \l
           
  • issue内各代码意义

    \d 本地时间的日期

    \l 第几个终端机接口

    \m 硬件类别

    \n 主机的网络名称

    \O domain name

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

    \t 本地时间

    \S 操作系统名称

    \v 操作系统版本

  • /etc/issue.net供telnet远程登录程序用。当我们用telnet连接主机时,主机的登入画面会显示/etc/issue.net而不是/etc/issue。
  • 用户登入后自动得到的信息在/etc/motd中。如:登入后,告诉登入者,系统将会在某个固定时间进行维护工作(一定要用root身份才能修改):
root:~ # vim /etc/motd
Hello everyone,
Our server will be maintained at 2015/07/10 0:00 ~ 24:00.
Please don't login server at that time. ^_^           
  • 当用户(所有一般账号与root)登入主机后,就会显示:
Last login:Wed Jul 8 23:22:25 2015 from 127.0.0.1
Hello everyone,
Our server will be maintained at 2015/07/10 0:00 ~ 24:00.
Please don't login server at that time. ^_^           

10.4.3 bash的环境配置文件

  • bash在启动时读取环境配置文件来设置操作环境。配置文件分为系统配置文件及用户个人配置文件。

login与non-login shell

  • login shell:取得bash需要完整的登入流程,如从tty1-tty6登入。
  • non-login shell:取得bash不需要登入。

    (1)以X window登入Linux后,再以X图形化接口启动终端机,此时终端接口不需要再次输入账号密码。

    (2)在bash下再次下达bash指令,同样不需要输入账号密码。

  • login shell读取两个配置文件:
    1. /etc/profile。这是系统整体的设定,最好不要修改。
    2. ~/.bash_profile或~/.bash_login或~/.profile。这是用户个人设定,可以改。

/etc/profile(login shell才会读)

  • 每个用户登入bash时一定会读取该文件。该文件设定的变量主要有:

    PATH 根据UID决定PATH是否含有sbin(系统指令目录)

    USER 根据用户账号设定此变量内容

    HOSTNAME 根据主机的hostname指令设定此变量内容

    HISTSIZE 历史命令记录条数

    umask root默认022;一般用户002

  • login shell读取的整体环境配置文件只有/etc/profile,但/etc/profile会呼叫其它的配置文件(/etc/profile.d/*.sh、/etc/locale.conf等等)。

~/.bash_profile(login shell才会读)

  • bash读完系统配置文件/etc/profile并通过此呼叫其它配置文件后,读取用户的个人配置文件。login shell按照下面的顺序读取三个个人配置文件(~/.bash_profile、~/.bash_login、~/.profile)中的一个,前面的文件不存在才读取后一个文件。
xiang :~ $ cat .profile
# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then #判断~/.bashrc是否存在,若存在则读入~/.bashrc
    . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH" #处理个人化设定
fi
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_77           
  • PATH在/etc/profile中已设定,这里增加用户的~/bin/。所以将程序存放到~/bin/后,就可以直接执行该程序而不需要用绝对/相对路径。
  • login shell的读取流程。实线方向是主线流程,虚线方向是被呼叫的配置文件。
10-认识与学习BASH

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

  • 因为/etc/profile与~/.bash_profile都是在取得login shell时读取配置文件,所以若将偏好设定写入上述文件后,需要注销再登入,该设定才会生效。

    source

    .

    指令能直接读取配置文件而不注销登入。
source或.    配置文件档名

#实例:将~/.bashrc的设定读入目前的bash环境中。
xiang:~ $ source ~/.bashrc
xiang:~ $ . ~/.bashrc           

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

  • 取得non-login shell时,bash只读取~/.bashrc。

其它相关配置文件

  • file 设定使用man时man page的搜索路径

    ~/.bash_history 默认记录历史命令的文件

    ~/.bash_logout 记录注销bash后,系统再做完什么动作后才退出。可以将备份或其它重要的工作写在该文件中

10.4.4终端机环境设定:stty,set

stty [-a]           
  • -a 将目前所有stty参数列出
xiang :~ $ stty -a
speed 38400 baud; rows 12; columns 92; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O;
min = 1; time = 0;
...           
  • ^表示Ctrl键。

    intr 发送一个interrupt信号给目前正在run的程序

    quit 发送一个quit信号给目前正在run的程序

    erase 向后删除字符

    kill 删除目前指令列上的所有文字

    eof 即End of file,代表结束输入

    start 在某个程序停止后,重新启动它的output

    stop 停止目前屏幕的输出

    susp 发送一个terminal stop信号给正在run的程序

  • stty erase ^h

    用Ctrl+h进行字符删除,按下backspace则会出现^?。

    stty erase ^?

    恢复使用backspace。
**set [-uvCHhmBx]**
           
  • -u 默认不使用。若使用,当使用未设定的变量时,会显示错误信息

    -v 默认不使用。若使用,输出信息前先显示信息的原始内容

    -x 默认不使用。若使用,执行指令前显示指令内容(前有++符号)

    -C 默认不使用。若使用>等,则若文件存在时,该文件不会被覆盖。

    -h 默认使用。与历史命令有关

    -H 默认使用。与历史命令有关

    -m 默认使用。与工作管理有关

    -B 默认使用。与[]的作用有关

xiang:~ $ echo $-#显示目前所有set设定值。变量`$-`的内容是set的所有设定。
himBH#bash默认是himBH

#未设定的变量默认为空;设定`-u`后使用未设定的变量时报错。
#`set+u`取消这个设定。
xiang:~ $ set -u
xiang:~ $ echo $xiang
-bash:xiang:unbound variable           
  • bash默认组合键:

    Ctrl + C 终止目前命令

    Ctrl + D EOF输入结束

    Ctrl + M Enter

    Ctrl + S 暂停屏幕输出

    Ctrl + Q 恢复屏幕输出

    Ctrl + U 在提示字符下,将整列命令删除

    Ctrl + Z 暂停目前命令

10.4.5通配符与特殊符号

    • 代表0到无穷多个任意字符

      ? 代表一定有一个任意字符

      [] 代表一定有一个在括号内的字符。[abc]代表一定有一个为a或b或c的字符

      [-] 有

      -

      代表在编码顺序内的所有字符。[0-9]代表0到9之间的所有数字。

      [^] []内第一个字符为

      ^

      表示反向选择。[^abc]代表一定有一个字符不是a/b/c
#找出/etc/下五个字母的文件名,`?`代表一定有一个
xiang:~ $ ll -d /etc/?????
#找出/etc/下含有数字的文件名。中括号左右两边均需`*`
xiang:~ $ ll -d /etc/*[0-9]*
#找出/etc/下档名开头不是小写字母的文件名。中括号左边没有`*`
xiang:~ $ ll -d /etc/[^a-z]* #注意
#将上例找到的文件复制到/tmp/upper
xiang:~ $ mkdir /tmp/upper; cp -a /etc/[^a-z]* /tmp/upper           
  • bash的特殊符号:

    井号 后跟注释,其后的数据均不执行

    \ 跳脱符号:将特殊字符或通配符还原成一般字符

    | 管线pipe:分隔两个管线命令

    ; 分隔连续指令

    ~ 用户家目录

    $ 读取变量前导符

    & 工作控制job control,将指令变成背景工作

    ! 逻辑运算的not

    / 路径分隔的符号

    >, >> 数据流输出导向:取代,累加

    <, << 数据流输入导向

    ” 单引号,无变量置换功能( 变为纯文本)“”有变量置换功能( 保留相关功能)

    “ 两个符号中间为先执行的指令,也可使用$()

    () 在中间为子shell的起始与结束

    {} 在中间为命令区块的组合

10.5数据流重导向

10.5.1 什么是数据流重导向

10-认识与学习BASH

standard output与 standard error output

  • 标准输出指指令执行返回的正确信息,标准错误输出为指令执行失败返回的错误信息。数据流重导向将指令执行后应输出在屏幕上的数据传输到其它地方。
    1. 标准输入stdin:代码0,使用<或<<
    2. 标准输出stdout:代码1,使用>或>>
    3. 标准错误输出stderr:代码2,使用2>或2>>
#一:观察你的系统根目录(/) 下各目录的文件名、权限与属性,并记录下来
xiang:~ $ ll / #此时屏幕会显示出文件名信息
xiang:~ $ ll / > ~/file #屏幕并无任何信息
xiang:~ $ ll ~/file #有个新档被建立了。
-rw-rw-r--. 1 xiang xiang 1078 Jul 9 18:51 /home/xiang/file           
  • >

    2>

    写入文件的建立方式:
    1. 若不存在,系统自动建立。
    2. 若存在时,系统先将该文件清空,然后再将数据写入。

      >>

      2>>

      写入文件的建立方式:
    3. 若不存在,系统自动建立。
    4. 若存在时,数据会从文件结尾处累加。

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

  • /dev/null删除任何导向其的信息。
>file1 2>file2  #将stdout与stderr存入不同文件
#将stdout与stderr均写入文件list
>list 2>list        #错误
>list 2>&1      #正确
&> list         #正确           
  • >list 2>list

    错误原因:两组数据同时写入一个文件,数据可能会交叉,造成次序错乱。虽然list文件包含所有stdout、stderr的输出,但是数据排列不是原屏幕的输出顺序。

    使用特殊语法

    2>&1

    &>

standard input<与<<

  • <

    将原来由键盘输入的数据改为文件内容。
xiang :~ $ cat > hello.c
#include<stdio.h>

int main()
{
    printf("hello world\n");
}#按Ctrl+d退出
xiang :~ $ cat hello.c 
#include<stdio.h>

int main()
{
    printf("hello world\n");
}
xiang :~ $ gcc hello.c 
xiang :~ $ ./a.out 
hello world

xiang :~ $ cat > hello2.c < hello.c #用stdin取代键盘输入建立新文件
xiang :~ $ ll hello*
-rw-rw-r-- 1 xiang xiang    60  10月 12 19:59 hello2.c
-rw-rw-r-- 1 xiang xiang    60  10月 12 19:57 hello.c    #大小一样           
  • <<代表结束的输入字符。
xiang :~ $ cat > eof << "eof"
> i am gaoxiang
> life is competition!
> eof #输入关键词立刻结束,不需要输入Ctrl+d
xiang :~ $ cat eof 
i am gaoxiang
life is competition! #只有两行,无关键词那行           
  • 2>&1

    2>

    转到

    1>

    1>&2

    反之。
#将`echo "error message"`以stderr格式输出
xiang:~ $ echo "error message" 1>&2               #输出到屏幕
xiang:~ $ echo "error message" 2> /dev/null 1>&2  #屏幕没有信息           

10.5.2 命令执行的判断根据:; ,&&,||

不考虑指令相关性的连续指令下达cmd;cmd

  • 指令与指令间用

    ;

    隔开,分号前的指令执行完后立刻执行后面的指令。

指令返回值$?与&&或||

  • cmd1 && cmd2

    若cmd1执行正确($?=0),执行cmd2;否则不执行cmd2。

    cmd1 || cmd2

    若cmd1执行正确,不执行cmd2;否则执行cmd2。
#先判断目录是否存在;若存在才在该目录下新建文件。
xiang :~ $ ls abc/ && touch abc/xyz
ls: cannot access abc/: No such file or directory#没有touch错误,说明touch没执行
xiang :~ $ mkdir abc
xiang :~ $ ls abc/ && touch abc/xyz
xiang :~ $ ll abc/
total 0
-rw-rw-r-- 1 xiang xiang 0 10月 12 20:29 xyz

#实现无论abc是否存在,都会新建abc/xyz
xiang :~ $ rm -rf abc/
xiang :~ $ ls abc/ || mkdir abc && touch abc/xyz
ls: cannot access abc/: No such file or directory
xiang :~ $ ll abc/
total 0
-rw-rw-r-- 1 xiang xiang 0 10月 12 20:35 xyz           
  • 指令由左往右执行。
10-认识与学习BASH
#以ls测试abc是否存在,若存在显示"exist";否则显示"not exist"。
xiang :~ $ ll abc
ls: cannot access abc: No such file or directory
xiang :~ $ ll abc && echo "exist" || echo "not exist" #正确
ls: cannot access abc: No such file or directory
not exist
xiang :~ $ ll abc || echo "not exist" && echo "exist" #错误
ls: cannot access abc: No such file or directory
not exist
exist           

10.6管线命令pipe

  • 管线命令

    |

    1. 仅处理前一个指令的stdout,忽略stderr。通过

      2>&1

      将stderr重导向至stdout,即可让管线命令处理stderr。
    2. 必须能接受前一个指令的数据,成为stdin继续处理。

10.6.1 撷取命令:cut,grep

grep

grep [-acinv] [--color=auto] '字符串' filename           
  • -a 将binary文件以text文件的方式搜索数据

    -c 计算找到’字符串’的次数

    -i 视大小写为相同

    -n 输出行号

    -v 反向选择,显示没有’字符串’的行

    –color=auto 将找到的关键词部分加上颜色显示

10.6.2排序命令:sort,wc,uniq

10.6.3双向重导向:tee

  • tee同时将数据送到文件和屏幕。
tee [-a] file #-a以累加的方式将数据加入file

ll | tee file #将ls的数据存到file,同时输出到屏幕           

10.6.4 字符转换命令:tr,col,join,paste,expand

10.6.5 分区命令:split

10.6.6 参数代换:xargs

10.6.7 关于减号-的用途

  • 某些指令需要用文件名来处理时,stdin与stdout可以用”-“替代。
mkdir /tmp/home
tar -cvf - /home | tar -xvf - -C /tmp/home           
  • 将/home中的文件打包,并将打包的数据传送到stdout;经过管线后,将

    tar -cvf - /home

    传送给后面的

    tar -xvf -

    。后面

    -

    读取前一个指令的stdout,因此不需要使用文件名。

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1

Welcome to my github: https://github.com/gaoxiangnumber1