Shell脚本基础I
1、Linux shell类型
/bin/sh--已经被/bin/bash所取代
/bin/bash--就是Linux预设的shell
/bin/ksh--由AT&T Bell lab发展出来的,兼容于bash
/bin/tcsh--整合C Shell,提供更多的功能
/bin/csh--已经被/bin/tcsh所取代
/bin/zsh--基于ksh发展出来的,功能更强大的shell
2、Bash的内建命令:type
[root@linux ~]# type [-tpa] name
参数:
:不加任何参数时,则type会显示出那个name是外部指令还是bash内建的指令
-t:当加入-t参数时,type会将name以底下这些字眼显示出他的意义:
file:表示为外部指令;
alias:表示该指令为命令别名所设定的名称;
builtin:表示该指令为bash内建的指令功能;
-p:如果后面接的name为指令时,会显示完整文件名(外部指令)或显示为内建指令;
-a:会将由PATH变量定义的路径中,将所有含有name的指令都列出来,包含alias
范例一:查询一下ls这个指令是否为bash内建?
[root@linux ~]# type ls
ls is aliased to `ls --color=tty'
没有加上任何参数,仅列出ls这个指令的最主要使用情况
[root@linux ~]# type -t ls
alias
-t参数则仅列出ls这个指令的最主要使用情况说明
[root@linux ~]# type -a ls
ls is aliased to `ls --color=tty'
ls is /bin/ls
利用所有方法找出来的ls相关信息都会被列出来
范例二:那么cd呢?
[root@linux ~]# type cd
cd is a shell builtin
3、变量设定规则(echo、unset)
变量在设定时还是需要符合某些规定的,否则会设定失败,这些规则如下:
1)变量与变量内容以等号=来连结;
2)等号两边不能直接接空格符;
3)变量名称只能是英文字母与数字,但是数字不能是开头字符;
4)若有空格符可以使用双引号『"』或单引号『'』来将变量内容结合起来,但须要留意双引号内的特殊字符可以保有变量特性,但单引号内的特殊字符则仅为一般字符;
5)必要时需要以跳脱字符『\』来将特殊符号(如Enter,$,\,空格符,'等)变成一般符号;
6)在一串指令中,还需要藉由其它的指令提供的信息,可以使用quote『`command`』;(那个`是键盘上方的数字键1左边那个按键而不是单引号)
7)若该变量为扩增变量内容时,则需以双引号及$变量名称 如:『"$PATH":/home』继续累加内容;
8)若该变量需要在其它子程序执行,则需要以export来使变量变成环境变量,如『export PATH』;
9)通常大写字符为系统预设变量,自行设定变量可以使用小写字符,方便判断;
10)取消变量的方法为:『unset 变量名称』。
范例一:设定一变量name,内容为VBird
[root@linux ~]# 12name=VBird
-bash: 12name=VBird: command not found <==屏幕会显示错误!因为不能以数字开头!
[root@linux ~]# name = VBird <==还是错误!因为有空白!
[root@linux ~]# name=VBird <==OK 的啦!
范例二:承上题,若变量内容为VBird's name呢?
[root@linux ~]# name=VBird's name
因为单引号可以将Enter这个特殊字符取消,所以,您可以继续在下一行输入内容~不过,这与我们要达到的功能不同,所以算是失败的
[root@linux ~]# name="VBird's name" <==OK 的啦!
[root@linux ~]# name=VBird\'s\ name
利用反斜线(\)跳脱特殊字符,例如单引号与空格键,这也是OK的。
范例三:我要在PATH这个变量当中『累加』:/home/dmtsai/bin这个目录
[root@linux ~]# PATH=$PATH:/home/dmtsai/bin
[root@linux ~]# PATH="$PATH":/home/dmtsai/bin
上面这两种格式在PATH里头的设定都是OK的!但是底下的例子就不见得。
范例四:呈范例三,我要将name的内容多出"yes"呢?
[root@linux ~]# name=$nameyes
知道了吧?如果没有双引号,那么变量成了啥?name的内容是$nameyes这个变量!我们可没有设定过nameyes这个变量吶!所以,应该是底下这样才对!
[root@linux ~]# name="$name"yes
[root@linux ~]# name=${name}yes
范例五:如何让刚刚设定的name=VBird可以用在下个shell的程序?
[root@linux ~]# name=VBird
[root@linux ~]# bash <==进入到所谓的子程序
[root@linux ~]# echo $name <== 并没有刚刚设定的内容喔!
[root@linux ~]# exit <==离开刚刚的子程序
[root@linux ~]# export name
[root@linux ~]# bash <==进入到所谓的子程序
[root@linux ~]# echo $name <==出现了设定值了
[root@linux ~]# exit <==离开刚刚的子程序
什么是『子程序』呢?就是说,在我目前这个shell的情况下去启用另一个新的shell,新的那个shell就是子程序啦!在一般的状态下,父程序的自订变量是无法在子
程序内使用的。但是透过export将变量变成环境变量后,就能够在子程序底下应用了。
范例六:如何进入到您目前核心的模块目录?
[root@linux ~]# cd /lib/modules/`uname -r`/kernel
每个操作系统核心版本都不相同,以FC4为例,他的预设核心版本是2.6.11-1.1369_FC4,所以他的模块目录在/lib/modules/2.6.11-1.1369_FC4/kernel。因为每个
distributions的这个值都不相同,但是我们却可以利用uname -r这个指令先取得版本信息,就可以透过上面指令当中的内含指令`uname -r`先取得版本输出到cd .. 那
个指令当中,就能够顺利的进入目前核心的驱动程序所放置的目录。
范例七:取消刚刚设定的name这个变量内容
[root@linux ~]# unset name
4、查看环境变量--env
范例一:列出目前的shell环境下的所有环境变量与其内容。
[root@linux ~]# env
HOSTNAME=linux.dmtsai.tw <== 这部主机的主机名称
SHELL=/bin/bash <== 目前这个环境下,使用的Shel是哪一个程序?
TERM=xterm <== 这个终端机使用的环境是什么类型
HISTSIZE=1000 <== 这个就是『记录指令的笔数』在FC4预设可记录1000笔
USER=root <== 使用者的名称啊!
LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:
or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=0
0;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=
00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;3
1:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00
;35:*.xpm=00;35:*.png=00;35:*.tif=00;35: <== 一些颜色显示
ENV=/root/.bashrc <== 使用的个人环境设定档
MAIL=/var/spool/mail/root <== 这个使用者所取用的mailbox位置
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:
/root/bin <== 不再多讲啊!是执行文件指令搜寻路径
INPUTRC=/etc/inputrc <== 与键盘按键功能有关。可以设定特殊按键!
PWD=/root <== 目前使用者所在的工作目录(利用 pwd 取出!)
LANG=en_US.UTF-8 <== 这个与语系有关,底下会再介绍!
HOME=/root <== 这个使用者的家目录啊!
_=/bin/env <== 上一次使用的指令的最后一个参数(或指令本身)
那么上面这些变量有些什么功用呢?
1)HOME:代表使用者的家目录。可以使用 cd ~ 去到使用者的家目录或者利用cd就可以直接回到使用者家目录了
2)SHELL:告知我们目前这个环境使用的SHELL是哪支程序? 如果是bash的话,预设是/bin/bash
3)HISTSIZE:这个与『历史命令』有关,亦即是曾经下达过的指令可以被系统记录下来,而记录的笔数则是由这个值来设定的
4)ENV:这个使用者所使用的个人化环境设定档的读取档案
5)MAIL:当我们使用mail这个指令在收信时,系统会去读取的邮件信箱档案(mailbox)。
6)PATH:就是执行文件搜寻的路径~目录与目录中间以冒号(:)分隔,由于档案的搜寻是依序由PATH的变量内的目录来查询,所以目录的顺序也是重要
7)LANG: 这个是语系档案~很多数据都会用到他,举例说,当我们在启动某些perl的程序语言档案时,他会主动的去分析语系数据文件,如果发现有他无法解析的编码
语系可能会产生错误!一般来说,我们中文编码通常是zh_TW.Big5或者是zh_TW.UTF-8这两个编码,偏偏不容易被解译出来,所以有的时候可能需要修订一下语系数据。
8)RANDOM:这个玩意儿就是『随机随机数』的变量啦!目前大多数的distributions都会有随机数产生器,那就是/dev/random这个档案。 我们可以透过这个随机数档
案相关的变量($RANDOM)来随机取得随机数值。在BASH的环境下,这个RANDOM变量的内容介于0~32767之间,所以,你只要echo $RANDOM时,系统就会主动的随机取出一
个介于 0~32767 的数值。万一我想要使用0~9之间的数值呢?利用declare宣告数值类型, 然后这样做就可以了:
[root@linux ~]# declare -i number=$RANDOM*10/32767; echo $number
8 <== 此时会随机取出 0~9 之间的数值喔!
5、查看所有变量--set
[root@linux ~]# set
BASH=/bin/bash <== bash的主程序放置路径
BASH_VERSINFO=([0]="3" [1]="00" [2]="16" [3]="1" [4]="release"
[5]="i386-redhat-linux-gnu") <== bash的版本啊
BASH_VERSION='3.00.16(1)-release' <== bash的版本
COLORS=/etc/DIR_COLORS.xterm <== 使用的颜色纪录档案
COLUMNS=115 <== 在目前的终端机环境下,使用的字段有几个字符长度
HISTFILE=/root/.bash_history <== 历史命令记录的放置档案,隐藏档
HISTFILESIZE=1000 <== 存起来(与上个变量有关)的档案之指令的最大纪录笔数
HISTSIZE=1000 <== 目前环境下,可记录的历史命令最大笔数
HOSTTYPE=i386 <== 主机安装的软件主要类型。我们用的是i386兼容机器软件
IFS=$' \t\n' <== 预设的分隔符
LINES=35 <== 目前的终端机下的最大行数
MACHTYPE=i386-redhat-linux-gnu <== 安装的机器类型
MAILCHECK=60 <== 与邮件有关,每60秒去扫瞄一次信箱有无新信
OLDPWD=/home <== 上个工作目录
OSTYPE=linux-gnu <== 操作系统的类型
PPID=20046 <== 父程序的PID
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"' <== 命令提示字符,与底下也有关
PS1='[\u@\h \W]\$ ' <== PS1命令提示字符
RANDOM=13586 <== 随机数
SUPPORTED=zh_TW.UTF-8:zh_TW:zh:en_US.UTF-8 <== 本系统所支持的语系
name=VBird <== 刚刚设定的自订变量也可以被列出来
$ <== 目前这个shell所使用的PID
? <== 刚刚执行完指令的回传值
使用set除了会将系统的默认值秀出来之外,连带的所有的你自己设定的变量也会被秀出来,同时需要注意的是,若当时有相当多人同时在线的话,那么你的变量只
能给自己使用(除非改的是系统的预设参数档,如/etc/profile ),而不会干扰到别人的。
6、自订变量转成环境变量--export
[root@linux ~]# export
declare -x ENV="/root/.bashrc"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="linux.dmtsai.tw"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US.UTF-8"
declare -x MAIL="/var/spool/mail/root"
declare -x SHELL="/bin/bash"
7、语系档案的变量--locale
[root@linux ~]# locale -a
aa_DJ
aa_DJ.iso88591
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8
zh_TW
zh_TW.big5
zh_TW.euctw
zh_TW.utf8
中文语系至少支持了两种以上的编码,一种是目前还是很常见的big5 ,另一种则是越来越热门的utf-8编码。那么我们如何修订这些编码呢?其实可以透过底下这些变量
的:
[root@linux ~]# LANG <==主语言的环境
[root@linux ~]# LC_CTYPE <==字符辨识的编码
[root@linux ~]# LC_NUMERIC <==数字系统的显示讯息
[root@linux ~]# LC_TIME <==时间系统的显示数据
[root@linux ~]# LC_COLLATE <==字符串的比较与排序等
[root@linux ~]# LC_MONETARY <==币值格式的显示等
[root@linux ~]# LC_MESSAGES <==讯息显示的内容,如菜单、错误讯息等
[root@linux ~]# LC_ALL <==语言环境的整体设定。
8、要读取来自键盘输入的变量--read
[root@linux ~]# read [-pt] variable
参数:
-p:后面可以接提示字符
-t:后面可以接等待的『秒数!』
范例一:让使用者由键盘输入一内容,将该内容变成atest变量
[root@linux ~]# read atest
This is a test
[root@linux ~]# echo $atest
This is a test
范例二:提示使用者30秒内输入自己的大名,将该输入字符串做named变量
[root@linux ~]# read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai
[root@linux ~]# echo $named
VBird Tsai
9、宣告变量的属性--declare / typeset
declare或typeset是一样的功能。如果使用declare后面并没有接任何参数,那么bash就会主动的将所有的变量名称与内容通通叫出来,就好像使用set一样。
[root@linux ~]# declare [-aixr] variable
参数:
-a:将后面的variable定义成为数组(array)
-i:将后面接的variable定义成为整数数字(integer)
-x:用法与export一样,就是将后面的variable变成环境变量;
-r:将一个variable的变量设定成为readonly,该变量不可被更改内容也不能unset
范例一:让变量sum进行100+300+50的加总结果
[root@linux ~]# sum=100+300+50
[root@linux ~]# echo $sum
100+300+50 <==怎么没有帮我计算加总?因为这是文字型态的变量属性啊
[root@linux ~]# declare -i sum=100+300+50
[root@linux ~]# echo $sum
450
范例二:将sum变成环境变量
[root@linux ~]# declare -x sum
范例三:让sum变成只读属性,不可更动!
[root@linux ~]# declare -r sum
[root@linux ~]# sum=tesgting
-bash: sum: readonly variable <==不能改这个变数了
10、与档案系统及程序的限制关系--ulimit
[root@linux ~]# ulimit [-SHacdflmnpstuv] [配额]
参数:
-H:hard limit,严格的设定,必定不能超过设定的值;
-S:soft limit,警告的设定,可以超过这个设定值,但是会有警告讯息,并且,还是无法超过hard limit的,也就是说,假设我的soft limit为 80,hard limit为
100,那么我的某个资源可以用到90,可以超过80,还是无法超过100,而且在80~90之间,会有警告讯息的;
-a:列出所有的限制额度;
-c:可建立的最大核心档案容量(core files);
-d:程序数据可使用的最大容量;
-f:此shell可以建立的最大档案容量 (一般可能设定为2GB)单位为Kbytes;
-l:可用于锁定(lock)的内存量;
-p:可用以管线处理(pipe)的数量;
-t:可使用的最大CPU时间(单位为秒);
-u:单一使用者可以使用的最大程序(process)数量。
范例一:列出所有的限制数据
[root@linux ~]# ulimit -a
范例二:限制使用者仅能建立1MBytes以下的容量的档案
[root@linux ~]# ulimit -f 1024
11、额外的变量设定功能
1)完整呈现vbird这个变量的内容;
[root@linux ~]# vbird="/home/vbird/testing/testing.x.sh"
[root@linux ~]# echo ${vbird}
/home/vbird/testing/testing.x.sh
2)在vbird变量中,从最前面开始比对,若开头为/,则删除两个/之间的所有数据,亦即/*/
[root@linux ~]# echo ${vbird##/*/}
testing.x.sh <==删除了 /home/vbird/testing/
[root@linux ~]# echo ${vbird#/*/}
vbird/testing/testing.x.sh <==仅删除 /home/ 而已
这两个小例子变量名称后面如果接了两个##,表示在##后面的字符串取最长的那一段;如果仅有一个# ,表示取最小的那一段
3)承上题,如果是从后面开始,删除/*呢?
[root@linux ~]# echo ${vbird%%/*/}
/home/vbird/testing/testing.x.sh <==都没被删除
[root@linux ~]# echo ${vbird%%/*} <==被删除光了!
[root@linux ~]# echo ${vbird%/*}
/home/vbird/testing <==只删除/testing.x.sh部分
这个例子当中需要特别注意,那个%比对的是最后面那个字符的意思,所以第一个方式当然不对~因为vbird这个变量的内容最后面是h而不是/,至于%%/*则是删除最
长的那个/*,当然就是全部喔,而%/*则是最短的那个
4)将vbird变数中的testing取代为TEST
[root@linux ~]# echo ${vbird/testing/TEST}
/home/vbird/TEST/testing.x.sh
[root@linux ~]# echo ${vbird//testing/TEST}
/home/vbird/TEST/TEST.x.sh
如果变量后面接的是/时,那么表示后面是进行取代的工作~而且仅取代第一个,但如果是//,则表示全部的字符串都取代。
12、变量设定方式
str 没有设定 str为空字符串 str已设定非为空字符串
范例一:若str变量内容存在,则var设定为str ,否则var设定为"newvar"
[root@linux ~]# unset str; var=${str-newvar}
[root@linux ~]# echo var="$var", str="$str"
var=newvar, str= <==因为str不存在,所以var为newvar
[root@linux ~]# str="oldvar"; var=${str-newvar}
[root@linux ~]# echo var="$var", str="$str"
var=oldvar, str=oldvar <==因为str存在,所以var等于str的内容
范例二:若str不存在,则var与str均设定为newvar,否则仅var为newvar
[root@linux ~]# unset str; var=${str=newvar}
[root@linux ~]# echo var="$var", str="$str"
var=newvar, str=newvar <==因为str不存在,所以var/str均为newvar
[root@linux ~]# str="oldvar"; var=${str=newvar}
[root@linux ~]# echo var="$var", str="$str"
var=oldvar, str=oldvar <==因为str存在,所以var等于str的内容
范例三:若str这个变量存在,则var等于str,否则输出"novar"
[root@linux ~]# unset str; var=${str?novar}
-bash: str: novar <==因为str不存在,所以输出错误讯息
[root@linux ~]# str="oldvar"; var=${str?novar}
[root@linux ~]# echo var="$var", str="$str"
var=oldvar, str=oldvar <==因为str存在,所以var等于str的内容
13、命令别名设定--alias,unalias
[root@linux ~]# alias lm='ls -l | more'
[root@linux ~]# alias rm='rm -i'
[root@linux ~]# alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias lm='ls -al | more'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@linux ~]# unalias lm
14、历史命令--history
[root@linux ~]# history [n]
[root@linux ~]# history [-c]
[root@linux ~]# history [-raw] histfiles
参数:
n:数字,要列出最近的n笔命令列表
-c:将目前的shell中的所有history内容全部消除
-a:将目前新增的history指令新增入histfiles中,若没有加histfiles则预设写入~/.bash_history
-r:将histfiles的内容读到目前这个shell的history记忆中
-w:将目前的history记忆内容写入histfiles中
范例一:列出目前内存内的所有history记忆
[root@linux ~]# history
#前面省略
1017 man bash
1018 ll
1019 history
1020 history
列出的信息当中,共分两栏,第一栏为该指令在这个shell当中的代码,另一个则是指令本身的内容,至于会秀出几笔指令记录则与HISTSIZE有关。
范例二:列出目前最近的3笔资料
[root@linux ~]# history 3
1019 history
1020 history
1021 history 3
范例三:立刻将目前的资料写入histfile当中
[root@linux ~]# history -w
在预设的情况下,会将历史纪录写入~/.bash_history当中。
[root@linux ~]# echo $HISTSIZE
1000
相关命令:
[root@linux ~]# !number
[root@linux ~]# !command
[root@linux ~]# !!
参数:
number:执行第几笔指令的意思;
command:由最近的指令向前搜寻指令串开头为command的那个指令并执行
!!:就是执行上一个指令(相当于按↑按键后,按Enter)
范例:
[root@linux ~]# history
66 man rm
67 alias
68 man history
69 history
[root@linux ~]# !66 <==执行第66笔指令
[root@linux ~]# !! <==执行上一个指令,本例中亦即!66
[root@linux ~]# !al <==执行最近以al为开头的指令(上头列出的第67个)
15、登录讯息显示数据--/etc/issue,/etc/motd
16、环境设定
1)系统设定值
每个使用者进入到bash shell之后,会先读取的设定档案,预设的设定档案有下列几个:
/etc/sysconfig/i18n
/etc/profile
/etc/bashrc
/etc/profile.d/*.sh
/etc/man.config
2)个人设定值
个人的喜好设定:
~/.bash_profile,~/.bash_login,~/.profile
~/.bashrc
~/.bash_history
~/.bash_logout
3)登入bash的时候,这些设定档到底是如何读取的呢?
先读取/etc/profile,再根据/etc/profile的内容去读取其它额外的设定档, 例如/etc/profile.d与/etc/inputrc等;
根据不同的使用者,到使用者家目录去读取~/.bash_profile或~/.bash_login或~/.profile等;
根据不同使用者,到他家目录去读取~/.bashrc
4)bash命令运作顺序
a、以相对/绝对路径执行指令,例如/bin/ls或./ls;
b、由alias找到该指令来执行;
c、由bash内建的 (builtin) 指令来执行;
d、透过$PATH这个变量的顺序搜寻到的第一个指令来执行。
17、终端机的环境设定--stty,set
1)stty
stty也可以帮助设定终端机的输入按键代表意义。
[root@linux ~]# stty [-a]
参数:
-a:将目前所有的 stty 参数列出来;
范例一:列出所有的按键与按键内容
[root@linux ~]# stty -a
speed 38400 baud; rows 40; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase
= ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl
ixon -ixoff -iuclc -ixany -imaxbel opost -olcuc -ocrnl onlcr -onocr
-onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten
echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
可以利用stty -a来列出目前环境中所有的按键列表,在上头的列表当中,需要之前提到一些变量时,可以利用set来显示,除此之外,其实set还可以帮我们设定整个指令输出/输入的环境。 例如记录历史命令、显示错误内容等。
2)set
[root@linux ~]# set [-uvCHhmBx]
参数:
-u:预设不启用。若启用后,当使用未设定变量时,会显示错误讯息;
-v:预设不启用。若启用后,在讯息被输出前,会先显示讯息的原始内容;
-x:预设不启用。若启用后,在指令被执行前,会显示指令内容(前面有++符号);
-h:预设启用。与历史命令有关;
-H:预设启用。与历史命令有关;
-m:预设启用。与工作管理有关;
-B:预设启用。与刮号[]的作用有关;
-C:预设不启用。若使用>等,则若档案存在时该档案不会被覆盖。
范例一:显示目前所有的set设定值
[root@linux ~]# echo $-
himBH
那个$-变量内容就是set的所有设定,bash预设是himBH。
范例二:设定"若使用未定义变量时,则显示错误讯息"
[root@linux ~]# set -u
[root@linux ~]# echo $vbirding
-bash: vbirding: unbound variable
预设情况下,未设定/未宣告的变量都会是空的,不过若设定-u参数,那么当使用未设定的变量时,就会有问题,很多的shell都预设启用-u参数。若要取消这个参数
,输入set +u即可。
范例三:执行前显示该指令内容。
[root@linux ~]# set -x
[root@linux ~]# echo $HOME
+ echo /root
/root
++ echo -ne '\033]0;root@linux:~\007'
要输出的指令都会先被打印到屏幕上,前面会多出+的符号。
18、万用字符与特殊符号
在bash里还支持一些万用字符(wild card),利用bash处理数据就更方便了,底下我们列出一些常用的万用字符:
* 万用字符,代表0个或多个字符(或数字)
? 万用字符,代表一定有一个字母
# 批注,这个最常被使用在script当中,视为说明
\ 跳脱符号,将特殊字符或万用字符还原成一般字符
| 分隔两个管线命令的界定
; 连续性命令的界定
~ 使用者的家目录
$ 亦即是变量之前需要加的变量取代值(间接引用:\$$)
& 将指令变成背景下工作
! 逻辑运算意义上的非not的意思
/ 路径分隔的符号
>, >> 输出导向,分别是取代与累加
' 单引号,不具有变量置换的功能
" 具有变量置换的功能!
` ` 两个`中间为可以先执行的指令
( ) 在中间为子shell的起始与结束
[ ] 在中间为字符的组合
{ } 在中间为命令区块的组合
\<,\>正则表达式单词边界
>| 强制重定向
~+ 当前工作目录
~- 之前的工作目录
<<,<< = n 左移1/n位
>>,>> = n 右移1/n位
~ 按位非
& 按位与
| 按位或
^ 按位异或
&& 逻辑与,同-a
|| 逻辑或,同-o
组合按键 执行结果
Ctrl + C 终止目前的命令
Ctrl + D 输入结束(EOF)
Ctrl + M 就是Enter
Ctrl + S 暂停屏幕的输出
Ctrl + Q 恢复屏幕的输出
Ctrl + U 在提示字符下将整列命令删除
Ctrl + Z 暂停目前的命令
19、数据流重导向
1)标准输入(stdin):代码为0,使用<或<<;
2)标准输出(stdout):代码为1,使用>或>>;
3)标准错误输出(stderr):代码为2,使用2>或2>>;
1>:是将正确的数据输出到指定的地方去
2>:是将错误的数据输出到指定的地方去
[dmtsai@linux ~]$ find /home -name testing > list 2> list <==错误写法
[dmtsai@linux ~]$ find /home -name testing > list 2>&1 <==正确写法
< 是什么?
就是将原本需要由键盘输入的数据,经由档案来读入的意思。举例来说,可以使用cat在键盘上面输入一些数据,然后写入一个档案内,例如:
[root@linux ~]# cat > catfile
testing
cat file test
<==这里按下[ctrl]+d结束输入来离开
常用重定向:
2>&1 重定向stdrr到stdout
i>&j 重定向文件描述符i到j
>&j 默认的重定向文件描述符1(stdout)到j
0<FILENAME
<FILENAME 从文件中接受输入
n<&_ 关闭输入文件描述符n
0<&_
<&_ 关闭标准输入
n>&_ 关闭输出文件描述符
1>&_
>&_ 关闭标准输出
exec <FILENAME 后面的输入都来自文件filename
exec 6<&0 将标准输入保存在文件描述符6中
exec 0<&6,6<&_ 标准输入从文件描述符6中恢复,并关闭文件描述符6
20、命令执行的判断依据 -- ; && ||
管线命令 -- |
21、一些字符/字符串处理命令
1)grep
[root@linux ~]# grep [-acinv] '搜寻字符串' filename
参数:
-a:将binary档案以text档案的方式搜寻数据
-c:找到'搜寻字符串'的次数
-i:忽略大小写的不同
-n:顺便输出行号
-v:反向选择,亦即显示出没有'搜寻字符串'内容的那一行
-R:递归搜索文件中文本
-w:只搜索整个词
-l:列出包含搜索内容的文件名
范例一:将last当中有出现root的那一行就取出来
[root@linux ~]# last | grep 'root'
范例二:与范例一相反,只要没有root的就取出
[root@linux ~]# last | grep -v 'root'
范例三:在last的输出讯息中,只要有root就取出并且仅取第一栏
[root@linux ~]# last | grep 'root' |cut -d ' ' -f1
grep -G(grep) 基本准则表达式
grep -E(egrep) 扩展准则表达式
grep -F(fgrep)固定字符串列表,匹配其中任何一项
grep -P Perl准则表达式
查看文件中搜索内容的上下文信息:
-A 之前
-B 之后
-C 之前和之后
2)wc
[root@linux ~]# wc [-lwm]
参数:
-l:仅列出行;
-w:仅列出多少字(英文单字);
-m:多少字符;
范例一:那个/etc/man.config里面到底有多少相关字、行、字符数?
[root@linux ~]# cat /etc/man.config | wc
138 709 4506
输出的三个数字中分别代表:行、字数、字符数
范例二:我知道使用last可以输出登入者,但是last最后两行并非账号内容,那么该如何以一行指令串取得这个月份登入系统的总人次?
[root@linux ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
由于last会输出空白行与wtmp字样在最底下两行,因此利用grep取出非空白行,以及去除wtmp那一行。
3)双向重导向: tee
同时将数据流分送到档案去与屏幕(screen);而输出到屏幕的其实就是stdout,可以让下个指令继续处理。
[root@linux ~]# tee [-a] file
参数:
-a:以累加 (append) 的方式,将数据加入 file 当中!
范例:
[root@linux ~]# last | tee last.list | cut -d " " -f1
这个范例可以让我们将last的输出存一份到last.list档案中。
[root@linux ~]# ls -l /home | tee ~/homefile | more
这个范例则是将ls的数据存一份到~/homefile,同时屏幕也有输出讯息。
[root@linux ~]# ls -l / | tee -a ~/homefile | more
要注意:tee后接的档案会被覆盖,所以我们要加上-a这个参数才能将讯息累加。
4)expand
这玩意儿就是在将[tab]按键转成空格键。
[root@linux ~]# expand [-t] file
参数:
-t:后面可以接数字。一般来说一个tab按键可以用8个空格键取代。也可以自行定义一个tab按键代表多少个字符。
范例一:将/etc/man.config内行首为MANPATH的字样就取出;仅取前三行;
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
范例二:承上,如果我想要将所有的符号都列出来?(用cat)
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A
MANPATH^I/usr/man$
MANPATH^I/usr/share/man$
MANPATH^I/usr/local/man$
tab]按键可以被cat -A显示成为^I
范例三:承上,我将tab按键设定成6个字符
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 | expand -t 6 - | cat -A
MANPATH /usr/man$
MANPATH /usr/share/man$
MANPATH /usr/local/man$
123456123456123456.....
因为是以6个字符来代表一个tab的长度,所以MAN...到/usr之间会隔12(两个tab个字符,如果tab改成9的话情况就又不同了。
5)col
[root@linux ~]# col [-x]
参数:
-x:将tab键转换成对等的空格键
-A 则tab会以^I来表示
范例:
[root@linux ~]# cat -A /etc/man.config <==此时会看到很多^I的符号,那就是tab
[root@linux ~]# cat /etc/man.config | col -x | cat -A | more
tab按键会被取代成为空格键,输出就美观多了。
Shell脚本基础I的更多相关文章
- 详细介绍Linux shell脚本基础学习
Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提.1. Lin ...
- shell脚本-基础
shell脚本-基础 编程基础 程序是指令+ 数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell 程序提供了编程能力,解释执行. 计算运行二进 ...
- Linux shell脚本基础学习详细介绍(完整版)二
详细介绍Linux shell脚本基础学习(五) Linux shell脚本基础前面我们在介绍Linux shell脚本的控制流程时,还有一部分内容没讲就是有关here document的内容这里继续 ...
- Linux shell脚本基础学习详细介绍(完整版)一
Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提.1. Lin ...
- Shell脚本基础学习
Shell脚本基础学习 当你在类Unix机器上编程时, 或者参与大型项目如k8s等, 某些框架和软件的安装都是使用shell脚本写的. 学会基本的shell脚本使用, 让你走上人生巅峰, 才怪. 学会 ...
- 什么是Shell?Shell脚本基础知识详细介绍
这篇文章主要介绍了什么是Shell?Shell脚本基础知识介绍,本文是一篇Shell脚本入门文章,在本文你可学到什么是Shell.有多少种Shell.一个Shell脚本代码实例,需要的朋友可以参考下 ...
- shell脚本基础知识
虽然现在能在Linux系统下生存,但是自觉效率太低,和高手有很大的差距. 这就是关于Linux的知识太过匮乏,有很多事情知道该怎么做,但是就是没法在Linux下实现,为了提升工作效率,必须要接触Lin ...
- shell脚本 基础应用
变量分为普通变量可只读变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ...
- 模块一:shell 脚本基础
一.shell脚本介绍 (一)脚本案例及介绍: #!/bin/bash LOG_DIR=/var/log ROOT_UID=0 if ["$UID -ne "$ROOT_UID&q ...
- shell脚本基础知识以及变量
一.基础知识 1.shell脚本的格式注意事项 第一行(一般必须写明):指定脚本使用的shell(若不写明也不影响脚本的执行,系统会自动以sh解析脚本)."#!/bin/bash" ...
随机推荐
- 关于VS2010“ADO.NET Entity Data Model模板丢失或者添加失败问题
我最近在安装vs2010后,添加ADO.NET Entity 实体时发现,我的新建项里面并没有这个实体模型,后来我就在博问里面发表了问题,请求大家帮忙解决,悲剧的是少有人回应啊,呵呵,不过我还是在网上 ...
- 位bit——字节Byte???
1.换算 每8个位(bit)组成一个字节(byte) 位bit简写为小写字母“b”,字节Byte简写为大写字母“B” 8*b=1*B 1024*B=1*KB 1024*K=1MB 2.举例 一个英文字 ...
- Labview实现脉波调制( PAM )
Labview实现脉波调制( PAM ) 根据定义为脉冲振幅调制 生成一个正弦信号,得到其幅值输入给一个方波信号的幅值 这个等价于一个方波信号和一个正弦信号相乘 得到的PAM信号通过观察其频率可以发现 ...
- SQLite函数详解之二
sqlite3支持的数据类型: NULL.INTEGER.REAL.TEXT.BLOB 但是,sqlite3也支持如下的数据类型 smallint 16位整数 integer ...
- ubuntu 10.04 fcitx 4.12 实现按下shit切换输入法同时提交英文输入
安装: echo "add fcitx ppa..." sudo apt-add-repository ppa:fcitx-team/nightly sudo apt-get in ...
- RHEL6.4找回root密码的方法
1.先在系统启动的时候提示:press any key to enter menu 时按下e键(其实其他键也可以,只不过我习惯e键而已) 2.进入如下界面: 3.按上下箭头方向键选中第二项,按e键,进 ...
- ubuntu 13.04 163源(亲测可用)
# deb cdrom:[Ubuntu )]/ trusty main restricted # See http://help.ubuntu.com/community/UpgradeNotes f ...
- 软件工程课堂练习——N层电梯只停一层求乘客爬楼层数最少(基本方法+优化方法)
题目: •石家庄铁道大学基础大楼一共有四部电梯,每层都有人上下,电梯在每层都停.信1201-1班的张一东觉得在每层都停觉得不耐烦. •由于楼层不太高,在上下课高峰期时时,电梯从一层上行,但只允许停在某 ...
- oracle数据库登录连接很慢;kettle连接oracle 报 IO 错误,socket time out 问题解决记录
问题描述: 1:oracle数据库连接登陆时突然变得很慢:sqldeveloper链接数据库很慢: 2:Kettle-spoon etl程序访问数据库,任务执行时报 :数据库连接 IO错误 :Sock ...
- NYOJ-235 zb的生日 AC 分类: NYOJ 2013-12-30 23:10 183人阅读 评论(0) 收藏
DFS算法: #include<stdio.h> #include<math.h> void find(int k,int w); int num[23]={0}; int m ...