UNIX Shell Programming (notes)
Intro for this note:
As the title of this doc, this file is astudy notes for UNIX shell Programming, revised edition. The book is publishedApril 1997, 11 years old. However, I do not think there will be a lotdifference as UNIX is so solid and programming are all the same.
I have been asked to learn some Shell workby my kindly manager to improve myself. And for sure I do not want be a UNIX dummyany more. So let’s start with the book. Keep recording the good useful knowledgeand hopefully this book can be finished not too late.
It is no need to introduce UNIX oreverything old-story, so lets skip the introduction and start with chapter 2.
Chapter 2 A quick review of the Basics(page 5-40)
It is 35 pages in total, should be done bytoday.
Some basic commands: (boldface means thecommand you should type in)
$date
tells the system to print the date and time
$who
find out who is logged in
$whoam i
get information of yourself
$echo<string>
print what ever you typed on the line.
Generally, unix ignores extra blanks.
Working with files
$ls<filename>
list all the files you have stored in yourdirectory.
$cat<filename>
display file content
$wc<filename>
5 527
counting the number of words in a file(-_-for what reason???…-_-)
first 5 means 5 lines, second means 5words, third means 27 charactors
$cp<sourcefile> <destfile>
Copy, every body knows
$rm<fileName>|<filename>|…
Remove a file
Working with directories(every body should knowdirectory structures)
$pwd
Print current directory path
$cd …
$ls-l
[root@dsbj-lab13~]# ls -l
total364364
-rw-r--r-- 1 root root 1506 Oct 24 15:18 anaconda-ks.cfg
drwxr-xr-x 2 root root 4096 Nov 12 17:59 config
First column -means it is a file, d meansit is folder
rw-r—r—means the access of every user. Firstthree are owner, then group user, then anybody else.
1 meanse the link count, then owner of the file,then the size(how many characters) then the time it was last modified. Then thefile name.
$mkdir
Make directory
$ln
Link files make file have different nameslink folders make two folders have same content.(try some here)
$rmdir
Delete an empty folder
$rm –r<dir>
Delete a folder anyway
*is useful
? is too
Standard input/output
Ctrl-d means the end of input
$<command>> file
can put the out put into a files
$<command>>> file
Can add content of output that file. Onlyone >do the replace
|
pipes commands together
More on commands
<command1>;<command2>
Multi commands in 1 line
& put command to back ground
ps -f
gives you the information of processes arerunning
sh means the shell
tty the terminal No the process was runfrom.
-f give your parents process id
Start time
Chapter 3 what is the shell (p41-53)
I do not know what I need to do withchapters, it is basically a illustration and very easy to be understand if youhave fundamental education of computer science. It is no need to dig into itsince you just need to know shell is a interface which links users and kernelof UNIX together.
Chapter 4 Tools of the trade (p55-102) 47pages, need maybe several hours
Regular expression characters
Please read this huge chart
Table 4.1. Regular Expression Characters | |||
Notation | Meaning | Example | Matches |
. | any character | a.. | a followed by any two characters |
^ | beginning of line | ^wood | wood only if it appears at the beginning of the line |
$ | end of line | x$ | x only if it is the last character on the line |
|
| ^INSERT$ | a line containing just the characters INSERT |
|
| ^$ | a line that contains no characters |
* | zero or more occurrences of previous regular expression | x* xx* | zero or more consecutive x' s one or more consecutive x's |
|
| .* | zero or more characters |
|
| w.*s | w followed by zero or more characters followed by an s |
[chars] | any character in chars | [tT] [a-z] [a-zA-Z] | lower- or uppercase t lowercase letter |
[^chars] | any character not in chars | [^0-9] [^a-zA-Z] | any nonnumeric character any nonalphabetic character |
{min,max} | at least min and at most max occurrences of previous regular expressions | x{1,5} [0-9]{3,9} [0-9]{3} [0-9]{3,} | at least 1 and at and at most 5 x's anywhere from 3 to 9 successive digits exactly 3 digits at least 3 digits |
(...) | store characters matched between parentheses in next register (1-9) | ^(.) ^(.) | first character on line and stores it in register 1 |
Cat and cut
Cut just as its name, can be used bycutting information u need from a file.
I just find this is no good to learn thesecommands right now, since they are not needy yet. I will go back to them once Ifound I need them, kets record these names.
Cut,paste,sed,tr,grep,sort,uniq. For sure Iwill go back, but it is nonsense to read them now. lets go to chapter 5.
Chapter 5. And Away we go.我暂时没有发现这本书的翻译本 所以干脆翻译些算了毕竟技术类书籍再画蛇添足怪怪的 不如翻译来的成就感大
<!--[if !supportLists]-->第五章 <!--[endif]-->让我们上路(翻得不好-_-!) 第四章是一些工具介绍估计第五章会用到那我们就从第五章开始学 学到了第四章的再回来看 反正我有原书也有电子书不费劲
通过第三章学习我们应该明白当你用 who| wc –l
的时候 你已经用shell了 因为shell会建立管道来处理这些指令 这一章我们来学如何写自己的命令和如何用shell 变量variables
指令文件commandfiles
这一部分基本上可以理解如何写一些命令的组合 然后简化到一个指令 我觉得没必要一步步来 如果你写过dos的批处理指令的话 那我们可以直接从下边这个文件开始
文件名称 stats
我们用cat stats 来读文件内容,这个也是你要写到这个文件的
$ cat stats
date
who | wc –l
pwd
$ chmod +x stats
$ stats Try it out
Wed Jul 10 11:55:50 EDT 2002
13
/users/steve/documents/proposals
$
You can add some echo commands to statsto make the output a bit more informative:
$ cat stats
echo The current date and time is:
date
echo
echo The number of users _disibledevent="EN-US">who | wc –l
echo
echo Your current working directory is:
pwd
$ stats Execute it
The current date and time is:
Wed Jul 10 12:00:27 EDT 2002
The number of users _disibledevent="EN-US"> 13
Your current working directory is:
/users/steve/documents/proposals
$
这个就是批处理文件了 没什么可多说的 把多个指令写到一个文件里 一次执行就是了 记住要改下运行权限 $chmod +x stats;
下一部分是变量 Variables
基本上 可以这么写 要回家了 回家再说 或者明后天再议
Variable=value 变量=值
my_bin=/users/steve/bin
注意了 空格是不能在等号两边使用的
显示变量的话则需要用 $变量名来表示这个是一个变量
下一部分是变量 Variables
基本上 可以这么写 要回家了 回家再说或者明后天再议
Variable=value 变量=值
my_bin=/users/steve/bin
注意了 空格是不能在等号两边使用的
显示变量的话则需要用 $变量名来表示这个是一个变量
如果你想改一个文件名 但在原有的文件名后加个x
如果你用mv $filename $filenameX
是不行的 因为$filenameX会被认为是一个值
所以你应该用 mv $filename ${filename}X
这里是第二版和第三版的一些区别了 第二版的同志们要注意了 第三版多了一节
Built-in Integer Arithmetic 内置整形算法
POSIX标准的shell (我查了下POSIX,还发现了个国内能上的wiki) http://wiki.ccw.com.cn/POSIX
POSIX是IEEE为要在各种UNIX操作系统上运行的软件而定义API的一系列互相关联的标准的总称,其正式称呼为IEEE 1003,而国际标准名称为ISO/IEC 9945。
此标准源于一个大约开始于1985年的项目。POSIX这个名称是由Richard Stallman应IEEE的要求而提议的一个易于记忆的名称。它基本上是Portable Operating System Interface(可移植操作系统接口)的缩写,而X则表明其API的传承。
Portable Operating System for UNIX(TM)的缩写。一个标准,通过一组最小的需要被支持的功能定义了在UNIX操作系统和应用程序之间兼容的语言接口。
基本来说就是用两个小括号包含一个算式 比如
$((i+1))
echo $((i = (i + 10) * j))
$ j=$(( i < 1000 )) 如果i值小于1000 j就等于0 否则j=1 这就是逻辑了
这一节就是说用变量的过程中 可以直接进行一些数学基本运算。或者简单的逻辑(大于小于)
第六章 我能标注那个部分么
第一 我们不是非常非常菜 第二 既然是针对基础用户 基础知识难免重迭 那么就去伪存精 取其精华 找有价值的东西
这一章讲的是标注 没什么难得 我直接把有用的印出来 一带而过
单引号 双引号 (这俩必须成对出现) / 后斜杠 ` 这个我不知道怎么说 后单引号?
简单的说 ‘ ‘用来标注两个单引号之间的值是一个值 举例来说
$ cat phonebook
Alice Chebba 973-555-2015
Barbara Swingle 201-555-9257
Liz Stachiw 212-555-2298
Susan Goldberg 201-555-7776
Susan Topple 212-555-4932
Tony Iannino 973-555-1295
$ grep Alice phonebook (取出有alice的一行)
Alice Chebba 973-555-2015
$ grep Susan Goldberg phonebook (这个表示方法就不行)
grep: can't open Goldberg
Susan Goldberg 201-555-7776
Susan Topple 212-555-4932
$ grep 'Susan Goldberg' phonebook (这个就行 因为 ‘’中间的内容被认为一个值 )
Susan Goldberg 201-555-7776
不管多少分开的值被俩单引号包含 都认定为一个值
$ echo one two three four (四个值)
one two three four
$ echo 'one two three four' (一个值 空格被保留)
one two three four
说白了 单引号就把可能出现歧义或者保留字的一些东西给标注为其字表含义了
双引号
双引号和单引号差不多 区别是三个保留字符仍然具有其原有意义 不像单引号掩杀一切
这三个符号是 $ ` /
吃饭去 有时间再说了
/可以用来当作下一行的开始
也可以保留/后边的字符 比如/c$ echo />
>
基本上这些东西需要自己试验了 没什么太多可说的
、、后引号是用来发指令的 例子
$ echo The date and time is: `date`
The date and time is: Wed Aug 28 14:28:43 EDT 2002
$(…)表示这里边是个指令
$ echo The date and time is: $(date)
The date and time is: Wed Aug 28 14:28:43 EDT 2002
另外一个指令 expr 就是运算了 你把要算的式子放在后边就会得到结果
$ expr 10 + 20 / 2
20
六章了 感觉要硬性学习的东西没多少 都是些实用的 只有频繁操作才能深刻理解这些符号和指令看看第七章吧
第七章 传送参数这一章学传递函数 有很多以前的知识要被涉及到 所以要追溯这些用到的命令并且把这些知识补充下三个指令 需要重新看看 tbl nroff 和 lptbl 的资料 googled 在家里没有unix 所以直接还是去国外网站抓
|
Linux / Unix tbl command http://www.computerhope.com/unix/utbl.htm
| |||||||||||||||||||||||||||||||||||||||||
|
nroff command
|
$# 用来得到命令行中被传递的参数数量 比如
$ cat args Look at the program
echo $# arguments passed
echo arg 1 = :$1: arg 2 = :$2: arg 3 = :$3:
$ args a b c Execute it
3 arguments passed
arg 1 = :a: arg 2 = :b: arg 3 = :c:
3个参数被传递 所以 $#为3
$* 用来的到命令行中被传递的参数
$ cat args2
echo $# arguments passed
echo they are :$*:
$ args
2 a
b c
3 arguments passed
they are :a b c:
grep 用来检索文档中所有含有关键字的行
$ cat phonebook
Alice Chebba 973-555-2015
Barbara Swingle 201-555-9257
Liz Stachiw 212-555-2298
Susan Goldberg 201-555-7776
Susan Topple 212-555-4932
Tony Iannino 973-555-1295
$ grep Cheb(关键字) phonebook(文件)
Alice Chebba 973-555-2015
那$1就代表第一个参数 比如我们写个程序
一个加名字到电话本的程序
$ cat add
# Add someone to the phonebook file -- version 2
#
echo "$1 $2" >> phonebook
sort -o phonebook phonebook
$
$ add 'Billy Bach' 201-555-7618
$ cat phonebook
Alice Chebba 973-555-2015
Barbara Swingle 201-555-9257
Billy Bach 201-555-7618
Liz Stachiw 212-555-2298
Stromboli Pizza 973-555-9478
Susan Goldberg 201-555-7776
Susan Topple 212-555-4932
Tony Iannino 973-555-1295
$ cat rem
#
# Remove someone from the phone book
#
grep -v "$1" phonebook > /tmp/phonebook 从phonebook中清掉某一行 把文件写到 tmp/phonebook中
mv /tmp/phonebook phonebook 替换原文件
直接连到第n个参数
shift 参数
简单地说shift就是把存在内存里的参数左移 最左位那一位移出去 然后从右往左填 这样第10个参数就变成第九个 因为你只能吊1-9这几个数的参数 超过9就调不了了
第八章 决定,决定。
首先说个老掉牙的判断
if commandt
then
command
command
...
fi
我想基本不解释大家也知道什么意思
exit status 也可以说是return status 返回值
who | grep fred
比如这句如果grep在用户中 就返回一个0 (ture) 如果没有这个用户 就返回 1(false)
在unix中
$?用来代表当前最后一个指令的返回状态
这里用到了以前一个符号 ^ 这个符号如果用在 一个值前 比如我们用
grep “^$username” 这个就表示开始行处是$username的
test
test expression
test 就是一个判断 他返回真假值 相当于我们编程的小括号 那么用 if test expression就很明白不过是干吗的了
还有另一种test的形势 不过使用的是符号 [ expression ]
这里涉及了一些操作符号 整形的有
符号 当以下情况时返回0值
int1 is equal to int2.俩数等 | |
int1 is greater than or equal to int2. 1大于等于2 | |
int1 is greater than int2.1大于2 | |
int1 is less than or equal to int2.1小于等于2 | |
int1 is less than int2.1小于2 | |
int1 is not equal to int2.1不等于2 |
文件操作符
符号 当以下情况时返回0值
file is a directory. 文件是个目录 | |
file exists. 有这个文件 | |
file is an ordinary file. 文件是个传统、、标准文件 | |
file is readable by the process. 文件可读 | |
file has nonzero length. 文件大小不是0 | |
file is writable by the process. 文件可写 | |
file is executable. 文件可执行 | |
file is a symbolic link. 文件是个符号链接(啥意思啊) |
! 逻辑否定符号 不 这个哪里都一样了就不多说了
-a 逻辑与符号 [expression1 –a expression2] 俩都真才真 一个假都不真
()可以用 但注意括号前要加来保留其符号
[ ( "$count" -ge 0 ) -a ( "$count" -lt 10 ) ]
-o 逻辑或符号[expression1 –a expression2] 有一个真就真
else
有了if 自然有else
if expression
xxx
xxx
else
xxx
xxx
fi
没什么可说的了
exit n
结束当前程序并且返回状态n
嵌套的ifelse结构也无需多言 大家应该都懂
: 冒号代表什么都不干
if grep "^$system" /users/steve/mail/systems > /dev/null
then
:
&&和||
sort bigdata > /tmp/sortout && mv /tmp/sortout bigdata
等于
if sort bigdata > /tmp/sortout
then
mv /tmp/sortout bigdata
fi
grep "$name" phonebook || echo "Couldn't find $name"
等于
if grep "$name" phonebook
then
:
else
echo "Couldn't find $name"
fi
基本就这样了
第八章还有个case
case value in
pat1) command
command
...
command;;
pat2) command
command
...
command;;
...
patn) command
command
...
command;;
esac
没什么可多说的
第八章讲的是逻辑 前八章给我感觉都是基础知识 看看第九章吧
第九章看来也是基础 都是老面孔 基本来说就是循环了
for 和while 把格式列出来
for var in word1 word2 ... wordn
do
command
command
...
done
while commandt
do
command
command
...
done
还有until 都是熟人
until commandt
do
command
command
...
done
break
break用来中断最近的一个循环
break n
用来中断以它为核心 周围的第n层近的循环(当然包括小于n的循环)
continue n
用来中断当前循环 但继续周围第n层近的循环
放到后台 就是把要执行的语句在done后边加个&号
〉把执行的结果放到某个文件
for i in 1 2 3 4; do echo $i; done
$ if [ 1 = 1 ]; then echo yes; fi
还可以把东西如上写到一行
最后一节是个程序 有点意思 我们先看程序 后讲解过程 讲完了 估计我自己就明白了
$ cat mon
# Wait until a specified user logs _disibledevent=EN-US># Set up default values
mailopt=FALSE
interval=60
# process command options
while getopts mt: option
do
case "$option"
in
m) mailopt=TRUE;;
t) interval=$OPTARG;;
?) echo "Usage: mon [-m] [-t n] user"
echo " -m means to be informed by mail"
echo " -t means check every n secs."
exit 1;;
esac
done
# Make sure a user name was specified
if [ "$OPTIND" -gt "$#" ]
then
echo "Missing user name!"
exit 2
fi
shiftcount=$((OPTIND – 1))
shift $shiftcount
user=$1
#
# Check for user logging _disibledevent=EN-US>#
until who | grep "^$user " > /dev/null
do
sleep $interval
done
#
# When we reach this point, the user has logged _disibledevent=EN-US>#
if [ "$mailopt" = FALSE]
then
echo "$user has logged _disibledevent=EN-US>else
runner=$(who am i | cut -c1-8)
echo "$user has logged _disibledevent=EN-US>fi
$ mon -m
Missing user name!
$ mon -x fred Illegal option
mon: illegal option -- x
Usage: mon [-m] [-t n] user
-m means to be informed by mail
-t means check every n secs.
$ mon -m -t 600 ann & Check every 10 min. for ann
[1] 5792
当我们运行 mon -m -t 600 ann & 的时候,紧接着发生的是while循环:然后getopts就被执行了 这个指令格式如下
getopts options variable
getopts air option
选项 变量
也就是说a i r 分别被当作可选项存到了option这个变量当中
他把m存到了option中 并且设OPTIND 为2, 返回一个0得返回值.case这时候被执行来看什么指令被存在这个m的选项中。然后含m的那一项选择了发邮件,所以mailopt设成了真(?在这里需要被标注)
第二次getopts被执行, getopts把t存到了option中,把后边接的参数600存到了OPTARG中,并把OPTIND设成3,继续返回了0。这个时候t的这个部分的代码把这个OPTARG中所存的600存到了 变量interval中
第三次getopt被执行,直接返回一个0,并且说明已经没有更多的选项了。 这时候程序会检查OPTIND的值对照$#来确定用户名被输入了,如果OPTIND大于$#(参数值),这说明用户名没有输入。反之,$1将通过shift OPTIND-1次来存入下一个参数,也就是用户名.
剩下的没啥了。除了用interval的值来决定睡眠时间。我是看懂了 现在回去对照程序再来一遍这章就结束了cheers
这一章最后一节不错 练习也不错 找个时间把所有的练习作一遍 真正巩固下对这些知识的理解。
下面开始第十章 read和printf数据
看到这俩估计本章会非常快结束了
read 输入
printf输出 计算机发展了n年 这俩没啥变化 回头练习 看下一章算了
第十一章 你的环境 这个看起来相当的不错
从第十一章开始 感觉有些东西和我工作息息相关了
第一节 本地变量 也就是说 我们写的shell中 变量属于shell变量 和进入Unix后的shell不属于一个shell所以两者不等价 (好比class)
第二节 输出变量
那如何将本地变量输入到其他shell中呢?
export variables
export 就是把当前的变量传到子shell中
export –p 把当前所有的环境变量传到子shell中