关于子shell, subshell 参考:http://blog.csdn.net/sosodream/article/details/5683515
系统引导时的进程为 "原始进程" id=0, 然后时init 进程, 进程号=1, 后面所有的进程都是它派生出来的. 如果父进程终止导致留下 孤儿 (子进程) 也会被 init所收养.
子进程的创建过程: fork+exec: fork由父进程创建子进程的环境; 然后由exe加载子进程代码并执行.
shell创建子进程有 四种情况: 后台执行时&; 管道执行时 |; 括号执行时(); 执行外部的程序或命令时.
但是shell也提供了(有两个不会创建子进程, 直接在当前shell中执行的命令)就是 source和点号命令.
shell的变量类型: shell变量和shell 环境变量.
区别是: shell变量只能在当前shell中有效, 而不能在 其子进程中(子shell)中有效.
shell环境变量, 可以在当前shell 及其 subshell中 有效.
但是 不管是什么shell变量(包括shell环境变量), 都只是针对当前shell "当前这个 shell 窗口" 有效的. 即使是在shell中定义的 export环境变量, 也不能在 其他 shell 窗口中生效! 也就是说, 所谓的export是针对 "一个shell窗口的" subshell 子进程而言的. 而两个 shell窗口是独立的进程. 当然不能共享.
两个"shell窗口"间不能共享"export变量", source和点号命令不创建subshell
注意: echo $一个变量, 如果有值, 则输出该变量的值, 否则会输出一个空行(包括纯粹的echo命令, 也会输出一个空行)
================
shell脚本什么时候,需要 添加可执行 属性才能执行?
一个原则, 如果直接运行 该脚本文件, 不借助于 外部的命令 来执行, 则需要设置脚本文件的 可执行属性, 否则会提示 permission denied . 因为在脚本中已经指名了 执行该脚本的程序, 就是用bash来执行的.
反之, 如果借助外部命令, 如: bash, .点命令, source 则不需要设置 脚本的executable 属性, 甚至不必 写 #!/bin/bash.
为什么要用 ./foo.sh 来执行脚本
因为, 如果shell 没有扫描到 ./ 就会把它当作 $PATH 中的目录中的命令 去搜索 执行, 就会报错"foo.sh command is not found. " 的错误.
sh脚本异常:/bin/bash^M: bad interpreter: No such file or directory ?
在这里是把 bash^M, 作为一个整体的 shell解释器, 当然是没有这样的解释器了.
为什么会多一个 ^M 呢?
这个是不同系统的换行符不同引起的.windows的换行符一般都是用\r\n 而Linux/Unix一般只用\n 如果在linux下用\n换行的文本, 用记事本打开时会没有换行,而用\r\n结尾的文件再linux的vi中显示时会将\r显示成^M
\r是回车符,\n是换行符
电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符, (每个字占0.1秒). 但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把 打印头 定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历, \r: return 回车; \n newline 新行, 换行
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。 于是,就出现了分歧。Unix 系统里,每行结尾只有“ ”,即“\n”; Mac系统里,每行结尾是“”, 即 "\r", Windows系统里面,每行结尾是“”,即“ \r\n”;。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行: 因为没有回车; 而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号: 其中的\r 变成^M, 而\n就成为 unix的换行了.
解决方法, 就是, 在vi中, 查看文件格式, set fileformat; 或, set ff=file format. 在windows中创建的就是 ff=dos, 只要重新设置一下, set ff=unix就可以了.