目录
sh概述
sh语言标准
sh命令
sh控制语句
I/O重定向和嵌入文档
sh函数
sh中的通配符
命令行分组
eval语句
调试sh脚本
sh即shell的缩写,sh是一种具备特殊功能的程序。与C语言不同,sh是一种解释语言而非编译性语言,它提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令,并把它送入内核去执行。Shell是一种应用程序,当用户登录Linux系统时,Shell就会被调入内存去执行。Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,Linux内核才能执行该命令。
sh脚本是一个包含了sh语句的文本文件,命令解释了程序sh要执行该语句。
#! /bin/bash //#! 是一个约定的标记符号,指示脚本对应的解释器 # comment line echo hello //此处为输出的内容
2.使用以下命令运行sh脚本
chmod +x mysh.sh //把mysh.sh文件转为可执行文件 ./mysh.sh //运行脚本程序
/bin/sh mysh.sh //这种方法下就不需要第一行的解释器信息了
//sh 逐行读取并执行 mysh a b c d $0 $1 $2 $3 $4 //C 编译链接至可执行文件 a.out a.out a b c d main(int argc , char *argv[])
sh是一种解释性语言,逐行读取sh脚本文件并直接执行这些行。如果是可执行的内置命令,那么就会直接执行,否则会复刻一个子进程来执行命令,并等待子进程终止后再继续,这和sh执行单个命令行一样。sh中的变量都是字符串。sh不需要main函数,sh脚本中的第一个可执行语句就是函数入口。
C程序要先编译链接到一个二进制可执行文件上,然后通过主sh的子进程运行这个可执行二进制可执行文件.在C程序中,每个变量都需要一个类型,如int、float、char等。C程序需要一个main函数作为函数的入口。
mysh one two three //在实际操作中还是要按照下面的操作来 chmod +x file.sh ./file.sh
$# ---命令行参数$1~$n数目 $* ---所有命令行数,$#+1 $S ---执行sh的进程PID $? ---最后一个命令执行的退出状态(成功时为0,否则为非0)
vi mysh.sh // #! /bin/bash echo \$# = $# echo \$* = $* echo $1 $9 $10 echo $1 $9 ${10} shift //行位置顺序左移一位 echo $1 $9 ${10} // chmod +x mysh.sh ./mysh.sh abc D E F G H I J K L M N
结果如下:
ps:
在sh中,想要输出"$"符号,需要在前面加上个反斜杠"/"。
sh有很多内置变量,如 PATH 、 HOME 、 TERM 等,除了这些内置变量外,还可以定义变量,定义的变量无需声明,sh的所有变量都是字符串,为赋值的sh变量是一个 NULL 字符串。
echo A //定义 A = 'askdjhlaksjdh' //赋值
想要输出sh中的特殊字符,除了在前面加反斜杠以外,还可以用单引号" '' "来引用它们。 一般反斜杠"/"用于单个符号的引用,单引号" '' "用于长字符串。 单引号内没有替换,即单引号内的特殊符号会被视为字符,而双引号可以保留引用字符串中的空格和替换部分。
sh语句包含了Unix/Linux的所有命令。
sh有许多的内置命令,这些命令由sh执行,不需要创造一个新的进程
下面是一些常用的内置sh命令,如图下所见:
read命令,当sh执行read命令时,他会等待来自stdin(标准输入)的输入行。它将输入行划分为几个标记,分配给列出的变量。read的常见用法是允许用户与正在执行的sh进行交互,类似scanf()。
下面是一个read应用:
echo -n "enter your ID :" read ANS echo $ANS
将参数符号对应的字符串作为行输出至stdout。一般会将多个相邻的空格合并为一个,除非有引号。echo已经用过很多次了。
将sh中的字符串转化为二进制数,经行运算后转回字符串。一般格式如下: expr 字符串A 运算操作OP 字符串B
read A read B echo $(expr $A + $B)
ps -ax | grep httpd cat file | grep word
更多关于管道命令
用括号括起来的部分会被优先处理 echo $(data) echo $(ls dir) //先进行 ls dir 操作再输出整个 ls dir
sh是一种编程语言,支持许多执行控制语句,类似C语言,注意格式的不同之处。
if-else-if语句的一般格式: if [中括号里的条件A] then 分支A else 分支B fi //结束 或者是这种: if [condition]; then branchA else branchB fi 又或者: if [[ A && B]]; then if [[ A && B || C]]; then if [[ A && (B || C) ]]; then
for语句的一般格式: for A in Character do cmdA done
while语句的一般格式: while [ 条件 ] do cmdA done
until-do语句的一般格式: until [ $A = "never gone give you up" ] do cmdA done
case语句的一般格式: case $A in pattern1) cmd1;; pattern2) cmd2;; pattern3) cmd3;; encase
与C语言中一样
>file stdout转向文件,如果文件不存在,创建这个文件。 >>file stdout追加到文件中。 <file 将文件作为stdin;文件需要有r权限。 <<file 从"here"文件中获取输入,直到只包含"word"的行。
指示输出命令从stdin获取输入,将其回显到stdout,直到遇到预先安排的关键字。 格式一般如下: echo << END #一直按行输入并输出直到一行只剩下END END cat << DONE #一直按行输入输出直到DONE DONE
一般格式如下: func() { # 函数内容 }
file *:列出当前目录中的所有文件信息 ls *.c:列出当前目录.c文件
file ???:所有有三个字符名字的文件 ls *.??:所有.后有两位拓展名的文件
file *[ad]*:包含字符a或d的所有文件名 ls *[xyz]*:列出所有包含x、y或z的文件名 ls *[a-m]*:列出包括a到m范围内字符的所有文件名
eval [arg1 arg2 ...argn]
使用如下格式进行调试:
bash -x mysh