subShell 是一群被括在圆括号里的命令,这些命令会在另外的进程里执行。当你需要让一组命令在不同的目录下执行时,这种方法可以让你不修改主脚本的目录。

例; 将某个目录树通过管道复制到另外一个地方。

tar -cf - . | (cd /newdir; tar -xpf - )

代码块概念上与subShell相同,但是它不会建立新的进程。代码块里的命令用花括号{}括起来,且对主脚本的状态会产生影响。

 子shell: 每个shell脚本都有效地运行在父shell的一个子进程中. 这个父shell指的是在一个控制终端或在一个xterm窗口中给出命令提示符的那个进程.

shell脚本也能启动它自已的子进程. 这些子shell能够使脚本并行的, 有效的, 同时运行多个子任务.

圆括号中的命令列表( command1; command2; command3; ... )圆括号中命令列表的命令将会运行在一个子shell中.

子shell中的变量对于子shell之外的代码块来说, 是不可见的. 当然, 父进程也不能访问这些变量, 父进程指的是产生这个子shell的shell. 事实上, 这些变量都是局部变量.

子shell中的目录更改不会影响到父shell.

子shell中的目录更改不会影响到父shell.父shell不受任何影响, 并且父shell的环境也没有被更改.

子shell的另一个应用, 是可以用来检测一个变量是否被定义.

[[ ${variable-x} != x || ${variable-y} != y ]]  或 [[ ${variable-x} != x$variable ]]  或 [[ ${variable+x} = x ]]  或  [[ ${variable-x} != x ]]

使用"|"管道操作符, 将I/O流重定向到一个子shell中, 比如ls -al | (command).

在大括号中的命令不会启动子shell.{ command1; command2; command3; . . . commandN; }

Here Document:  一个here document就是一段带有特殊目的的代码段. 它使用I/O重定向的形式将一个命令序列传递到一个交互程序或者命令中, 比如ftp, cat, 或者ex文本编辑器.

  COMMAND <<InputComesFromHERE
          ...
  InputComesFromHERE

limit string用来界定命令序列的范围(译者注: 两个相同的limit string之间就是命令序列). 特殊符号<<用来标识limit string. 这个符号的作用就是将文件的输出重定向到程序或命令的stdin中.与interactive-program < command-file很相似, 其中command-file包含:
而here document看上去是下面这个样子:
  #!/bin/bash
  interactive-program <<LimitString
   command #1
   command #2
  ...
   LimitString
选择一个名字非常诡异limit string能够有效的避免命令列表与limit string重名的问题.

-选项用来标记here document的limit string (<<-LimitString), 可以抑制输出时前边的tab(不是空格). 这么做可以增加一个脚本的可读性.

结尾的limit string, 就是here document最后一行的limit string, 必须从第一个字符开始. 它的前面不能够有任何前置的空白. 而在这个limit string后边的空白也会引起异常.空白将会阻止limit string的识别.

列表结构: "与列表"和"或列表"结构能够提供一种手段, 这种手段能够用来处理一串连续的命令.

与列表: command-1 && command-2 && command-3 && ... command-n,如果每个命令执行后都返回true(0)的话, 那么命令将会依次执行下去. 如果其中的某个命令返
回false(非零值)的话, 那么这个命令链就会被打断, 也就是结束执行, (那么第一个返回false的命令, 就是最后一个执行的命令, 其后的命令都不会执行).

或列表:command-1 || command-2 || command-3 || ... command-n如果每个命令都返回false, 那么命令链就会执行下去. 一旦有一个命令返回true, 命令链就会被打断, 也就是结束执行, (第一个返回true的命令将会是最后一个执行的命令). 显然, 这和"与列表"完全相反.

与列表和或列表的退出状态码由最后一个命令的退出状态所决定。

false && true || echo false # false
# 与下面的结果相同
( false && true ) || echo false # false# But *not*false && ( true || echo false ) # (没有输出)
#  注意, 以从左到右的顺序进行分组与求值,  这是因为逻辑操作"&&"和"||"具有相同的优先级.  最好避免这么复杂的情况, 除非你非常了解你到底在做什么.

 进程替换

进程替换与命令替换很相似. 命令替换把一个命令的结果赋值给一个变量, 比如dir_contents=`ls -al`或xref=$( grep word datafile). 进程替换把一个进程的输出提供给另一个进程(换句话说, 它把一个命令的结果发给了另一个命令).

用圆括号扩起来的命令>(command) , <(command)启动进程替换. 它使用/dev/fd/<n>文件将圆括号中的进程处理结果发送给另一个进程.在"<"或">"与圆括号之间是没有空格的. 如果加了空格, 会产生错误

进程替换可以比较两个不同命令的输出, 甚至能够比较同一个命令不同选项情况下的输出.

comm <(ls -l) <(ls -al)
diff <(ls $first_directory) <(ls $second_directory)
cat <(ls -l)  # 等价于ls -l | cat
sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin)  # 列出系统3个主要'bin'目录中的所有文件, 并且按文件名进行排序.   注意是3个(查一下, 上面就3个圆括号)明显不同的命令输出传递给'sort'
diff <(command1) <(command2) # 给出两个命令输出的不同之处.while read des what mask iface; doecho $des $what $mask $iface
done < <(route -n)
一个更容易理解的等价代码是:
route -n |
while read des what mask iface; do # 管道的输出被赋值给了变量.
echo $des $what $mask $iface
done #  这将产生出与上边相同的输出. 然而, Ulrich Gayer指出. . .这个简单的等价版本在while循环中使用了一个子shell,  因此当管道结束后, 变量就消失了.

Shell中脚本变量和函数变量的作用域   http://blog.csdn.net/ltx19860420/article/details/5570902

(1)Shell脚本中定义的变量是global的,其作用域从被定义的地方开始,到shell结束或被显示删除的地方为止。解析:脚本变量v1的作用域从被定义的地方开始,到shell结束。调用函数ltx_func的地方在变量v1的作用域内,所以能够访问并修改变量v1。

(2)Shell函数定义的变量默认是global的,其作用域从“函数被调用时执行变量定义的地方”开始,到shell结束或被显示删除处为止。函数定义的变量可以被显示定义成local的,其作用域局限于函数内。但请注意,函数的参数是local的。

解析:函数变量v2默认是global的,其作用域从“函数被调用时执行变量定义的地方”开始,到shell结束为止。注意,不是从定义函数的地方开始,而是从调用函数的地方开始。打印命令在变量v2的作用域内,所以能够访问变量v2。

解析:函数变量v2显示定义为local的,其作用域局限于函数内。打印命令在函数外,不在变量v2的作用域内,所以能够不能访问变量v2。函数参数是local的,通过位置变量来访问。打印命令输出函数的第一个参数。

(3)如果同名,Shell函数定义的local变量会屏蔽脚本定义的global变量。

在函数被调用之前, 所有在函数中声明的变量, 在函数体外都是不可见的,当然也包括那些被明确声明为local的变量.

退出状态码
函数返回一个值, 被称为退出状态码. 退出状态码可以由return命令明确指定, 也可以由函数中最后一条命令的退出状态码来指定(如果成功则返回0, 否则返回非0值). 可以在脚本中使用$?来引用退出状态码. 因为有了这种机制, 所以脚本函数也可以象C函数一样有"返回值".
return终止一个函数. return命令 [1]可选的允许带一个整型参数, 这个整数将作为函数的"退出状态码"返回给调用这个函数的脚本, 并且这个整数也被赋值给变量$?.函数所能返回最大的正整数是255.  为了让函数可以返回字符串或是数组, 可以使用一个在函数外可见的专用全局变量.

重定向函数的stdin函数本质上其实就是一个代码块, 这就意味着它的stdin可以被重定向.

2:shell什么情况下会产生子进程以下几个创建子进程的情况。(以下英文摘自info bash)
1:&,提交后台作业
If a command is terminated by the control operator `&', the shell executes the command asynchronously in a subshell.
2:管道
Each command in a pipeline is executed in its own subshell
3:括号命令列表
()操作符Placing a list of commands between parentheses causes a subshellenvironment to be created
4:执行外部脚本、程序:
When Bash finds such a file while searching the `$PATH' for a command, it spawns a subshell to execute it.  In other words, executing
                     filename ARGUMENTSis equivalent to executingbash filename ARGUMENTS说明:大致上子进程的创建包括以上四种情况了。需要说明的是只要是符合上边四种情况之一,便会创建(fork)子进程,不因是否是函数,命令,或程序,也不会因为是内置函数(buitin)或是外部程序。

转载于:https://www.cnblogs.com/fly-xiang-zhao/p/3675642.html

subShell与代码块相关推荐

  1. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  2. 【经验】向word中插入格式化的代码块

    参考博客:如何在word中插入代码块 1.打开http://www.planetb.ca/syntax-highlight-word网站 语法高亮显示Word文档中的代码 2.将你的代码复制进去,选择 ...

  3. android studio同步代码块,Android Studio快捷键大全

    Ctrl+P 提示有效说明参数 Ait + Enter 提示 Ctrl+Ait+L 格式化 Ctrl+Y 删除本行 Alt + Shift + Up/Down 上下移动本行代码 Alt + Ctrl ...

  4. Java代码块总结(速读版)

    **代码块必须直接定义在类中**,有两种:静态代码块 和 非静态代码块 静态代码块是在类(class文件)加载内存时执行,而非静态代码块是在创建对象(new 类名();)时执行. public cla ...

  5. Xcode可重用代码块code snippets

    一. 关于code snippets 通过Xcode的重用代码块(code snippets)可快速输入预设好的常用代码模板,如通过键入 hystrong 系统会直接替代为 @property(non ...

  6. Xcode快捷键及代码块

    2017-02-16 吴白 CocoaChina 手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥 ...

  7. java 静态代码块 多线程,Java多线程编程笔记10:单例模式

    立即加载:"饿汉模式" 立即加载就是指使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化.也就是在调用方法前,实例就被创建了.示例代码如下所示: class MyO ...

  8. 控件包含代码块,因此无法修改控件集合

    文章转载至:  http://www.olnote.com/itlife/note/100000003.aspx 控件包含代码块(即<% ... %>),因此无法修改控件集合. 说明: 执 ...

  9. java gui构造工具_Java Web框架 静态代码块、构造代码块、构造函数、普通代码块 执行顺序 Decompiler JD-GUI 反编译工具...

    1.下载jd-gui-windows-1.4.0. http://jd.benow.ca/ 2.通过jd-gui.exe查看.class文件,用于分析类编译过程. 3.源文件. // 加载相应的 He ...

最新文章

  1. DedeCMS(织梦)安全设置经验分享
  2. 【NLP】NLP从业人员必须知道的十大必备知识库(附资料下载)
  3. 数据分析与挖掘理论-概述
  4. linux r包默认安装位置,R-Language(R语言或称r-project)的安装
  5. android 暂停其他app的声音_【一万个APP】第二十二期潮汐
  6. 职场 | 3天准备5天面试,跳槽完成
  7. 3-19pytorch与矩阵分解SVD
  8. k64 datasheet学习笔记3---Chip Configuration之System modules
  9. excel函数学习系列一
  10. 负负为何得正的推理过程
  11. .10-浅析webpack源码之graceful-fs模块
  12. STM32 SPI驱动OLED12864原理图和源代码分享
  13. 制作钓鱼网站进行渗透测试——内网SET工具包
  14. 求职时,怎样判断一家公司是否靠谱?
  15. ecshop mysql密码忘记_ECSHOP后台密码忘记了怎么办
  16. win10系统mysql重新配置密码
  17. 快递API接口对接分析
  18. ironpython是什么意思_部类“IronPython.Runtime.Binding.PythonBinder”的派生方法“GetTypeName”不能减少访问。这什么意思啊...
  19. 同花顺抓起涨做波段指标公式 副图 源码
  20. A Game of Thrones(21)

热门文章

  1. 详解SOA五种基本架构模式
  2. go web本地化资源
  3. golang中的文件读写
  4. 买卖股票的最佳时机|||
  5. TCP/IP 建立连接的过程
  6. setsockopt()函数功能介绍
  7. 【Sphinx】MySQL+Sphinx 全文检索的使用和测试
  8. 记一次与用户的亲密接触
  9. iterm2 mac链接linux工具 桌面程序Transmit
  10. 格式化大容量硬盘为fat32