初学shell
时间:2007-12-24 来源:wangshixian
ftp://www.vodzy.com/╃%20学习视频资源版╃/【外国语学习视频发布区】/计算机专业英语教程
http://58.251.57.67/down?cid=16CB0EFF61F3B26C7DC781EC303F5E3627CA9B87&t=3&fmt=-
学习shell
今天学习shell第一课,来自 chinaunix shell 论坛的网中人。
笔记:
shell是计算机内核和我们交换的界面Interface,也可以理解成 kernel+shell+..=operating system.
每次我们log in,都是取得一个互动模式的shell,也称login shell或primary shell。从 process的角度说我们在shell下运行的命令就是一个shell的字shell (sub shell)。
不同的操作系统有不同的kernal,同一个kernal可以有几种不同的shell,比如linux系统的shell可以有:
/etc/shells 2大主流
sh burne shell (sh) ,burne again shell (bash)
csh c shell (csh), tc shell ,korn shell (ksh)
bash 是主流的shell,自由软件,功能强大,有gun project 最成功的产品。
IBM AIX的默认shell是 ksh
shell第二课
笔记:
本讲主要讲: shell prompt (PS1)shell提示符 和 Carriage Return (CR)回车
我们把登陆后不断闪烁的光标称为 cursor,提示符 prompt ,$: 普通用户, #:root管理员
注意cursor告诉我们光标在那里,prompt提示我们可以数据字符了,每次输入一个字符cursor后移动一个位置直到读进CR (Carriage Return,由Enter产生)字符为止。CR的意思就是告诉shell可以执行我的命令了。严格来说,所谓的命令行就是在 shell prompt和CR字符之间输入的文字。注意:CR和回车有区别。
格式: command-name options argument
从技术细节上讲,shell会依据IFS Internal Field separator 将command line输入的文件给拆分为字段word然后再针对特殊字符meta先做处理,最后在重组命令行command line。
IFS是shell与设置使用的分割符号,可以由一个及多个如下按键构成:
* 空白建 white space
* 表格键 Tab
* 回车键 Enter
系统可以接受的命令名称可以从如下途径获得:
* 明确路径所指定的外部命令
* 命令别名 alias
* 自定功能 function
* shell内奸的命令 bulit-in
* $ PATH下的外部命令
第三讲 本讲主要内容是 echo
command_name option argument
echo 将argument输出到标注输出,通常是monitor上输出。
**********************************************
$
$ echo
$
**********************************************
只是您只是会发现一个空白行,然后又回到了shell prompt上了,这是因为echo显示完argument后还会送出一个换行符号(new-line character),但是上面的command并没有任何argument,那么就只剩一个换行符号了
若你要取消这个换行符号可以输入
$ echo -n
$
这种情况下command line只有command_name(echo)及option (-n),并没有任何argument。
练习 echo first line , echo -n first line
**********************************************
$ echo hello
hello
$ echo -n hello world
hello world$ # 注意prompt符号并没有换行。
**********************************************
来看echo的其他option
\a:ALERT / BELL (從系統喇叭送出鈴聲)
\b:BACKSPACE ,也就是向左刪除鍵
\c:取消行末之換行符號
\E:ESCAPE,跳脫鍵
\f:FORMFEED,換頁字符
\n:NEWLINE,換行字符
\r:RETURN,回車鍵
\t:TAB,表格跳位鍵
\v:VERTICAL TAB,垂直表格跳位鍵
\n:ASCII 八進位編碼(以 x 開首為十六進位)
\\:反斜線本身
练习:
**********************************************
# echo "a\tb\tc\nd\te\tf"
a b c
d e f
#
**********************************************
这里用\t来区隔 abc中间加tab, 用\n将def换行
**********************************************
# echo "a\tb\tc\nd\te\bf\a"
a b c
d f
#
**********************************************
因为e后有输出键\b所以字母e没有了。
第四江 今天主要讲 “”双引号,和‘’单引号的区别,越来越难了,注意阿
command line的每个character,分为如下2种:
literal , 也就是普通文字,对command line时顺序说明
meta , metadata对shell来说,遇有特殊功能,特殊保留的字元。
这里主要讲 meta,主要的meta包括
IFS,用来拆解每个词word用的,因为shell command line是按照词来处理的
CR , 由Enter 产生,用来结束command line的。
=,变量设定
$,作变量或运算替换,不要与shell prompt混淆了
>,重订向 stdout
<, stdin
|,管道
&,重订向file descriptor,或将命令置于后台执行
(),将其内的命令置于 nested subshell执行,或用于运算或命令替换
{},将其内的命令置于 nod-nested subshell执行,或用于运算或命令替换
;,在前一个命令结束时,忽略其返回值,继续执行下一个命令
&&,在前一个命令结束时,若返回值为true,继续执行下一个命令
||,在前一个命令结束时,若返回值为false,继续执行下一个命令
!,执行history 列表中的命令
假如我们需要在command line中需要将这些保留的字源的功能关闭的话,就需要quoting处理了。
hard quote ''但引号,凡是在单引号中的所有meta均被关闭
soft quote " " 双引号,凡是在soft quote中的大部分meta被关闭,但是$保留。
escape \ 反斜线,只有紧接在escape后的单一meta才被关闭。
**********************************************
# a=b c
ksh: c: not found.
# echo $a
# echo $daf
# a="b c"
# echo $a
b c
# a='b
> c
> '
# echo $a
b c
#
# echo "$a"
b
c
**********************************************
enter的特殊性
enter在“”或‘’中会被解释成IFS,而不是new linue。
enter在\后会被取消CR功能,也不会保留IFS功能,也就是说/后的enter会彻底取消意义。
**********************************************
“” 和‘’的区别就是对$功能是否失效
# a=b\ c
# echo $a
b c
# echo "$a"
b c
# echo '$a'
$a
#
**********************************************
加深记忆,把自己搞晕,请看以下输出为什么
$ A=B\ C
$ echo '"$A"' # 最外面的是單引號
"$A"
$ echo "'$A'" # 最外面的是雙引號
'B C'
$
**********************************************
第五讲 今天主要讲的内容是变量 var value variable
所谓的变量就是用特定的name来存取一段可以变化的值value
格式 name=value,要如下规则:
等号左右两边不能使用IFS,也避免使用meta character
变量名称不能使用$符号
变量名称的一个字符不能使数字number
变更两长度不能超过256个字母
变量名称及变量值之大小写事有区别的 case sensitive
注意$符号可以在变量值内例如
**********************************************
[root@ftp ~]# d=f
[root@ftp ~]# e=$d
[root@ftp ~]# echo $e
f
[root@ftp ~]#
**********************************************
变量替换 substitution
**********************************************
例如
[root@ftp ~]# a=ls
[root@ftp ~]# b=-l
[root@ftp ~]# c=/tmp
[root@ftp ~]# $a $b $c
drwxr-xr-x 2 root root 4096 12 ?18 03:10 1
-rwxr-xr-x 1 root root 107 12 ?18 03:12 del.sh
drwx------ 2 admin administrators 4096 12 ?20 05:39 ssh-VUlUtYK581
[root@ftp ~]#
**********************************************
注意变量不同于简单的数学=号
例如
**********************************************
[root@ftp ~]# a=b
[root@ftp ~]# b=c
[root@ftp ~]# echo $a
b
[root@ftp ~]# b=$a
[root@ftp ~]# echo $b
b
[root@ftp ~]#
**********************************************
注意 变量的值为空和unset变量是不一样的;例如
$ a=
$ echo $a
$ unset a
$ echo $a
第六讲 今天主要讲exec 和 source的差别
一般我们执行某个脚本都是在现有父进程parent process产生一个子进程chirld process,这种现象在Linux系统中称为fork。
如果想让现在执行的某个脚本不产生子进程,就在当前进程下执行,用source命令调用就可以了
例如
**********************************************
[root@ftp tmp]# more 1.sh
aa=bb
export aa
[root@ftp tmp]# ./1.sh
[root@ftp tmp]# echo $aa
[root@ftp tmp]# source ./1.sh
[root@ftp tmp]# echo $aa
bb
[root@ftp tmp]#
**********************************************
再说exec与source/fork的关系,exec让script在同一个进程上执行,但是原有的进程被结束了。也就是说原有的进程是否终止,就是exec与source/fork的最大区别了。
看如下2个脚本,然后运行 ./1.sh source , ./1.sh exec , ./1.sh 看结果。
**********************************************
[root@ftp tmp]# more 1.sh
#!/bin/bash
a=b
echo "PID for 1.sh before exec/source/fork:$$"
export a
echo "1.sh: \$a is $a"
case $1 in
exec)
echo "using exec..."
exec ./2.sh;;
source)
echo "using source..."
source ./2.sh;;
*)
echo "using fork by default..."
./2.sh;;
esac
echo "PID for 1.sh after exec/source/fork:$$"
echo "1.sh: \$a is $a"
**********************************************
[root@ftp tmp]# more 2.sh
#!/bin/bash
echo "PID for 2.sh:$$"
echo "2.sh get \$a=$a from 1.sh"
a=c
export a
echo "2.sh: \$a is $a"
**********************************************
第七讲 今天我们讲()和{}
()和{}主要用于命令群组的概念 ,也就是在一行命令中让特殊的几个部分先执行,而不是从左到右执行,有点类似于算数的 2*(3+4)
()...将command gorup置于sub-shell去执行,,也称为 nested sub-shell,也就是说用子进程方式执行,
{}...将command gorup置于no-sub-shell去执行,,也就是说在同一个进程内完成。
function,就是用一个名字去命名一个command group,然后再用这个名字去执行command group,从non-named command group来推断,我们用{}来讲。
可以把function理解成函数,但是他与函数还有很大的区别,唯一相同的是他们都可以被调用,
在redhat linux中有个文件很有意义,可以来看看/etc/rc.d/init.d/functions
function定义的方法有2种
function function_name {
command1
command2
command3
....
}
或
fuction_name () {
command1
command2
command3
....
}
然后直接在command line 中输入function就可以使用了。
argument
Internal Field Separator
字段
分隔