BASH

来源:互联网 发布:vocaloid软件 编辑:程序博客网 时间:2024/06/06 03:55

Shell(壳程序):

提供用户与操作系统之间的接口。狭义的shell指指令列方面的软件,如bash,广义的壳程序则包括图形接口的软件。/bin/bash是Linux预设的shell。系统合法的shell均记录在/etc/shells档案中


type指令可以用来查看一个指令是外部指令还是bash内建指令


真正以shell与Linux进行沟通是登入Linux之后,在进入shell之前,由于系统需要一些变量来进行数据的存取或环境的设定参数,所以需要“环境变量”。环境变量通常以大写字母表示。


变量的设定规则:

1. 变量与变量内容用等号连接,如user=xero

2. 等号两边不能直接接空格

3. 变量名只能是字母、数字或下划线,且不能以数字开头

4. 变量内容若有空格可以用双引号或单引号引起,双引号内的特殊字符会保持原有属性("$user"是xero),单引号内的特殊字符则为纯字符('$user'是$user)

5. 特殊字符可用 "\" 跳脱

6. 在一串指令中,需要藉由其他指令提供的信息可以用反单引号【`】或【$(指令)】(反单引号内的指令会先被执行,获得的结果作为外部输入信息)

7. 扩增变量内容时,可用"$变量名"或${变量名},如PATH="$PATH":/home/bin

8. 若该变量要在其他子程序执行,需要以export使其变成环境变量(在一个shell下启动另一个新的shell,新的shell就是子程序。一般情况下,子程序仅会继承父程序的环境变量,父程序的自定义变量在子程序内是无法使用的)

9. 通常大写为系统默认变量,自定义变量最好用小写

10. 取消变量使用unset


env可以用来观察环境变量

set会显示所有变量

特殊变量:

1. $:目前shell的线程号(PID)

2. ?:上一个指令执行的回传值,成功执行为0


为什么环境变量可以被子程序使用:

主要是因为内存配置的关系

当启动shell时,操作系统会分配一块内存给shell使用,这块内存中的变量可以让子程序调用

当父程序export一个变量后,该变量会被写到上述内存中而成为环境变量

当加载另一个shell(启动子程序)时,子程序会将父程序环境变量所在的内存导入自己环境变量的内存中


read:可以读取来自键盘输入的变量,可以与用户进行交互

read [-pt] 变量名

-p:后接提示字符

-t:后接等待的秒数


declare:声明变量类型

declare [-aixr] 变量名

-a:将变量定义为数组类型

-i:将变量定义为integer

-x:将变量定义为环境变量

-r:将变量设定为只读,内容无法更改,也不能被unset

将"-"变成"+"可进行取消操作。当不接任何参数时,bash会显示所有变量,效果同set。


ulimit:限制用户的某些系统资源

ulimit -[SHacdfltu] [配额]

-H:严格的设定,必须不能超过这个数值

-S:警告的设定,可以超过这个值,但会有警告信息

-a:后面不接任何选项与参数,可列出所有的限制额度

-c:限制核心档案的最大容量(当某些程序出错时,系统会将该程序在内存中的信息写成档案以进行纠错,这种档案称为核心档案(core file))

-f:此shell可建立最大档案的大小,单位为KB(一般为2GB)

-d:可使用的最大segment容量

-l:用于锁定(lock)的内存量

-t:可使用的最大CPU时间(秒)

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


变量内容的删除(Ubuntu下并未改变原变量内容,只是显示出的内容变化了)

例:echo ${path#/*lightdm:}:删除符合从"/"开始到"*ligtdm:"最短的部分



变量内容的替换:



设定alias:alias lm='ls -al'

ualias lm:取消lm

alias是创建命令别名,创建的是一个新的可下达的指令;而变量需要echo才能呼叫出变量内容

(创建的变量和alias注销后就被清除,若想保存需写入~/.bashrc)


history:历史命令

history [n]:列出最近执行的n条指令

history [-c]:将目前shell中的history删除

history [-arw] histfiles:

-a:将目前新增的history指令增加至histfiles中(预设写入~/.bash_history)

-r:将histfiles的内容读入当前shell的history记录中

-w:将目前的history内容写入histfiles

当以bash登入linux时,系统会主动通过家目录的~/.bash_history读取曾经下达过的指令,在注销时,会将新下达的指令更新到~/.bash_history中,也可以用history -w强制写入


当多个bash以相同身份登入Linux时,最后注销的bash才会写入history数据,其他bash写入的数据都被覆盖掉了


指令的运作顺序:

1. 以相对/绝对路径执行

2. 由alias找到指令执行

3. 由bash内建(builtin)指令来执行

4. 通过$PATH变量的顺序搜索到的第一条指令


通过修改/etc/issue可以修改进站画面的欢迎信息

/etc/issue.net可修改通过telnet远程登入时的欢迎界面



shell可以分为login shell和non-login shell

login shell:

取得bash时需要完整的登入流程(输入账户和密码)。读取的配置文件:

1. /etc/profile:系统的整体设定

2. ~/.bash_profile或~/.bash_login或~/.profile:属于使用者的个人设定(Ubuntu是~/.profile)

non-login shell:

取得bash时不需要登录,如以X window登入linux或在原本的bash环境下呼叫新的bash


/etc/profile(login shell才会读):

每个使用者登录取得bash时一定会读取的配置文件。如果想要更改所有使用者的整体环境就修改这个档案。同时,它还会呼叫外部的设定数据,如

/etc/inputrc(其实这个档案并未被执行,/etc/profile会主动判断使用者有没有自定义输入的按键功能,如果没有,它会设定[INPUTRC=/etc/inputrc])

/etc/profile.d/*.sh(多个.sh档案,规范了bash操作接口的颜色、语系、ll与ls指令的别名等,如果需要)。如果要给所有使用者设定共享的alias,可以在该目录下自行建立.sh档案

/etc/sysconfig/i18n(由/etc/profile.d/lang.sh调用,决定bash预设使用语系的配置文件,最重要的就是变量LANG的设定)


~/.bash_profile(login shell才会读):

有三个文件,依次为:~/.bash_profile,~/.bash_login,~/.profile。其实login shell只会读取其中一个


source:读入环境配置文件

由于/etc/profile与~/.bash_profile都是在取得login shell的时候才会读取,在自行更改后需要通过source指令来读入(source或"."都可以)。


non-login shell会读取~/.bashrc


其他bash相关的配置文件:

/etc/manpth.config:规范了使用man的时候,man page的路径是什么。这个档案中最重要的是变量“MANPATH”的设定,搜寻man page的时候会依据MANPATH的路径去搜索

~/.bash_history:记录历史命令。每次登入bash后,bash会先读取这个档案,将所有的历史指令读入内存

~/.bash_logout:记录了注销bash后系统执行的动作


stty:查阅目前的按键内容(stty -a:列出所有的stty参数)


例:将ctrl+h设为向后删除:stty earse ^h


除stty之外,bash还有自己的终端机设定值,是用set来设定的

set [-uvCHhmBx]

-u:预设不启用。启用后,使用未设定变量时,会显示错误信息

-v:预设不起用。启用后,信息被输出前,会先显示信息的原始内容

-x:预设不起用。启用后,指令被执行前,会显示指令内容(前面有++符号)

-h:预设启用。与历史指令有关

-H:预设启用。与历史指令有关

-m:预设启用。与工作管理有关

-B:预设启用,与[ ]的作用有关

-C:预设不启用。若是用>等,则档案存在时不会被覆盖

若要取消参数,输入set +“参数” 即可

显示目前所有的set设定:echo $-


bash默认的组合键:



bash的通配符:



bash的特殊符号:



数据流重导向:

将某个指令执行后应该要出现在屏幕上的数据传输到其他的地方


standard output:指令执行所回传的正确信息

standard error output:指令执行失败后回传的错误信息

standard input:将原本需要由键盘输入的数据改由档案内容来取代

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

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

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

>:若文件不存在则建立文件再写入,若文件存在则覆盖原文件。如果不想删除旧数据就使用>>

将正误信息写入到一个档案的方法:&> 档案名。例:find /home -name .bashrc &> list

可以将错误信息输入到/dev/null从而忽略掉错误信息

用cat建立档案:cat > catfile,然后输入数据,完成后ctrl+d离开

用stdin代替键盘输入:cat > catfile < ~/.bashrc

<<:结束的输入字符。例:cat > catfile << "eof",则输入结束后按"eof"即可终止输入,不需要ctrl+d


常见使用命令输出重导向的情况:

1. 输出的信息很重要,需要进行保存

2. 后台执行的程序,不希望干扰屏幕正常输出

3. 系统例行命令的执行结果希望可以保存

4. 一些指令已知会产生错误信息时进行忽略

5. 错误信息与正确信息需要分别输出时


command1 ; command2:执行command1和command2

command1 && command2:只有在command1成功时才执行command2

command1 || command2:只有在command1执行失败时才执行command2

若有多个&&,||则按从左到右的顺序依次执行


管线命令:

管线命令“|”只能处理前面一个指令传来的正确的信息(也就是stdout),对stderr并没有直接处理能力。

在每个管线后面接的第一个数据必须是指令才可以,并且该指令必须能够接受stdin的数据指令(这样的指令称为管线指令)


撷取指令(cut,grep)是一行一行地进行分析,并不是一下分析整篇信息

cut:主要用于同一行中的数据进行分解,将一行信息中取出部分需要的

cut -d '分隔符' -f fileds:用于有特定分隔字符

cut -c 字符区间:用于排列整齐的信息

-d:后接分隔字符,与-f一起使用

-f:依据-d的分隔字符将一段信息分割成为数段,-f表示取出第几段

-c:以字符的个数取出固定字符区间的信息

例:echo $PATH | cut -d ':' -f 5   :取出以":"分割,第5个区间的信息

export | cut -c 12-   :取出12个以后的字符


grep:分析一行信息,若有需要的,则将该行整个取出

grep [-acinv] [--color=auto] '搜寻的字符串' filename

-a:将binary档案以text档案的方式搜寻数据

-c:计算找到'搜寻字符串'的次数

-i:忽略大小写

-n:顺便输出行号

-v:反向选择,即输出没有'搜寻字符串'内容的那行

--color=auto:将找到的关键词部分进行颜色显示


排序指令:sort,wc,uniq

sort [-fbMnrtuk] [file or stdin]

-f:忽略大小写

-b:忽略最前面的空格

-M:以月份的名字排序

-n:使用数字进行排序(默认是以文字形态来排序的)

-r:反向排序

-u:就是uniq,相同的数据仅出现一行代表

-t:分隔符,预设是[tab]

-k:以那个区间(field)进行排序

例:/etc/passwd的内容是以":"来分隔的,以第三栏排序:cat /etc/passwd | sort -t ':' -k 3


uniq:重复的信息仅显示一次:

uniq [-ic]

-i:忽略大小写

-c:进行计数

例:last列出帐号,取出帐号栏,排序后仅取出一位并统计登录次数:last | cut -d -f 1 | sort | uniq -c


wc:统计字数,行数及字符数

wc [-lwm]

-l:列出行数

-w:列出单词数

-m:列出字符数

不加参数的话就是将三个数字依次列出


tee:双向引导,将数据送至屏幕和档案

tee [-a] filename

-a:以累加(append)的方式将数据加入file当中(若无该参数则会覆盖已存在档案)

例:ls -l | tee file.txt | less


tr:删除或替换文字(搭配管线使用)

tr [-ds] SET1 SET2

-d:删除信息中的SET1这个字符串

-s:取代重复的字符

无参数:将SET1用SET2进行代替

(DOS中的"^M"可以用"\r"代替)


col [-xb]

-x:将[tab]转换成空格

-b:在文字中有"/"时,仅保留"/"后的那个字符


join:将两个档案中有相同数据的两行合并到一起

join [-ti12] file1 file2

-t:join默认以空格分隔数据,并对比第一个字段的数据,若二者相同,则将两行合并,第一个字段放在前面

-i:忽略大小写

-1:第一个档案用哪个字段进行分析

-2:第二个档案用哪个字段进行分析

例:用/etc/passwd的第4个字段和/etc/group的第3个字段进行合并:join -t ':' -1 4 /etc/passwd -2 3 /etc/group


paste:将两行合并到一起,中间以[tab]分开

paste [-d] file1 file2

-d:后接分隔字符,预设为[tab]

-:如果file部分写成"-",表示来自stdin的资料


expand:将[tab]转换成空格(unexpand将空格转换成[tab])

-t:后接数字,表示一个tab用多少个空格代替,常为8


split:将一个大的档案分成若干个小档案

split [-bl] file PREFIX

-b:后接欲分割成的小档案的大小,可加单位,如k,b,m等

-l:以行数进行分割

PREFIX:前导符,可作为分割档案的前导文字

例:将一个档案分成每个100K的小档案:split -b 100k /etc/passwd new_pw

再将这几个小档案合并成一个大档案: cat new_pw* >> passwd

例:将ls -al的输出信息每10行记录成一个档案:ls -al | split -l 10 - ls_file


xargs:参数替换,可以读入stdin的数据,用空格或断行符分割,将stdin的数据作为argument

xargs [-0epn] command

-0:如果stdin含有特殊字符(如`, \等),可以将其还原成一般字符

-e:EOF的意思,后接一个字符,当xargs分析到该字符时便停止工作

-p:执行每个argument时进行询问

-n:数字,表示一次执行多少个arguments

当没有参数时,默认以echo进行输出

例:将/etc/passwd内的帐号以finger查阅,一次仅查阅5个帐号: cut -d ':' -f 1 /etc/passwd | xargs -p -n 5 finger

例:将/etc/passwd内的帐号以finger查阅,分析到'lp'时结束指令:cut -d ':' -f 1 /etc/passwd | xargs -e'lp' finger (注意-e'lp'连在一起,中间无空格)

当指令不是管线指令,无法直接从stdin获得数据时,可以使用xargs引用stdin提供给指令

例:find /sbin/ -perm +7000 | xargs ls -l


减号(-):

在管线中,管线后指令的stdin或stdout可用"-"代替,代表的是前一个指令的输出(如split的那个例子)


0 0