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的那个例子)