BASH命令和SHELL脚本总结(2)常识篇

@进程中的FORK

                                                    ------------- sub shell

            ------------- primary shell                   -------------sub shell

FORK       --------------                                   -------------sub shell

            --------------

 

@EXPORT@

能将变量export在当前运行的脚本的所有的子进程.

不能将变量export到父进程(就是调用这个脚本或shell的进程)中.

 

@exec命令@

这个shell内建命令将使用一个特定的命令来取代当前进程.一般的当shell遇到一个命令,它会fork off一个子进程来真正的运行命令.使用exec内建命令,shell就不会fork了,并且命令的执行将会替换掉当前shell.因此,当我们在脚本中使用它时,当命令实行完毕,它就会强制退出脚本.

 

@SHELL命令执行的两种方式@

有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不再启用其他shell。

新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

#!/bin/sh

一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

source:

source命令即点(.)命令。

在bash下输入man source,找到source命令解释处,可以看到解释"Read and execute commandsfrom filename in the current shell environment and ..."。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是另起子进程(或sub-shell)。source filename or .filename 执行filename中的命令。

exec:

在bash下输入man exec,找到exec命令解释处,可以看到有"No new process iscreated."这样的解释,这就是说exec命令不产生新的子进程。那么exec与source的区别是什么呢?

 

@exec的两种使用方式@

方式一

exec program

将 program 程序替代当前程序进程.

这就意味着 exec 后面再跟任何命令都是没有意义的, 因为他们永远得不到执行

 

方式二

可以用 exec 命令来关闭标准输入, 然后再以任何从中读取的文件重新打开

要把标准输入改变到文件, 用以下的格式的exec命令 exec < file

以后任何从标准输入读数据的命令都会从file中读取

如果用 exec 重新分配了标准输入, 后来又想重新分配到别处, 只需要再执行一次 exec.

如果要把标准输入重新改回终端, 可以写

exec < /dev/tty

以上讨论的内容也适用于重新分配标准输出. exec > report 将此后所有写向标准输出的文件写入report文件.

注: 这里的 exec 不是像前面介绍的那样用来启动运行新程序的, 而是用来重新分配标准输入和标准输出的.

 

@什么是标准输入标准输出?@

在BASH中,关于输入输出的重定向是这样的:

字符 行动

> 重定向标准输出

2> 重定向标准错误

2>&1 标准错误重定向到标准输出

< 重定向标准输入

| 重定向到下一个管道

>> 附加到标准输出

2>&1| 管标准输出和标准错误到另一个命令

 

@重定向@

例1

exec 2>$OUTPUT_PATH/$DATE/err_${TIME}.log

将错误日志重定向到err_${TIME}.log文件中。

exec 2>&1 1>$OUTPUT_PATH/$DATE/err_${TIME}.log可以使得stderr和stdout内容都被重定向,

例2观察crotab中使用的重定向

[@administer realtime_duplicate]#crontab -l

49 * * * * /usr/sbin/ntpdatentp.sohu.com > /dev/null 2>&1

49 16 * * * /sbin/clock -w

# [system] disk check

00 * * * * cd/root/machine_config/;sh super_check.sh -d disk.conf 1>output.log

[@administerorin_realtime_duplicate]# 

 程序运行中,默认的输出信息放入1中,错误信息放入2中。默认1和2的信息都显示到屏幕中。

但是可以使用>将它们重定向。

例2

[@administer ~]# (echo 123|cat>&2; echo 456) 1>/dev/null 

123

[@administer ~]# (echo 123|cat>&2; echo 456) 2>/dev/null   

456

 

@管道改变中的效率问题

在 cm1 | cm2 | cm3 ... 這段 pipe line 中,若要將 cm2 的結果存到某一檔案呢? 

若你寫成 cm1 | cm2 > file | cm3 的話, 

那你肯定會發現 cm3 的 stdin 是空的﹗(當然啦,你都將水管接到別的水池了﹗) 

聰明的你或許會如此解決: 

cm1 | cm2 > file ; cm3 <file

是的,你的確可以這樣做,但最大的壞處是:這樣一來,file I/O 會變雙倍﹗ 

在 command 執行的整個過程中,file I/O 是最常見的最大效能殺手。 

凡是有經驗的 shell 操作者,都會盡量避免或降低 file I/O 的頻率。  

 所謂 tee 命令是在不影響原本 I/O 的情況下,將 stdout 複製一份到檔案去。 

因此,上面的命令行可以如此打: 

cm1 | cm2 | tee file | cm3

 

@解释语言与编译性语言@

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能值型高级语言编写的程序。 

翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同。编译型语言写的程序执行之前,需要一个专门的编译过程,把程序编译成为机器语言的文件,比如exe文件,以后要运行的话就不用重新翻译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行时不需要翻译,所以编译型语言的程序执行效率高。 

解释则不同,解释性语言的程序不需要编译,省了道工序,解释性语言在运行程序的时候才翻译,比如解释性basic语言,专门有一个解释器能够直接执行basic程序,每个语句都是执行的时候才翻译。这样解释性语言每执行一次就要翻译一次,效率比较低。

 

@什么是脚本语言@

1 脚本语言是一种解释性的语言,例如vbscript,javascript,installshield script等等,它不像c/c++等可以编译成二进制代码,以可执行文件的形式存在. 脚本语言不需要编译,可以直接用,由解释器来负责解释。 

 

@正则注意事项@

须留心 UNIX Shell中使用 "*"表示 Wild card,可用以代表任意长度的字

. Regexp中使用 "."来代表一个任意字符.(注意:并非任意长度的字

)Regexp "*"另有其它涵意, 并不代表任意长度的字串.

 

@解决mkdir问题@

create a directory, you need to have bothwrite (w) AND execute (x) permissions in the parent directory. Whereever youare, you can check the parent using "ls -l .."

所以,应该改变文件夹或者文件的属主

 

@脚本框架@

在总控文件run_all中,一方面可以export常量,另一方面可以运行子文件

 

@一些特殊的变量@

$0是该bash文件名

$? 是上一指令的返回值

$# 是参数的个数

$1 是运行shell脚步时提供的第一个参数

$2 是运行shell脚步时提供的第二个参数

$* 是调用当前脚本时的所有参数

$@ 基本上与上面相同。只不过是$*返回的是一个字符串,字符串中存在空格,但是$@返回多个字符串。

 

 

@反引号@

反引号 ` 

反引号(`)这个字符所对应的键一般位于键盘的左上角,不要将其同单引号(’)混淆。反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。例如:

$ pwd

/home/xyz

$ string="current directoryis `pwd`"

$ echo $string

current directour is /home/xyz

 

shell执行echo命令时,首先执行`pwd`中的命令pwd,并将输出结果/home/xyz取代`pwd`这部分,最后输出替换后的整个结果。

 

利用反引号的这种功能可以进行命令置换,即把反引号括起来的执行结果赋值给指定变量。例如:

$ today=`date`

$ echo Today is $today

Today is Mon Apr 15 16:20:13 CST1999

 


@数组操作

a=(abcdef)  

[@administerExec2Source]# echo${a[@]}  

#打印数组所有内容

abcdef

 

[@administerExec2Source]# echo ${a[1]} 

#打印数组第二个元素

def

 

[@administerExec2Source]# echo ${a[0]} 

#打印数组第一个元素

abc

 

[@administerExec2Source]# echo ${#a[1]} 

#打印数组第一个元素的长度

3

@SHELL的返回值@
返回结果为0表示真,其它任何值为假。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值