第五章、bash功能

  本文借鉴了很多来自鸟哥书上的,因为找来找去,最后发现还是鸟哥写得最详细了,然后自己写了一些,网上收集了一些。

  shell,人机交互接口。


Bash shell的功能:


一、快捷键:

Ctrl+a: 跳到命令行首

Ctrl+e: 跳到命令行尾

Ctrl+u: 删除光标至命令行首

Ctrl+k: 删除光标至命令行尾

Ctrl+l: 清屏

Ctrl+c: 终止目前的命令

Ctrl+d: 输入结束(EOF)

Ctrl+m: 相当于Enter

Ctrl+s: 暂停屏幕输出

Ctrl+q: 恢复屏幕输出

Ctrl+z: 暂停当前执行命令

Shift+[PgUp]/[PgDn]: 文字界面前后翻动


二、命令历史(history)

history 查看命令历史

  选项

  -c  清空所有命令历史

  -d  删除指定命令历史

    -d 500 删除第500个命令

    -d 500 10 从500往后10个命令都删除

  -w  将缓冲区写入手动写入该用户家目录下.bash_history文件


  操作

  !50  执行第50条命令

  !-4  执行倒数第4条命令

  !!  执行上一条命令

  !m  m代表一个字符串,执行最近一个以m开头的命令,类似补全

  !$  引用前一个命令的最后一个参数,类似的还有

  Esc .

  Alt+.


三、命令别名(alias)

alias ll='ls -l' 设置别名

unalias ll     取消别名

\rm         不用别名用本身


四、通配符(Wildcard)

符号 含义
* 代表0到无穷个任意字符
? 代表只有1个字符
[] 代表有1个字符在其中,例[abcdef]
[-] 代表在编码顺序一定范围内的所有字符,例[0-9]
[^] 反向选择,同[!],例[!a-z],表示除了所有的小写字母的任意字符


五、特殊符号

符号 含义
# 注释字符,在shell script视为解释
\ 跳脱字符,将特殊字符还原成一般字符
| 管线(pipe)
; 下达连续命令的分隔符
~ 使用者家目录
$ 在变量前代表取出变量的值
& 将当前工作放入后台执行
! 相当于not,反向
/ 路径分隔符
> >> 输出重定向,分别为取代和累加
< << 输入重定向
'' 单引号,会使变量前$符号变为无意义
"" 具有变量置换功能
`` 优先执行命令,同$()
() 在中间为子 shell 的起始与结束
{} 在中间为命令区块的组合


六、重定向

1、标准输入(stdin),代码为0,使用 < 或 <<

2、标准输出(stdout),代码为1,使用 > 或 >>

3、标准错误输出(stderr),代码为2,使用 2> 或 2>>

  1> :以覆盖的方式将‘正确的资料’输出到指定的档案或者装置上;

  1>> :以累加的方式将‘正确的资料’输出到指定的档案或者装置上;

  2> :以覆盖的方式将‘错误的资料’输出到指定的档案或者装置上;

  2>> :以累加的方式将‘错误的资料’输出到指定的档案或者装置上;

  < :将原本需要由键盘输入的资料,改由档案内容来取代

  << :代表的是‘结束的输入字符’的意思,比如cat > file << "eof",最后输入eof字符代表结束


只输出标准输出(stdout)

 find /home -name .bashrc 2> /dev/null > list

只输出标准错误输出(stderr)

 fine /home -name .bashrc > /dev/null 2> list

标准输出和标准错误输出都输出

 fine /home -name .bashrc > list 2>&1

 fine /home -name .bashrc 2> list 1>&2

 fine /home -name .bashrc &> list

 #这三种结果一致

标准输出和标准错误输出都不输出

 fine /home -name .bashrc &> /dev/null

 #同理


例子:

一、
[root@study ~]# cat > filename
test1  
test2
test3
#这里必须要一个回车然后ctrl+d才能完整退出
[root@study ~]# cat filename
test1
test2
test3
#cat从键盘获取输入,然后输出到filename文件


二、
[root@study ~]# cat > filename < .bashrc
[root@study ~]# cat filename 
# .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
#从左到右,cat先从键盘获取输出到filename,但是键盘没有输入,然后从.bashrc标准输入到
filename


三、
[root@study ~]# cat > filename << EOF
> test1
> test2
> test3
> EOF
[root@study ~]# cat filename 
test1
test2
test3
#同样,从左到右,cat先从键盘获取输出到filename,最后遇到EOF结束


四、
[root@study ~]# cat >> filename << EOF
> test4
> EOF
[root@study ~]# cat filename 
test1
test2
test3
test4
#从左到右,cat先从键盘获取追加输出到filename,最后遇到EOF结束


五、
[root@study ~]# cat
testtest
testtest
#cat命令既能获得输入又能将该输入输出,输入默认来自键盘,输出默认来自屏幕
#这问题以前一直没搞明白,写着写着就懂了...


七、命令执行的判断依据:

; 连续下达指令,无相关性

&&|| 与前一个命令有相关性,与$?(命令回传值)有关

指令下达情况 说明
cmd1 && cmd2 1. 若 cmd1 执行完毕且正确执行($?=0),则开始执行 cmd2。

2. 若 cmd1 执行完毕且为错误 ($?≠0),则 cmd2 不执行。

cmd1 || cmd2 1. 若 cmd1 执行完毕且正确执行($?=0),则 cmd2 不执行。

2. 若 cmd1 执行完毕且为错误 ($?≠0),则开始执行 cmd2。

&&和||还有逻辑与和或的意思


八、管线命令(pipe)

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

第五章、bash功能_第1张图片

注意:

1、管线命令仅会处理 standard output,对于 standard error output 会予以忽略

2、管线命令必须要能够接受来自前一个指令的资料成为 standard input 继续处理才行。

如果硬要让 standard error 可以被管线命令所使用,那该如何处理?

让 2>&1 加入指令中,就可以让 2> 变成 1> 了。


tee 双向重定向

标准输出 > 会将资料流整个传送给档案或装置,因此我们除非去读取该档案或装置,否则就无法继续利用这个资料流。通过tee,会同时将资料流分送到档案去与屏幕(screen);而输出到的屏幕的,其实就是stdout。

第五章、bash功能_第2张图片

[root@study ~]# tee [-a] file
-a :以累加(append)的方式,将资料加入 file 当中!

例子:
[root@study ~]# last | tee last.list | cut -d " " -f1
#将last结果输出到last.list文件,同时交给cut处理

[root@study ~]# ls -l /home | tee ~/homefile | more
#将结果放入~/homefile,同时在屏幕输出

[root@study ~]# ls -l / | tee -a ~/homefile | more
#将结果追加到~/homefile,同时在屏幕输出


九、变量

变量分为环境变量(全局变量)和本地变量(局部变量)

echo $HOME 或 echo ${HOME} 取出变量的值


 规则:

 1、变量与变量内容必须以一个 = 号来连接

 2、等号两边不能直接接空白符

 3、变量不能以数字开头

 4、变量的内容有空白符用 "" 或 ‘’ 号将变量内容引起来,单引号会使$name的$失去意义

 5、跳脱字符 \ 可以使特殊字符跳脱其本来的含义,变成一般字符

 6、可以使用$(命令)和`命令`来先执行再取出

 7、局部变量需要以export来使变量变成环境变量

 8、取消变量的方法为unset


 变量相关命令:

 set 观察所有变量(包含环境变量和局部变量)

 env(environment环境) 或 export 显示当前shell的所有环境变量

 export 将局部变量变成环境变量

  export 变量名称

 locale 显示所有的语序变量,默认显示当前变量使用的语序,对应文件则为/etc/locale.conf

  locale -a 显示所有支持的语序,比如big5,utf-8

 read 取得来自键盘输入

  read [-pt] variable

  -p 后面接提示字符

  -t 后面接等待的秒数

 declare/typeset 宣告变量类型

  declare [-aixr] variable

  -a 数组型

  -i 整形

  -x 同export,变成环境变量

  -r 将变量设为只读,该变量内容不能被修改,也不能unset


 变量:

 子程序仅会继承父程序的环境变量,不会继承父程序的局部变量

 $PATH 环境变量

 $HOME 使用者家目录

 $SHELL 使用的shell是什么程序

 $HISTSIZE 命令历史的长度

 $MAIL 使用者的邮箱路径

 $LANG 非常重要语系的变量

 $RANDOM 随机数

 $PS1 提示符设定

  默认是[\u@\h \W]\$

  \u 当前使用者的帐号

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

  \H 完整主机名

  \w 完整目录名称

  \W 当前目录名称,利用besename

  \# 使用的第几个命令

  \$ 提示字符,root为#,其余为$

  \d 可列出'星期 月 日'

  \t 显示时间,24小时格式的‘HH:MM:SS’

  \T 显示时间,12小时格式的‘HH:MM:SS’

  \A 显示时间,24小时格式的‘HH:MM’

  \@ 显示时间,12小时格式的‘am/pm’

  \v BASH的版本号

 $$ 本shell的PID

 $? 上个指令的回传值,正确为0,错误非0


 变量内容的删除与取代:

变量设定方式 说明

${变量#关键字}

${变量##关键字}

变量内容从头开始的资料符合‘关键字’,则将符合的最短资料删除

变量内容从尾向前的资料符合‘关键字’,则将符合的最长资料删除

${变量%关键字}

${变量%%关键字}

变量内容从尾向前的资料符合‘关键字’,则将符合的最短资料删除

变量内容从尾向前的资料符若合‘关键字’则将符合的最长资料删除

${变量/旧字串/新字串}

${变量//旧字串/新字串}

若变量内容符合‘旧字串’则‘第一个旧字串会被新字串取代’

若变量内容符合‘旧字串’则‘全部的旧字串会被新字串取代’


 变量的测试与内容替换:

变量设定方式 str没有设定 str为空字符串 str为非空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr}

str=expr

var=expr

str 不变

var=

str 不变

var=$str

var=${str:=expr}

str=expr

var=expr

str=expr

var=expr

str 不变

var=$str

var=${str?expr} expr 输出至 stderr var= var=$str
var=${str:?expr} expr 输出至 stderr expr 输出至 stderr var=$str


十、路径与指令的搜寻顺序:

1、以相对/绝对路径执行指令,例如‘ /bin/ls ’或‘ ./ls ’;

2、由 alias 找到该指令来执行;

3、由 bash 内建的 (builtin) 指令来执行;

4、透过 $PATH 这个变量的顺序搜寻到的第一个指令来执行。

 例子:

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

[root@study ~]# alias echo='echo -n'
[root@study ~]# type -a echo
echo is aliased to `echo -n'
echo is a shell builtin
echo is /usr/bin/echo


十一、login与non-login shell

login shell:简单来说,就是经过帐号密码的验证过程的shell就叫做login shell,比如,1、文字界面和图形界面的登录验证,2、su - 命令切换用户的过程。

 执行过程大概为:

 /etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc


non-login shell:反之,1、图形界面打开的终端(X window) 2、文字界面打开子shell 3、su 命令切换用户的过程。

  执行过程大概为:

  ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh


 全局配置为/etc/profile, /etc/profile.d/*.sh,/etc/bashrc (/etc目录下)

 局部配置为~/.bash_profile , ~/.bashrc (家目录下)

 profile类文件的作用为设定环境变量和运行命令或脚本

 bashrc类文件的作用为设定局部变量和定义命令别名

 

 有关设置文件:

 1、/etc/profile:系统整体的设置

 2、~/.bash_profile或~/.bash_login或~/.profile:个人设置,用户个人可修改的。


 1)/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 等!

  1.1)/etc/profile.d/*.sh

  只要在/etc/profile.d/这个目录内且后缀为.sh且使用者有r全权限,那么就会被/etc/profile调用进来,该目录下规范了bash操作界面的颜色、语系、别名等等。如果你需要帮所有使用者设定一些共用的命令别名时,可以在这个目录底下自行建立后缀名为 .sh 的档案,并将所需要的资料写入即可。

  1.2)/etc/locale.conf

  由/etc/profile.d/lang.sh调用,bash预设使用哪种语系的设置,文件里重要的就是 LANG/LC_ALL 这些个变量的设定

  1.3)/usr/share/bash-completion/completions/*

  有关[tab]补全的功能,与该目录下当对应的指令来处理的,其实这个目录底下的内容是由 /etc/profile.d/bash_completion.sh 这个档案载入的

 bash 的login shell情况下所读取的整体环境设定档其实只有 /etc/profile,但是 /etc/profile 还会呼叫出其他的设定档


 2)~/.bash_profile (login shell会读取)

 bash 在读完了整体环境设定的/etc/profile并借此呼叫其他设定档后,接下来则是会读取使用者的个人设定档。在login shell的 bash 环境中,所读取的个人偏好设定档主要有三个,依序分别是:

 1、~/.bash_profile

 2、~/.bash_login

 3、~/.profile

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

 

[root@study ~]$ cat ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then    #判断家目录下的~/.bashrc是否存在,若存在则读取设定
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH


第五章、bash功能_第3张图片

 在 CentOS 的 login shell 环境下,最终被读取的是 ~/.bashrc 这个文件。所以,可以将要改动的写入到这个文件中即可。


 source 

 使Shell读入指定的Shell程序文件并依次执行文件中的所有语句,在当前shell执行。

 source filename

  例子: 

[root@study ~]# source ~/.bashrc

[root@study ~]# . ~/.bashrc

#source和.都是一样的效果


 source filename 与 sh filename 及./filename执行脚本的区别:

 1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。

 2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。

 3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。


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

 当你取得 non-login shell 时,该 bash 仅会读取 ~/.bashrc 

[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的作用:

 1、依据不同的UID规范出 umask 的值

 2、依据不同的UID规范出提示字符 (就是PS1变量)

 3、呼叫/etc/profile.d/*.sh的设定


 /etc/bashrc 是CentOS和Red Hat特有的,由于 ~/.bashrc 会呼叫 /etc/bashrc 及 /etc/profile.d/*.sh,所以,万一你没有 ~/.bashrc (可能自己不小心将他删除了),那么你会发现你的 bash 提示字符可能会变成这个样子:

 bash-4.2$

 因为你并没有呼叫 /etc/bashrc 来规范 PS1 变量啦!这样的情况并不会影响你的 bash 使用。如果你想要恢复命令提示字符,那么可以复制 /etc/skel/.bashrc 到你的家目录,然后用source去执行~/.bashrc,就行了。


你可能感兴趣的:(shell,bash,功能)