2008年11月28日星期五

Unix.Power.Tools : 1 - 10

程序通过系统调用与内核交互。
用户与shell交互,shell解释用户指令,直接执行该指令(比如内置的cd)或将指令传给其他程序执行(比如外置的cat)。
shell执行内置指令时不会单独新建一个进程,而执行外部指令时需要fork+exec一个子进程。
shell找用户指令顺序:内置指令->绝对路径文件名->检查path中的路径。
注意有些程序的输入是由shell传入的,如cat/ls之类;而有些程序是由用户直接与程序交互进行输入的,如vi之类,shell此时的作用仅是负责启动该程序。
sort -u 相当于 sort|uniq。
在/etc/passwd里面可以改用户默认shell。
exec是内核以新进程替换旧进程执行。
fork是把原来的进程原样拷一份出来。
可以先fork一个子进程,再在这个子进程里exec,执行完之后就自己关掉了。
内核管理负责进程占用内存的调度,时间片分配,I/O控制,等等。
shutdown让所有用户退出系统,并保证后台daemon没在搞磁盘。
sync确保磁盘操作全部结束。
*?等通配符由shell解释,如ls *。
可以用{}省打一些字,如tar xv project/wk{9,14,15}/summary。
inode用于描述一个文件,每个inode有个唯一的标识符称为i-number。
文件系统被创建时,会创建若干inode,这些inode的数目是该文件系统能容纳的最大文件数。只要不重新初始化文件系统,就不能改变这个数目,否则会损坏该文件系统上所有的数据。当文件系统中有很多小文件时,有可能会将inode用光。
引自:控制对文件的访问
对目录设置粘滞位。粘滞位是每个文件的模式中的一个特殊位。设置粘滞位可阻止用户从该目录中删除其他用户的文件。通过设置目录的粘滞位,只允许文件属主、目录属主、或者具有相应权限的用户删除或重命名文件。
引自:深入理解linux的权限设置和SUID,SGID,粘滞位
setuid: 在执行时具有文件所有者的权限。 setgid: 在执行时具有文件所在组的权限。一个目录被标上setgid位,此目录下创建的文件继承该目录的属性。 sticky bit: 该位可以理解为防删除位。设置sticky bit位后,就算用户对目录具有写权限,但也只能添加文件而不能删除文件。
rwsrw-r-- 表示有setuid标志 (rwxrw-r--:rwsrw-r--) rwxrwsrw- 表示有setgid标志 (rwxrwxrw-:rwxrwsrw-) rwxrw-rwt 表示有sticky标志 (rwxrw-rwx:rwxrw-rwt)
在目录中新建、重命名、删除文件需要修改目录列表,因此需要对目录的写权限。
而在目录中修改文件不需要修改目录列表,因此不需要对目录的写权限。
列出目录内容需要对目录的读权限,但即使你没有对目录的读权限仍可直接指定文件名来访问该目录下的文件。
如果一个目录没有执行权限(其实是叫search bit),那么对该目录下所有内容啥都没法搞。
CTRL-Z中止前台任务,bg将该任务扔到后台并继续执行之。
fg将后台任务调到前台。在后台任务执行到一半要你输东西进去的时候比较好用。
jobs查看所有后台进程。
要在后台等15s再执行ls必须
$ ( sleep 15; ls ) &
如果是
$ sleep 15; ls &
会在前台等15s再跑去后台执行ls。
在一些交互式程序(比如vi)中,如果中间想回到shell,可以CTRL-Z一下,敲完命令再fg回原来程序界面。这样会比在vi中用:!cmd速度快,因为前者是跑回原来的shell执行指令,而后者是新建一个shell啦。
nohup防止由于用户退出导致后台进程终止。
前台任务的优先级比后台任务高,可以用nice调整后台任务优先级。
蛮多可执行文件开头有所谓的magic number,这个是一个2字节长的序号,告诉内核如何执行该文件。
X可以同时显示多个同步进行的终端会话,多个程序在不同的窗口前台执行。

2. Logging In

用户登陆到UNIX系统,login程序会为其启动一个shell。
login程序设置一个特殊的flag,告诉shell说它是个login shell。
xterm -ls启动一个login shell,而xterm +ls启动一个non-login shell。

一个subshell绝不会是login shell。
()被称为subshell操作符,不读取初始文件,启动当前shell的另一实例。

login bash将读取.bash_profile,.bash_login,或.profile。
bash subshell,注意它不是一个login shell,会读取.bashrc。
一个login shell结束时会读取.bash_logout。

在shell的配置文件中使用绝对路径名!

3. Logging Out

删除昨天没被修改过的文件:
find ~/temp −type f −mtime +1 | xargs rm −f &

4. Organizing Your Home Directory

可以多建些目录,那样文件好找点。
而且目录相对较小时,UNIX存取文件速度也快点。

mkdir −p /src/books/power/articles/files -p:中间路径不存在也会自动建好。

% mkdir /src/books/power % !!/articles mkdir /src/books/power/articles % !!/files mkdir /src/books/power/articles/files

mkdir −m 755 /src/books/power/articles/files
-m:建目录时顺便指定权限。

5. Setting Up Your Terminal

vi之类的全屏编辑器uses the terminal screen non−sequentially(这句还上原文吧!)。
non−sequentially output的程序不是一个字符接一个字符的打出来的,在送出字符前自己会对文本做些处理,比如滚屏,光标移动等等。
统一的操纵屏幕的机制:描述每种terminal能支持的操作的数据库,允许其他程序查询、使用该数据库的子程序库。
这个数据库以前是用文本格式的统一的termcap,现在是用二进制的terminfo,每种terminal有个单独的文件(按字母表存到各个子目录中)。/etc/termcap,/usr/lib/terminfo。
用 到termcap/terminfo的程序首先看$TERM环境变量确定terminal类型,然后读入对应类型的terminal的数据库中定义的、该 terminal能支持的、该程序需要用到的信息(teminal会跟vi说它自己多大,光标咋移,屏幕怎么刷新,等等)。比如clear程序只要知道怎 么清屏,vi就要用到整个terminal description了。
termcap/terminfo中存有escape sequences,就是输入一些特殊键时屏幕的处理啦。比如ESC是^[。
假设默认的erase key(就是把前面的一个字符删掉的键)是DELETE(^\?),现在换成BACKSPACE(^h):stty erase ^h。

7. Setting Your Shell Prompt

如果想显示的信息多一点,然后又有空间留下来打命令,可以试试用多行的prompt。
ESC[1m 粗体,强调 ESC[4m 下划线 ESC[0m 关闭之前的属性
$SHLVL环境变量让你跟踪到底在当前shell下的第几层子shell。
蛮多UNIX命令输出从第1列开始,也就是起头空4格啦。
目录栈的相关命令:dirs, pushd, popd

8. How the Shell Interprets What You Type

shell是负责解析用户输入的命令的程序。
shell一般会将命令分词,展开别名,处理历史操作符,替换shell变量及环境变量等等。
禁止文件描述符在一条命令里边同时作输入输出。否则 cat file1 file2 > file1会出问题:先清空file1,然后把file1,file2的内容输入file1,最后file1里面是原来file2的内容。
echo “xxxx” 1>&2是把echo的输出重定向到STDERR。
b=\$a;eval echo $b;相当于echo $a,eval的作用是再执行一次命令解析啦。
cat food 2>&1 >file是先指定STDERR与STDOUT一起(这两个本来就是一起输到终端的,所以2>&1写了等于没写),然后把STDOUT重定向到file,而STDERR没有到file里去。
cat food >file 2>&1是先把STDOUT重定向到file,然后指定STDERR跟STDOUT一起,所以最后STDOUT跟STDERR都会到file里边。
expr 2 \* 3会输出6啦,作计算。
set –xv这个设了之后执行shell script可以看变量啦,湊合记着。
$(..) 命令置换
((..))算术赋值
(cmd;cmd)子shell中进行命令
{cmd;cmd; }与(cmd;cmd)相同,只是没有子shell
<<<\word Read until word, no substitution.
<<−word Read until word, ignoring leading TABs.
<&m 将m的内容输入到STDIN
<&− 关闭STDIN.
>&m 将m的内容输出给STDOUT
>&− 关闭STDOUT
m<&n 将n内容输入给m
m<&− 关闭m输入
n>&m 将n内容输出给m
m>&− 关闭m输出
CTRL-U删掉行内光标前的所有字符
CTRL-W删掉行内光标前的一个词
CTRL-R历史命令的高级搜索
for file in a.c b.c
do
cat $file
done
vi `grep –l error *.c`中,``内的指令输出内容作为vi的输入参数。
在``内,换行符跟空白符同时作为指令的参数分隔符。
cat file.txt|cut –c1-8取出file.txt的前8列数据。
rm `cat file.txt`如果file.txt内容太多,导致rm的输入参数超出限制,shell可能会报错。可以用xargs解决此问题。
cat file.txt|xargs rm
xargs从stdin中读入一定大小的内容,以这些内容为参数执行rm,直至读完所有内容。就是每次读一些文件名,删掉这批文件,如果还没读完,就继续读继续删,直到eof。
xarg的-p参数可以在每次执行时都进行确认。
xargs的-n参数可以指定每次读入的参数个数。
% ls chap1.bad chap1.fixed chap2.bad chap2.fixed ... chap9.bad chap9.fixed % ls | xargs −p −n2 diff −c diff −c chap1.bad chap1.fixed ?...y ...Output of diff command for chap1... diff −c chap2.bad chap2.fixed ?...n diff −c chap3.bad chap3.fixed ?...y ...Output of diff command for chap3...
如果碰到包含空格或换行符的文件名,xargs会出错。解决方法:
find . –type f –print0 | xargs –0 rm
find的-print0选项指定以NUL而不以换行符分隔路径。
xargs的-0选项指定以NUL而不以空格分隔路径。
UNIX的路径不会包含NUL,所以可以这样搞。
<(process)运行process指令,并将其输出内容传给一个命名管道,然后该命名管道的文件名将作为命令行参数传递。
比如comm <(sort file1) <(sort file2),如果预先set -x还可以看到:
bash$ set −x bash$ comm <(sort file1) <(sort file2) + comm /tmp/sh−np−a11167 /tmp/sh−np−b11167 ++ sort file1 ++ sort file2 foo newprogram rcsdiff.log runsed runsed.new
其中,comm前面的+表示顶层process,sort前面的++表示二层的process。
剩下的是comm比较结果, 第一栏是只在前一个文件中出现的行,第二栏是只在后一个文件中出现的行,第三栏是在两个文件中都出现的行。
命令执行结束后,/tmp下的命名管道将被删除。

!$上一条指令的最后一个参数。
vim中 30| 表示跳到第30列。

没有评论:

发表评论