写在前面:shell是什么?shell脚本又是什么?
通俗的说:LINUX中,我们敲cd,ll等命令靠哪个程序来执行?就是shell。
复杂的说:shell是个用C语言写的程序,可以交互式的解释和执行用户输入的命令。相当于在系统内核(kernel)上加了一层壳。
shell脚本就是bash,一堆命令的集合,Shell解释器会把它们一条条执行完。
参考教程:菜鸟教程-shell
Shell 环境
Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash) (大多数Linux 系统默认的 Shell)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
注释
以“#”开头的行就是注释,会被解释器忽略。
多行注释
sh里没有多行注释,只能每一行加一个#号。
大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。
程序编写
#!/bin/bash
执行程序
chmod +x test.sh
./test.sh
双引号比单引号能力强
双引号里可以有变量、双引号里可以出现转义字符。单引号里不能有
str="Hello, I know your are \"$your_name\"! \n"
规则
变量名和等号之间不能有空格
获取长度
变量前加上#号,如echo "第四个元素为: ${#my_array[*]}"
表达式求值
写法1:
val=`expr 2 + 2`
echo "两数之和为 : $val"
写法2:
#!/bin/bash
a=5
b=6
result=$[a+b] # 注意等号两边不能有空格
echo "result 为: $result"
规则:
1. 注意使用的是反引号 而不是单引号 '。 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
2. 完整的表达式要被包含,注意这个字符不是常用的单引号,在 Esc 键下边。\
val=
3. 乘号(*)前边必须加反斜杠(\)才能实现乘法运算;expr $ a \* $b
echo “a * b : $val”`
开启转义
echo "OK! \n" # -e 开启转义
while语句
#!/bin/sh
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
函数参数
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"//这个会输出10
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
注意: 10不能获取第十个参数,获取第十个参数需要 {10}。当n>=10时,需要使用${n}来获取参数。
输出重定向
1.覆盖原有文件$ echo "菜鸟教程:www.runoob.com" > users
2.追加文件$ echo "菜鸟教程:www.runoob.com" >> users
输入重定向
统计 users 文件的行数$ wc -l users #输出: 2 users
输入重定向到 users 文件:$ wc -l < users #输出:2
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。command1 < infile > outfile
重定向深入讲解
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
如果希望 stderr 重定向到 file,可以这样写:$ command 2 > file
将 stdout 和 stderr 合并后重定向到 file$ command >> file 2>&1
文件包含
. filename # 注意点号(.)和文件名中间有一空格
或
source filename