Shell Script Notes
shell Script学习笔记
《鸟哥的Linux私房菜 3rd Edition》:
@1:若变量内容中包含空格字符,则可使用双引号"或单引号'将变量内容结合起来,但不同的是:
#1:双引号内的特殊字符(如 $ 等),会保有原本的特性:
var="lang is $LANG"
echo $var
可得lang is en_US
#2:单引号内的特殊字符则仅为一般字符 (纯文本):
var='lang is $LANG'
echo $var
可得lang is $LANG
【说明】:
单引号与双引号必须要成对:
name="VBird's name" #OK
命令是由左边向右找,先遇到的引号先有用,因此如上所示,单引号会失效!
name=VBird\'s\ name #OK
单引号 和 空格 都需要进行转义
@2:在一串命令中,可能会需要藉由其他的命令提供的信息,此时就可以使用 反单引号 ` 如: `命令` 或 $(命令):
ls $(pwd) #或ls `pwd`
说明: 在一串命令中,在单引号和括号之内的命令将会被先运行。
使用$运算符的结构比较特殊,因为圆括号内的命令将在一个子shell中执行,执行完后关闭子shell并将结果返回给最初的shell中。此时就需要注意,如果设置了当前shell的某些特殊的环境条件,则这些条件可能不会转移到子shell中(例如手动设置的PATH值),那么子shell可能不会继承这些条件,这时,这些命令将失效。
其实还可以使用花括号实现同样的功能: ls ${pwd}
与圆括号的区别是,如果使用花括号,则花括号中的命令是在当前的shell中执行的,并不需要产生子shell。花括号并不是在所有的UNIX版本中都有效。
@3:若要扩增某一变量的内容,则可使用下面的形式:
"$变量名称"或${变量} 累加内容 #【双引号要写】
例:PATH="$PATH":/home/bin
【注意】:
范例1:我要在 PATH 这个变量当中累加/home/dmtsai/bin 这个目录
[root@www ~]# PATH=$PATH:/home/dmtsai/bin [root@www ~]# PATH="$PATH":/home/dmtsai/bin [root@www ~]# PATH=${PATH}:/home/dmtsai/bin
上面这三种格式在 PATH 里头的配置都是 OK 的!但是底下的例子就不见得了!
范例2:承范例1,我要将 name 的内容多出 "yes" 呢?
[root@www ~]# name=$nameyes 如果没有双引号,那么变量成了啥?name 的内容是 $nameyes 这个变量! [root@www ~]# name="$name"yes [root@www ~]# name=${name}yes #推荐这种方式
@4:取消变量的方法为使用unset:
unset 变量名称
例如取消 myname 的配置:
unset myname
@5:数组定义:
lxw@lxw-Aspire-4736Z:~$ declare -a array lxw@lxw-Aspire-4736Z:~$ array[1]="sm" lxw@lxw-Aspire-4736Z:~$ array[2]="bm" lxw@lxw-Aspire-4736Z:~$ array[3]="nm" lxw@lxw-Aspire-4736Z:~$ echo $array[1] #【NOTE】 [1] lxw@lxw-Aspire-4736Z:~$ echo ${array[1]} sm lxw@lxw-Aspire-4736Z:~$ echo ${array[2]} bm lxw@lxw-Aspire-4736Z:~$ echo ${array[4]} #【NOTE】 lxw@lxw-Aspire-4736Z:~$ echo ${array[3]} nm lxw@lxw-Aspire-4736Z:~$ echo "${array[1]},${array[2]},${array[3]}" sm,bm,nm lxw@lxw-Aspire-4736Z:~$ echo ${array} lxw@lxw-Aspire-4736Z:~$
更多关于数组的用法可以到文章末尾提到的shell文件中查看。
@6:[root@www ~]# work="/cluster/server/work/taiwan_2005/003/"
[root@www ~]# cd $work
@7:touchDateFile.sh 中 为file1, file2, file3变量赋值的这种方法。
touchDateFile.sh:
#!/bin/bash first="log" #second=$(date) last=".txt" second="11" file1="$first$second$last" second="22" file2="$first$second$last" second="33" file3="$first$second$last" touch $file1 $file2 $file3
执行脚本查看运行结果:
[liu@localhost scripts_centos]$ bash touchDateFile.sh [liu@localhost scripts_centos]$ ls log11.txt log22.txt log33.txt touchDateFile.sh [liu@localhost scripts_centos]$ echo $file2 #什么也打印不出来 [liu@localhost scripts_centos]$ source touchDateFile.sh [liu@localhost scripts_centos]$ ls log11.txt log22.txt log33.txt touchDateFile.sh [liu@localhost scripts_centos]$ echo $file2 log22.txt [liu@localhost scripts_centos]$
利用source命令运行脚本,则脚本在当前shell中运行; 用bash命令运行脚本,则会创建一个新的shell运行。
使用bash运行shell脚本程序时,系统将创建一个子shell,当该脚本程序运行完毕时,它的脚本shell将终止,并返回到执行该脚本之前的shell。
source在当前bash环境下执行命令,而bash是启动一个子shell来执行命令。
source命令通常用命令“.”来替代。如:source .bash_rc 与 . .bash_rc 是等效的。
【注意】当把设置环境变量(或alias等)的命令写进shell脚本中时,如果用bash命令运行脚本文件,则只会影响子shell,无法改变当前的shell,所以通过shell脚本设置环境变量时,要用source命令。
@8:
cmd1 && cmd2 1. 若 cmd1 运行完毕且正确运行($?=0),则开始运行 cmd2。
2. 若 cmd1 运行完毕且为错误 ($?≠0),则 cmd2 不运行。
cmd1 || cmd2 1. 若 cmd1 运行完毕且正确运行($?=0),则 cmd2 不运行。
2. 若 cmd1 运行完毕且为错误 ($?≠0),则开始运行 cmd2。
Linux 底下的命令都是由左往右运行的,如:
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe #从左往右运行
@9:“test” 和 “[ ]” 的用法
#1: 使用[ ]的三条原则
在中括号 [ ] 内的每个组件都需要有空白键来分隔;
在中括号内的变量,最好都以双引号括号起来;
在中括号内的常数,最好都以单或双引号括号起来。
#2: 除了将多个条件写入一个中括号"[ ]"内的情况之外, 还可以用多个中括号来隔开,括号与括号之间以 && 或 || 来隔开,他们的意义是:
&& 代表 and || 代表 or
所以,在使用中括号的判断式中, && 及 || 就与 命令下达(前面的@8 )的状态不同了。
例如:
[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]
之所以这样改,很多人是习惯问题,很多人喜欢一个中括号仅有一个判别式。
@10:
[liu@localhost OpenSource]$ echo "abcde" | tr "a-z" "a-c" abccc [liu@localhost OpenSource]$ echo "abcde" | tr "a-z" "A-Z" ABCDE [liu@localhost OpenSource]$
tr converts the character in the first string to those in the second string.
@11:指令搜寻的顺序:
1. 以相对/绝对路径执行指令,例如 /bin/ls 或 ./ls ;
2. 由 alias 找到该指令来执行;
3. 由 bash 内建的 (builtin)指令来执行;
4. 透过 $PATH 这个变量的顺序搜寻到的第一个指令;
@12:用 echo 命令可以“输出”一些特殊的字符(如\a,发出咚的一声),但必须要加上 -e 的选项才行!
如:echo -e "Hello World!\a\n"
@13:shell script 的追踪与 debug
$ sh [-nvx] scripts.sh
选项与参数:
-n :不运行 script,仅查询语法的问题;
-v :再运行 sccript 前,先将 scripts 的内容输出到萤幕上;
-x :很有用的参数【把计算的过程输出出来,如:每次循环的计算过程】
@14:检测用户是否输入信息(而不是直接按回车)
read -p "Input : " input var=${input:-"Default Value"} # If input got the value, then $var==$input; else {$var=="Default Value"; $input==""} echo "\$input is \"$input\"" echo "\$var is \"$var\""
运行程序查看结果(第一次bash try.sh执行程序时,对于Input提示直接按回车;第二次执行程序时,对于Input提示输入“lxw”):
lxw 19:58:34:~/github/if_case_while_awk$ bash try.sh Input : $input is "" $var is "Default Value" lxw 19:58:40:~/github/if_case_while_awk$ bash try.sh
Input : lxw $input is "lxw" $var is "lxw" lxw 19:58:43:~/github/if_case_while_awk$
《 Unix入门经典》:
@1:Unix变量通常使用大写字母表示。
@2:比较运算符:
字符串比较: =. !=, >, <
整数比较:-ge, -gt, -le, -lt, -ne, -eq
@3:13章 14章
我将学习到的大多数语句都整理了出来,放在了Github上,如果你想得到这个脚本文件basicShellScripts.sh,可以到这里下载。