阅读之前,请务必花30秒查看前言说明(在第一、二章前面部分)
《Unix & Linux 大学教程》 - 第一、二章 学习笔记 Unix简介 & 什么是Linux?什么是Unix
>>>>和<<<<之间的内容为没有理解的部分,希望看到文章的各位,如果知道原因,希望能给予解释,感激不尽。
第十一章:shell
基础知识
启动shell
如果系统中存在该shell,那么只需键入shell的名称即可
Shell | 程序名称 |
Bash | bash/sh |
Bourne Shell | sh |
C-Shell | csh |
FreeBSD Shell | sh |
Korn Shell | ksh/sh |
Pdksh | ksh |
Tcsh | tcsh/csh |
Zsh | zsh |
一些系统将比较新的shell替换了旧shell,因此无法找到Bourne Shell或者C-Shell,键入sh得到的是Bash或者是Korn shell;键入csh得到的是tcsh。
改变使用的shell
首先查看哪些shell可用
临时改变shell只需在shell中输入shell名称就能启动新shell。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
(结果有这么多,可是当我输入csh的时候却找不到,难道需要设置环境变量?ksh也一样
$ ksh The program 'ksh' can be found in the following packages: * pdksh * zsh * ksh * mksh Try: sudo apt-get install <selected package>
我觉得:列表中的shell,是说系统可以使用的shell类型,并不是说系统已经安装了这些
当我安装了ksh一遍之后,结果变成了下面这样
su1216@su1216-OptiPlex-380:~$ ksh $ echo $SHELL /bin/bash $
为什么这里还是bash。。。)
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Unix有两个文件用来描述系统中的所有用户标识。
/etc/passwd(口令文件,包含每一个用户标识的基本信息)
/etc/shadow(影子文件,包含每一个用户标识的实际口令,加密过的)
Unix会从这两个文件中哦个检索用户标识相关信息。
/etc/shells存储了可用shell的路径名(Linux和FreeBSD使用此文件)
chsh [-s shell] [userid] :修改指定用户标识登录时的shell
但是,我的机器却无法显示列表
$ chsh -l chsh: invalid option -- 'l' Usage: chsh [options] [LOGIN] Options: -h, --help display this help message and exit -s, --shell SHELL new login shell for the user account
听说是man的版本问题,于是我把系统语言切换到英文状态,下面是英文版的man
CHSH(1) User Commands CHSH(1) NAME chsh - change login shell SYNOPSIS chsh [options] [LOGIN] DESCRIPTION The chsh command changes the user login shell. This determines the name of the users initial login command. A normal user may only change the login shell for her own account, the superuser may change the login shell for any account. OPTIONS The options which apply to the chsh command are: -h, --help Display help message and exit. -s, --shell SHELL The name of the users new login shell. Setting this field to blank causes the system to select the default login shell. If the -s option is not selected, chsh operates in an interactive fashion, prompting the user with the current login shell. Enter the new value to change the shell, or leave the line blank to use the current one. The current shell is displayed between a pair of [ ] marks. NOTE ......
果然,这里还真没有l选项,看书的时候要时刻注意软件版本的问题啊!
当改变登录shell时,下次登录才会生效。
在一些特定情形中,如果系统处于危急状态,需要用root用户登录进行修复,那么有一些shell可能不能正常运行。所以不要轻易修改root用户的登录shell。
一些系统上没有chsh命令。此时需要passwd命令(p224)
环境变量:
SHELL:当前使用的shell。(echo $SHELL)
名词解释
什么是shell:shell是一个命令处理器,一个读取并解释所输入命令的程序。shell还支持一些类型的编程语言,使用该语言,可以编写由shell解释的程序,这些程序称为shell脚本。这些脚本可以包含常规的Unix命令,以及特殊的shell编程命令。
Bourne Shell家族
sh:最早的shell,1971年由Unix创建者Ken Thompson开发。(后来Mashey Shell或称PWBshell也被命名为sh。Steve Bourne开发的Bourne Shell也被命名为sh,所有兼容的shell都被认为是Bourne Shell家族成员)
ksh:1982年贝尔实验室David Korn开发,Korn Shell或称ksh。对标准shell(Bourne Shell)做了极大改进,很快永久的替代了Bourne Shell。(2000年开源)
bash:Bourne-again shell,1987年Brian Fox创建,免费,开源。现在是Bourne Shell家族最重要的成员,是Linux以及基于Unix的Macintosh的默认shell。
C-Shell家族
csh:1978年由Bill Joy基于Unix第6版的sh开发,语法类似C语言,称之为C-Shell。
tcsh:20世纪70年代末由Ken Greer开发,20世纪80年代初期,开发职责交给Paul Placeway领导的程序小组。免费,并增强了C-shell。
C-Shell不善于编写shell脚本,特别是设计到I/O方面的内容,而且还有很多设计上的缺陷(p218)。
(p218-219作者讲述了C-shell、Tcsh、C、C++、C#名称含义)
(作者根据各种shell的说明书页的字节数估计了一下相对复杂度。Bourne Shell说明书页为38000字节,最小,复杂度记为1.0。那么Bash复杂度为7.9,Zsh复杂度为20.8)
POSIX:Unix标准化项目最初由IEEE组织负责,起初该项目称为IEEE-IX。由于名字不好听,所以打算更名。自由软件基金会创始人Richard Stallman建议称为POSIX(Portable Operating System Interface)。
第十二章:使用shell:变量和选项
基础知识
一个正在运行的shell就是一个进程,任何从shell中启动的程序也是一个进程。
使用Unix shell时,有两种不同类型的变量:shell变量和环境变量。
父进程/双亲、子进程/孩子、继承
当一个进程启动了另一个进程时,第一个进程称为父进程或双亲,第二个进程称为子进程或孩子
在子进程创建时,系统为子进程复制了父进程的环境,称子进程继承了父进程的环境(子进程可以访问父进程的环境变量,但子进程对环境变量的修改不会传递到父进程)。
Bourne Shell家族的变量要么为局部变量,要么为局部变量和全局变量。如果想创建全局变量必须使用export命令。
export +变量:设置此变量为全局变量
C-Shell家族中,环境变量通过setenv创建,shell变量由set命令创建,不允许即是环境变量又是shell变量。
有些变量需要成为即是环境变量又是shell变量,C-Shell定义少数特殊的shell变量绑定到对应的环境变量上。
C-Shell双名称变量中5个常用的变量
shell变量 | 环境变量 | 含义 |
cwd(current/working directory) | PWD | 当前/工作目录 |
home | HOME | home目录 |
path | PATH | 搜索程序的目录 |
term | TERM | 正在使用的终端类型 |
user | USER | 当前用户标识 |
env/printenv:显示环境变量
部分环境变量列表
(B=Bash,K=Korn Shell,C=C-Shell,T=Tcsh,X表示相应的shell不支持该选项)
(由于我使用Bash,所以Bash不支持的我用颜色标出)
shell | 变量 | 含义 |
B K X X | CDPATH | cd命令搜索的目录 |
B K X X | COLUMNS | 屏幕或者窗口的宽度(以字符为单位) |
B K X X | EDITOR | 默认文本编辑器 |
B K X X | ENV | 环境文件名称 |
B K X X | FCEDIT | 历史列表:fc命令使用的编辑器 |
B K X X | HISTFILE | 历史列表:用来存储历史命令的文件名称 |
B K X X | HISTSIZE | 历史列表:存储历史命令的最大数量 |
B K C T | HOME | home目录 |
X X X T | HOST | 计算机名称 |
B X X X | HOSTNAME | 计算机名称 |
B X X T | HOSTTYPE | 主计算机类型 |
B X X X | IGNOREEOF | 在结束shell之前忽略的eof信号(^D)的数量 |
B K C T | LOGNAME | 当前用户标识 |
B X X T | MACHTYPE | 系统描述 |
B K C T | 查看新邮件的文件 | |
B K C T | MAILCHECK | shell查看新邮件的时间间隔(单位为秒) |
B K X X | MAILPAT | 查看新邮件的文件 |
B K X X | OLDPWD | 前一个工作目录 |
B X X T | OSTYPE | 操作系统的描述 |
B K C T | PAGER | 显示数据的默认程序(应该是less) |
B K C T | PATH | 搜索程序的目录 |
B K X X | PS1 | shell提示(通过修改这个变量进行shell提示的定制) |
B K X X | PS2 | 连续行的特殊shell提示 |
B K C T | PWD | 工作[当前]目录 |
B K X X | RANDOM | 0-32767之间的随机数 |
B K X X | SECONDS | 自shell激活之后过去的时间(单位为秒) |
B K C T | SHELL | 登录shell的路径 |
B K C T | TERM | 正在使用的终端类型 |
B K X X | TMOUT | 在不键入命令时,系统自动注销前的等待时间(单位为秒) |
X K C T | TZ | 时区信息 |
B K C T | USER | 当前用户标识 |
B K C T | VISUAL | 默认文本编辑器(覆盖EDITOR) |
set:显示shell变量
确定Bourne shell变量类型的唯一方法:在set和env输出的交集中的变量既是环境变量又是shell变量,只位于set输出中的变量为shell变量。(书中说这是唯一方法,这方法太难用了吧!真的是唯一吗)
PAGER,在env的输出中并没有它(按书中的说法这个应该有)。
IGNOREEOF,在env的输出中也没有(按书中的说法这个应该有)。
但是设置IGNOREEOF后,例如
$ IGNOREEOF=2
那么它会忽略量词eof信号,说明系统认识IGNOREEOF,IGNOREEOF是起作用的,但是env的输出中仍然没有它。
当我export IGNOREEOF后,env的输出中可以找到IGNOREEOF了。
注意:这里没有列出的是没有赋过值的,他们使用默认值。他们依然是环境变量
具体可参见我的另一个学习笔记系列
显示及使用变量的值
echo +字符串:显示此字符串,如果要显示变量,那么要在变量名前加$,比如echo $TERM,为了消除岐义,可以使用{},比如echo ${TERM},这样就不会有echo $TERMMMM的尴尬了
shell中有一些元字符,所以最好在要显示的内容外面加上引号。
su1216@su1216-OptiPlex-380:~/android/source/odin$ echo hello world hello world su1216@su1216-OptiPlex-380:~/android/source/odin$ echo $TERM xterm su1216@su1216-OptiPlex-380:~/android/source/odin$ echo ${TERM} xterm su1216@su1216-OptiPlex-380:~/android/source/odin$ echo "TERM = ${TERM}" TERM = xterm
(在Korn Shell上可以使用print代替echo,如果要移植,那么不应使用print)
Bourne shell家族使用变量
变量名=值
如果此变量之前不存在,那么这样就创建(设置)了一个变量,如果之前存在,则修改了变量的值。注意:等号两边一定不能加空格。如果值中有空白字符,可以在外面加引号。例如:
NAME="Bourne shell"
每个新变量都自动设置为shell变量。
export NAME[=value]...
将名为NAME的变量导出为环境变量,同时可以选择赋值。
unset NAME...
删除(复位)变量
Bourne shell家族中没有简单的方法从环境变量中移除变量。一旦变量被导出,收回该变量的唯一方法就是复位(销毁)该变量。
作者有如下例子:
PAGER=less;export PAGER
之前的环境变量列表中有PAGER,难道所有的环境变量必须export一下才能使用?
C-Shell家族使用变量(p239)
setenv、unsetenv、set、unset
(之后笔记不再设计大量C-Shell内容)
shell选项
set -o option:设置一个选项
set +o option:复位一个选项
set -o:显示shell选项
set +o:显示shell选项
option为选项的长名称
shell选项设置或复位的方式有两种:
当shell启动时,可以以普通的方式指定选项,即为命令指定一个或多个选项。
部分shell选项列表
(B=Bash,K=Korn Shell,X表示相应的shell不支持该选项)
(由于我使用Bash,所以Bash不支持的我用颜色标出)
shell | 选项 | 长名称 | 含义 |
B K | -a | allexport | 导出随后定义的所有变量和函数 |
B X | -B | braceexpand | 启用括号扩展(生成字符模式) |
B K | -E | emacs | 命令行编辑器:Emacs模式,关闭vi模式 |
B K | -h | hashall | 查找到命令时(记住)的命令哈希位置 |
B X | -H | histexpand | 历史列表:启用!风格替换 |
B X | history | 历史列表:启用 | |
B K | -I | ingnoreeof | 忽略eof信号^D;使用exit退出shell |
X K | markdirs | 在通配时,在目录中追加/ | |
B K | -m | monitor | 作业控制:启用 |
B K | -C | noclobber | 不允许重定向的输出替换某个文件 |
X K | nolog | 历史列表:不保存函数定义 | |
B K | -b | notify | 作业控制:当后台作业结束时立即通知 |
X K | trackall | 别名:为命令替换完整路径名 | |
B K | -V | vi | 命令行编辑器:vi模式,关闭Emacs模式 |
X K | viraw | vi模式:立即处理每个键入的字符 |
Bash使用emacs和vi选项,但是不是是哟个-E和-V
Korn Shell使用-h选项,但是不支持长名称hashall
我机器的shell选项为
$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof on interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
bash提供一个特殊的命令shopt(shell options,shell选项)可以用来访问更多的选项。
例如,当设置ignoreeof选项后:
set -o ignoreeof
按下ctrl+d则提示:
复位ignoreeof后按下ctrl+d则可关闭shell。
set +o ignoreeof
名词解释
交互式程序:与人进行沟通的程序。
非交互式程序:独立于人的程序,一般情况下,它从文件获取输入,并将输出写入另一个文件。
交互式shell:与人进行沟通的shell。
非交互式shell:运行shell脚本,shell从文件中读取命令,并在不需要输入的情况下一次处理所有的命令。
这两种情况下的shell是同一种shell - 登录shell或用户启动的shell,系统都会设置成交互式shell。运行shell脚本时,系统会设置为非交互式的,脚本执行完毕时,非交互式shell终止。
至此245页结束,之后的笔记基本不会每次记录两章了,因为后面需要掌握的内容增加,作者从历史老师开始向计算机老师过渡。
之后关于C-Shell的内容不会重点记录,只会简单记录,重要的地方加上页码,以备日后查阅。
本人blog地址
http://su1216.iteye.com/
http://blog.csdn.net/su1216/