现在的位置: 首页 > 综合 > 正文

linux知识学习 fork,source和exec运行脚本时的差异shell中${}的妙用Shell十三问学习笔记

2017年09月29日 ⁄ 综合 ⁄ 共 6034字 ⁄ 字号 评论关闭
 

fork,source和exec运行脚本时的差异

分类: [Linux]--[命令] 21人阅读 评论(0) 收藏 举报
fork
   使用 fork 方式运行 script 时, 就是让 shell(parent process) 产生一个 child process 去执行该 script, 当 child process 结束后, 会返回 parent process, 
但 parent process 的环境是不会因 child process 的改变而改变的.
 
source
   使用 source 方式运行 script 时, 就是让 script 在当前 process 内执行, 而不是产生一个 child process 来执行. 由于所有执行结果均于当前 process 内完成, 若 script 的环境有所改变, 当然也会改变当前 process 环境了.
 
exec
   使用 exec 方式运行script时, 它和 source 一样, 也是让 script 在当前process内执行, 但是 process 内的原代码剩下部分将被终止. 同样, process 内的环境随script 改变而改变.

结论:通常如果我们执行时,都是默认为fork的。大家可以通过pstree命令看看关于父子进程的关系。如上,如果想让父进程得到子进程的环境变量,就是source方式了

1.sh的脚本

  1. #!/bin/bash  
  2.   
  3. A=B  
  4. echo "PID for 1.sh before exec/source/fork:$$"  
  5. export A  
  6. echo "1.sh: \$A is $A"  
  7. case $1 in  
  8.         exec)  
  9.                 echo "using exec…"  
  10.                 exec ./2.sh ;;  
  11.         source)  
  12.                 echo "using source…"  
  13.                 . ./2.sh ;;  
  14.         *)  
  15.                 echo "using fork by default…"  
  16.                 ./2.sh ;;  
  17. esac  
  18. echo "PID for 1.sh after exec/source/fork:$$"  
  19. echo "1.sh: \$A is $A"  

2.sh的脚本

  1. #!/bin/bash  
  2.   
  3. echo "PID for 2.sh: $$"  
  4. echo "2.sh get \$A=$A from 1.sh"  
  5. A=C  
  6. export A  
  7. echo "2.sh: \$A is $A"  

3. 实验
3.1 fork

  1. PID for 1.sh before exec/source/fork:25992  
  2. 1.sh: $A is B  
  3. using fork by default…  
  4. PID for 2.sh: 25993  
  5. 2.sh get $A=B from 1.sh  
  6. 2.sh: $A is C  
  7. PID for 1.sh after exec/source/fork:25992  
  8. 1.sh: $A is B  

3.2 source

  1. PID for 1.sh before exec/source/fork:25994  
  2. 1.sh: $A is B  
  3. using source…  
  4. PID for 2.sh: 25994  
  5. 2.sh get $A=B from 1.sh  
  6. 2.sh: $A is C  
  7. PID for 1.sh after exec/source/fork:25994  
  8. 1.sh: $A is C  

注意: 三个PID都是25994, 子程序的环境变量被带了出来.
3.3 exec

  1. PID for 1.sh before exec/source/fork:25997  
  2. 1.sh: $A is B  
  3. using exec…  
  4. PID for 2.sh: 25997  
  5. 2.sh get $A=B from 1.sh  
  6. 2.sh: $A is C  

注意: 主程序的剩下部分不执行了.


 

shell中${}的妙用

分类: [Linux]--[命令] 84人阅读 评论(0) 收藏 举报
以下的内容基本从Shell13问中提取.
1. 截断功能
${file#*/}:       拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:    拿掉最后一条/及其左边的字符串:my.file.txt
${file#*.}:       拿掉第一个.及其左边的字符串:file.txt
${file##*.}:    拿掉最后一个.及其左边的字符串:txt
${file%/*}:     拿掉最后条/及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条/及其右边的字符串:(空值)
${file%.*}:    拿掉最后一个.及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个.及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
[list]#是去掉左边, ##最后一个
      %是去掉右边, %%第一个
2. 字符串提取 
单一符号是最小匹配﹔两个符号是最大匹配。
${file:0:5}:提取最左边的 5 个字节:/dir1
${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
3. 字符串替换
${file/dir/path}:将第一个 dir 提换为 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部 dir 提换为 path:/path1/path2/path3/my.file.txt
4. 针对不同的变量状态赋值(没设定、空值、非空值):
${file-my.file.txt}: 若$file没有设定,则使用my.file.txt作返回值。(空值及非空值时不作处理)
${file:-my.file.txt}:若$file没有设定或为空值,则使用my.file.txt作返回值。(非空值时不作处理)
${file+my.file.txt}: 若$file设为空值或非空值,均使用my.file.txt作返回值。(没设定时不作处理)
${file:+my.file.txt}:若$file为非空值,则使用my.file.txt作返回值。(没设定及空值时不作处理)
${file=my.file.txt}: 若$file没设定,则使用my.file.txt作返回值,同时将$file 赋值为 my.file.txt。(空值及非空值时不作处理)
${file:=my.file.txt}:若$file没设定或为空值,则使用my.file.txt作返回值,同时将 $file 赋值为 my.file.txt。(非空值时不作处理)
${file?my.file.txt}: 若$file没设定,则将my.file.txt输出至 STDERR。(空值及非空值时不作处理)
${file:?my.file.txt}:若$file没设定或为空值,则将my.file.txt输出至STDERR。(非空值时不作处理)
注意: 
":+"的情况是不包含空值的.
":-", ":="等只要有号就是包含空值(null).

5. 变量的长度
${#file}
6. 数组运算
A=(a b c def)
${A[@]} 或 ${A[*]} 可得到 a b c def (全部组数)
${A[0]} 可得到 a (第一个组数),${A[1]} 则为第二个组数...
${#A[@]} 或 ${#A[*]} 可得到 4 (全部组数数量)
${#A[0]} 可得到 1 (即第一个组数(a)的长度),${#A[3]} 可得到 3 (第四个组数(def)的长度)

Shell十三问学习笔记

分类: [Linux]--[命令] 84人阅读 评论(0) 收藏 举报
1. echo 命令所支持的反斜线控制字符如下表:
\a:ALERT / BELL (从系统喇叭送出铃声)
\b:BACKSPACE ,也就是向左删除键
\c:取消行末之换行符号
\E:ESCAPE,跳脱键
\f:FORMFEED,换页字符
\n:NEWLINE,换行字符
\r:RETURN,回车键
\t:TAB,表格跳位键
\v:VERTICAL TAB,垂直表格跳位键
\n:ASCII 八进位编码(以 x 开首为十六进制)
\\:反斜线本身

2. 常用meta
IFS:由 <space> 或 <tab> 或 <enter> 三者之一组成(我们常用 space )。
CR: 由 <enter> 产生。

3. 除了IFS与CR,常用的meta还有:
=  :设定变量。
$  :作变量或运算替换(请不要与 shell prompt 搞混了)。
>  :重导向stdout。
<  :重导向stdin。
|  :命令管道。
&  :重导向file descriptor,或将命令置于后台执行。
() :将其内的命令置于nested subshell执行,或用于运算或命令替换。
{} :将其内的命令置于non-named function中执行,或用在变量替换的界定范围。
;  :在前一个命令结束时,而忽略其返回值,继续执行下一个命令。
&& :在前一个命令结束时,若返回值为true,继续执行下一个命令。
|| :在前一个命令结束时,若返回值为false,继续执行下一个命令。
!  :执行history列表中的命令

4. quoting的三种方法
hard quote:' '(单引号),凡在hard quote中的所有meta均被关闭。
soft quote:“”(双引号),在soft quote中大部份 meta 都会被关闭,但某些
则保留(如$)。
escape:\(反斜线),只有紧接在escape(跳脱字符)之后的单一meta才被关闭。

  1. 4.1 示例1  
  2. [test@rhel5 ~]$ A="B C"  
  3. [test@rhel5 ~]$ echo "'$A'"  
  4. 'B C'  
  5. [test@rhel5 ~]$ echo '"$A"'  
  6. "$A"  
  7.   
  8. [test@rhel5 ~]$ A=B\ C  
  9. [test@rhel5 ~]$ echo "'$A'"  
  10. 'B C'  
  11. [test@rhel5 ~]$ echo '"$A"'  
  12. "$A"  
  13.   
  14. 4.2 示例2  
  15. [test@rhel5 ~]$ A="  
  16. > B  
  17. > C"  
  18. [test@rhel5 ~]$ echo $A  
  19. B C  
  20. [test@rhel5 ~]$ echo "$A"  
  21.   
  22. B  
  23. C  

# $A 时的变量没至于 soft quote 中,因此当变量替换完成后并作命令行重组时,<enter> 会被解释为 IFS ,而不是解释为 New Line 字符。

5. ()与{}这两对符号的差异
()将command group置于sub-shell去执行,也称nested sub-shell。
{}则是在同一个shell内完成,也称为non-named command group。
所谓function,就是用一个名字去命名一个command group,然后再调用这个名字去执行command group。

6. $(( ))与$( )还有${ }的区别
$( )与` `(反引号)都是用来做命令替换用(command substitution)的。在多层次的复合替换中,``须要额外的跳脱(\`)处理,而$()则比较直观。
${ }是用来作变量替换用的。
$(( ))用来作整数运算的。

7. ${ }的一些特异功能
详见"shell中${}的妙用 "

8. $$, $#, $@, $*区别?
$$: 进程ID
$#: 参数的数量
$?: 上一条命令的返回值

my.sh p1 "p2 p3" p4
"$@" 则可得到 "p1" "p2 p3" "p4" 这三个不同的词段(word)﹔
"$*" 则可得到 "p1 p2 p3 p4" 这一整串单一的词段。

9. 命令的返回值
Return Value的作用,是用来判断行程的退出状态(exit status),只有两种:
0的话为"真"(true)
非0的话为"假"(false)

10. &&和||
&& 与 || 都是用来"组建"多个 command line 用的:
command1 && command2:其意思是command2只有在RV为0(true)的条件下执行。
command1 || command2:其意思是command2只有在RV为非0(false)的条件下执行。

11. < 和 >
标准输出: 1>
错误输出: 2>
两个输出合并: 1>file.both 2>&1
输出到空设备: &>/dev/null

12. 管道pipe
上一个命令的stdout接到下一个命令的stdin

13. if与case

  1. if comd1; then  
  2.   comd2  
  3. elif comd3; then  
  4.   comd4  
  5. else  
  6.   comd5  
  7. fi  
  8.   
  9. case "$1" in  
  10.   start)  
  11.     start  
  12.     ;;  
  13.   stop)  
  14.     stop  
  15.     ;;  
  16.   status)  
  17.     rhstatus  
  18.     ;;  
  19.   restart|reload)  
  20.     restart  
  21.     ;;  
  22.   condrestart)  
  23.     [ -f /var/lock/subsys/syslog ] && restart || :  
  24.     ;;  
  25.   *)  
  26.     echo $"Usage: $0 {start|stop|status|restart|condrestart}"  
  27.     exit 1  
  28. esac  

13. for, while, until

  1. for var; do  
  2.   ......  
  3. done  
  4.   
  5. for var in one two three four five  
  6. do  
  7.   echo '$var is '$var  
  8. done  
  9.   
  10. for ((i=1;i<=10;i++))  
  11. do  
  12.   echo "num is $i"  
  13. done  
  14.   
  15. num=1  
  16. while [ "$num" -le 10 ]; do  
  17.   echo "num is $num"  
  18.   num=$(($num + 1))  
  19. done 

抱歉!评论已关闭.