在 BBS上看到了Shell十三问的帖子,由于比较就远了,怕以后再也找不到了,就把笔记贴过来了,
原帖地址:
shell 十三问
http://bbs.chinaunix.net/thread-2033675-1-1.html
贴出我做的笔记:
<一>、为何叫做shell
使用者通过shell(操作系统即核心kernel的外壳)与kernel沟通,这是shell与kernel的命名的关系。
从技术角度讲,shell的最简单定义是——命令解译器( Command Interpreter )
/etc/shells 中存放着系统预装的好几种shell
大部分的linux 系统的预设 shell 都是 bash,原因:
*自由软件
*功能强大
<二>、shell prompt(PS1) 与 Carriage Return(CR)的关系?
$: 给一般使用者账号使用
#: 给 root(管理员)账号使用
shell prompt 的意思很简单:
是 shell 告诉使用者:您现在可以输入命令行了,使用者只有在得到 shell prompt 才能打开命令行,而 cursor(光标) 是指示键盘
在命令行所输入的位置,使用者每输入一个键,cursor 便往后移动一格,直到碰到命令行读进Carriage Return 字符为止。
Carriage Return 的意思也很简单:
是使用者告诉 shell:老兄你可以执行我的命令行了。
不同的命令可接受的命令行格式或有不同,一般情况下,一个标准的命令行格式为:
command-name options argument
若从技术细节来看,shell 会根据 IFS(Internal Field Seperator)将 command line 所输入的文字给拆解为“字段”
然后再针对特殊字符(meta)先作处理,最后在重组整行 command line. (注意:请务必理解上面两句话的意思,我们日后 的 学习中会经常回到这里思考。)
每一个命令行均必须含有命令名称,这是不能缺少的。
<三>、 别人 echo、你也 echo, 是问 echo 知多少?
承接上面所介绍的 command line, 这里我们用 echo 这个命令加以进一步说明,标准的 command line 饱含三个部件:command_name option argument
echo -e "a\t" -e选项是打开反斜杠控制字符
<四>、 ""(双引号)与‘‘(单引号)差在哪?
hard quote: ‘‘ 单引号,凡在hard quote 中的所有系统保留关键字meta 均被关闭。
soft quote: "" 双引号,在soft quote中大部分的meta 都会被关闭,蛋某些则被保留(如 $)
escape: \ 反斜线,只有进阶在 escape(跳脱字符)之后的单一 meta才被关闭。
<五>、 var=value? export 前后差在哪?
所谓的环境变量就是那些会传递给子行程的变量
遗传性 是区分本地变量与环境变量的决定性指标
var=value 赋值只是给局部变量赋值
export var=value 则是给环境变量赋值
unset var 对var变量取消,与对其赋值为NULL 是不一样的
<六>、exec 跟 source 差在哪?
了解 父进程(parent process) 和子进程(child process)的区别,父进程产生子进程,子进程结束后将返回到父进程去,子进程继承父进程的环境变量。
命令脚本(shell script):就是将平时在 shell prompt 后所输入的多行 command line 依序写入一个文件中去而已。
其中再加上一些条件判断、互动界面、参数运用、函数调用、等等技巧,得以让 script 更加聪明的执行、。
结合上面两个概念(process + script),便不难理解下面这句话的意思了
正常来说,当我们执行一个 shell script 时,其实是先产生一个 sub-shell 的子进程,然后sub-shell 再去产生命令行的子进程。
一般我们跑的 shell script 是用 sub-shell去执行的。当用 subshell 来跑 script 的话吗sub shell 的workding dir($PWD) 会因为 cd 而变更,
但当返回 primary shell 时,$PWD 是不会变更的。
source
所谓 source 就是让script 在当前 shell 内执行、而不是产生一个 sub-shell来执行。
因此,只要我们将原本单独输入的script 命令行变成 source 命令的参数,就可以轻易解决上面提到的问题啦
./my.sh
可以变为
source ./my.sh 或 ../my.script
exec 也是让 script 在同一个进程上执行,但是原有进程则被结束了。这就是 exec 与 source/fork 的最大差异了
<七>、 ()与 {} 差在哪?
命令群组(command group):将多个命令集中处理。。
()将 command group 置于 sub-shell来执行,也称 nested sub-shell
{} 则是在同一个 shell 内完成,也称 non-named command group
function 就是用一个名字去命名一个command group,然后再调用这个名字去执行 command group.
<八>、 $(()) 与 $() 还有 ${} 差在哪?
$() 与 ``(反引号)都用来做命令替换用的。
所谓的命令替换与我们学过的变量替换差不多,都是用来重组命令行:完成引号里的命令行,然后将其结果替换出来,再重组命令行。
<九>、$@ 与 $* 差在哪?
$@ 与 $* 在一般时都可以获得函数的所有参数
但是,当 $@ 与 $* 处在 hard quote即 ""中时,表现出的区别是:
$@ 会将所有的参数挨个返回
$* 会将所有的参数拼成一个字符串返回
$# 可以返回参数的总数 (不包括 $0,即路径)
${10} 通过${}可以获得超过10的参数,否则会将$1拼接0返回
<10>、 && 与 || 差在哪?
A=123
[ "$A" = 100 ] 可以用来判断A 是否等于100
上面的格式会返回一个返回值,若返回值为 0则代表判断正确,返回值为 1代表判断错误
每个命令执行完之后均由一个返回值,跟上面的含义相同
[ "$A" = 100 ] && echo "yes,\$A is 100" 意思是 && 前面的返回值为 ture时 执行后面
[ "$A" = 100 ] || echo "no,\$A is not 100" 意思是 || 前面的返回值为 false时 执行后面
一行命令中可以有多个 && 与 || 嵌套使用,如 [ "$A" = 100 ] || echo "no" && ls -G && echo "yes"
<11>、 、、、、原帖子被丢了。。。。。
<11.1>、stdin 与 stdout
<11.2>、 stderr 及如何改变File Descriptor 的预设数据通道
<12>、 你要 if 还是 case 呢
if:
# if [[ "$A" = 123 ]]; then
# echo "oh,Yes"
# elif [[ "$A" < 123 ]]; then
# echo "oh , \$A > 123"
# else
# echo "what"
# fi
case:
# case "$1" in
# start )
# echo "what is start";;
# stop )
# echo "hei,that is stop";;
# ok )
# echo "en , en A";;
# esac
<13>、 for what? while 与 until 差在哪?
....