shell学习笔记一

第一章
1.1 简介
在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器)。它类似于DOS下的command和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。
Shell脚本通常是以一个#!起始的文本文件,如下所示:
#! /bin/bash
其中#!(通常被称为shebang声明)被置于命令解释前之前(注:当只有#时,被解释为注释),/bin/bash是所使用的的命令解释器。
有两种运行方式:一种将脚本作为sh的命令行参数,另一种是将脚本作文具有执行权限的可执行文件。
将脚本作为命令行参数是的运行方式如下:
$ sh script.sh
如果将脚本作为sh的命令行参数来运行,那么脚本中的shebang行就没有什么用处了。
为了使shell脚本能够独立运行,需要具备可执行权限,要使脚本独立运行,必须利用
Shebang行,这样就可以用shebang之后的命令解释器来运行脚本。脚本的可执行权限通常用以下方式设置:
$ chmod a+x script.sh
该命令赋予文件可执行权限,运行方式如下:
$ ./script.sh (./表示当前文件目录
shell程序以该方式运行脚本时,查看shebang行是否为#! /bin/bash,它会识别 /bin/bash,并在内部以如下命令执行该脚本:
$ /bin/bash script.sh
在Bash中,每个命令行序列是通过使用分号或者换行符来分隔的。比如:
$ cmd1 ; cmd2
等同于:
$ cmd1
$ cmd2
1.2 终端打印
1.2.1 echo
echo适用于终端打印的基本命令,在默认情况下,echo在每次调用后都会加上一个换行符。
$ echo "welcome to Bash"
welcome to Bash
只需要使用带双引号的文本,结合echo命令就可以将该文本在终端打印出来。类似的,不带双引号的文本也可以得到同样的输出结果:
$ echo welcome to Bash
welcome to Bash
当然了使用单引号也可以完成同样的任务。这些方法看起来类似,但是各有一些特殊作用和副作用。每种方法的副作用如下:
 使用不带引号的的echo时,你没办法在所要显示的文本中使用分号,因为在bash shell中被用作命令界定符。以echo hello;hello为例,echo hello被视为一个命令,第二个hello被视为第二个命令。
 使用带单引号的echo时,Bash不会对单引号中的变量(如$var)求值,而是按照原样解释。比如$ echo ‘$var’将会返回$var,并不会对var求值。

1.2.1 printf
另一个可用于终端打印的命令是printf,其用法和C语言中的printf函数一样。例:
$ printf "hello world"
$ printf "my name is %s,age %d\n" jieke 12
将会得到:
hello world
my name is jake,age 12

1.3 变量和环境变量
在脚本语言中,使用变量通常不需要生命其类型,只需要使用时直接赋值就可以了。在Bash中,每一个变量的值都是字符串。无论给你变量赋值时有没有使用引号,值都会以字符串的形式存储。有一些特殊变量会被shell环境和操作系统环境来存储一些特别的值,这些变量就被称为环境变零。


1.3.1 实战演练:
一个变量可以通过以下方式赋值:
var=value
其中,var是变量,value是赋给变量的值。如果value中不包含任何空白字符(如空格),那么它不需要使用引号进行引用,繁殖必须使用单引号或者双引号。
要严格注意空额,等于号前后不能出现空格,比如讲var=value写成var = value,前者是一个变量赋值操作,后者是一个相等操作。
在变量名之前加上$前缀就可以打印出变量内容:
echo $var
就可以打印出变量内容value,当然也可以使用echo ${var}命令,效果一样。也可以在printf和echo命令的双引号中使用引用变量值。
#! /bin/bash
fruit=apple
count=5
echo "We have $count ${friut}(s)"
输出:We have 5 apple(s)
环境变零是未在当前进程中定义,而从父进程继承而来的变量。例如环境变零HTTP_PROXY,它定义了一个internet连接应该使用哪一个代理服务器。
Export命令用来设置环境变量,致辞以后,从shell脚本执行的程序都会继承这个变零。比如在PATH中添加一条新路径可以使用:
export PATH="PATH:/home/user/bin"
这样我们就将/home/user/bin添加到了PATH中。
1.3.2 补充内容
获得字符串长度:echo ${#var}
识别当前shell版本:echo $0
检查是否为超级用户:
#! /bin/bash
if [ $UID -ne 0 ];
then
echo NOn root use. please run as root
else
echo "Root user"
fi
1.4 shell数学运算
在bash中,可以使用let,(())和[]执行基本的数学操作,而进行高级操作时,会用到expr和bc这两个工具。
let命令的使用,例子如下:
#! /bin/bash
no1=4
no2=5
let result=no1+no2
echo $result
在使用let命令时,变量名之前可以不需要加$,let可以对变量实行基本的数学操作,如自加自减。
操作符[ ]的使用方法和let命令类似,如result=$[ no1 + no2 ]。
也可以使用(()),但是使用(())需要在变量名之前加上$:result=$( ( no1 + no2 ) )。
Expr同样也可是使用基本操作,result=’ expr 3 + 4’。
1.5 文件描述符和重定向
echo "this is a sumple txt">temp.txt
然后通过cat temp.txt查看,发现temp.txt文件里有this is simple txt字符。
echo "this is a sumple txt2">>temp.txt
输入该命令将会在temp.txt中追加this is a sumple txt2。
1.6 数组和关联数组
Bash同时支持普通数组和关联数组,普通数组只能使用整数作为数组索引,而关联数组可以使用字符串作为数组索引。
数组定义方法:array_var=( 1 2 3 4 5 6 )
也可以将数组定义成一组索引-值方式,如下:
array_var[0]="test0"
array_var[1]="test1"
打印数组内容:echo ${array_var[0]}
 以清单方式打印出素组内容:echo ${array_var[*]},也可以用echo ${array_var[@]}
  打印数组长度echo ${#array_var[*]}
列出数组索引:echo ${!array_var[*]}。
1. 7 使用别名
  alias install='sudo apt-get install'
就可以使用install命令来替代原有的sudo apt-get install命令了。
alias命令只是暂时的,一旦关闭终端,这个设置就失效了。如果要让其抑制保持作用,可以将其放入~/.bashrc文件中,因为每当一个shell进程生成时,都会执行该文件中的命令。方法如下:
echo 'alias cmd="command seq"'>>~/.bashrc
如果要删除该别名,可以想起对应的语句从~/.abshrc中删除,或者使用unalias命令。
1.8 获取终端信息
编写命令行shell脚本的时候,总是免不了处理当前信息,如行数,列数,光标位置和遮盖掩码字段等。tpus和stty是两款终端处理工具。
获取终端行数和列数:
tput cols
tput lines
将光标移动到(100,100)处:
tput cup 100 100
在输入密码时不能让输入的内容显示出来,方法:
#! /bin/bash
echo -e "Enter password: "
stty -echo
read password
stty echo
echo
echo Password read
其中,–echo禁止将输出发送到终端,而选项echo允许发送。
1.9 获取设置日期和延迟
1.10 调试脚本
使用选项 –x,启动和调试shell脚本:
bash –x script.sh
-x标识符将脚本中执行的每一行输入到stdout,不过我们也可以要求只关注某些部分的命令及参数的打印输出。针对这种情况,可以在脚本中使用set built-in来启动或禁止调试打印。
 set –x:在执行时显示参数和命令。
 set +x:禁止调试。
 set –v:当命令进行时显示输入
 set +v:禁止打印输入。
例如:
#! /bin/bash
for i in {1..6}
do
set -x
echo $i
set +x
done
echo "script executed"
输出如下:
+ echo 1
1
+ set +x
+ echo 2
2
+ set +x
+ echo 3
3
+ set +x
+ echo 4
4
+ set +x
+ echo 5
5
+ set +x
+ echo 6
6
+ set +x
script executed
可以发现,仅在-x和+x所限制的区域中,echo $i的信息才会被打印出来。
1.11 函数和参数
定义函数:
function fanme()
{
}
或者
fname()
{
}
只需要使用函数名就可以调用某个函数:
$ fanme ; # 执行参数
参数可以传递给函数,并由脚本进行访问
fanme arg1 arg2 ; # 传递参数
其中:
 $1是第一个参数(第0个是函数名本身)
 “$@”输出所有输入参数
 “$*”输出所有输入参数(用的比较少,因为将所有的参数当单个字符串)
递归函数,在bash中,函数同样支持递归,如
F()
{
echo $1;
F hello;
sleep(1);
}

这个递归函数会不断的调用自身。
导出函数,函数也能像环境变量一样用export导出,如此一来,函数的作用就会扩展到整个子进程中,如下:
export –f fname
echo $? 返回上个命令或函数的返回值。

你可能感兴趣的:(shell学习笔记一)