shell脚本入门|博客系列
# 脚本运行
建立一个文本文件demo1,以.sh结尾的或者不需要后缀都可以,下面是demo1的内容:
#!/bin/bash
NUM=10
printf "输出数字$NUM\n"
echo $NUM
直接运行是会报错误的,因为没有权限执行(Permission denied),需要给权限。下面方式
chmod +x ./demo1 # 使每个人都有执行的权限
chmod +rx ./demo1 # 使每个人都有读和执行的权限
chmod u+rx ./demo1 # 仅仅使脚本文件拥有者有读和执行的权限
chmod u+x ./demo1 # 只有自己可以执行,其它人不能执行
chmod ug+x ./demo1 # 只有自己以及同一群可以执行,其它人不能执行
chmod 555 ./demo1 # 使每个人都有读和执行的权限
chmod 777 ./demo1
当前目录下运行 demo1 脚本
./demo1
# 输出结果===>
输出数字10
10
直接运行demo1脚本,这个方法是把脚本给系统中所有其他的用户使用,这个时候需要你将demo1脚本移动到目录/usr/local/bin 中(必须要有root的权限),移动到 bin 目录之后,你只需使用 demo1 加回车就能执行脚本了。
demo1
# 输出结果===>
输出数字10
10
通过sh或者bash命令运行脚本,sh scriptname 运行一个Bash脚本将会禁止所有Bash的扩展特性。
# 你能够运行它用命令
sh demo1
# 另外也也可以用bash来执行
bash demo1
脚本以"#!"行开头,行将会命令解释器(sh或是bash)。#!/bin/rm 当你运行这个脚本时,除了这个脚本消失了之外,你不会发现更多其他的东西。
# 特殊字符
# 注释
以#开头的行就是注释,会被解释器忽略。注释行前面也可以有空白字符。
#--------------------------------------------
# 这是一个注释
# author:作者
# site:https://github.com/jaywcjlove
#--------------------------------------------
echo "A comment will follow." # 这里可以添加注释.
# ^ 注意在#前面可以有空白符
echo命令给出的一个转义的#字符并不会开始一个注释。同样地,出现在一些参数代换结构和在数值常量表达式中的#字符也同样不会开始一个注释。
echo "这里的 # 不会被注释"
echo '这里的 # 不会被注释'
echo 这里的 \# 不会被注释
echo 这里的 # 会被注释
echo ${PATH#*:} # 前面的#是参数代换,不是注释.
echo $(( 2#101011 )) # 基本转换,不是注释.
# 命令分割符
分号;命令分割符,分割符允许在同一行里有两个或更多的命令。执行demo2,会将 demo2 拷贝输出 demo2.bak 。
echo hello; echo there # 输出 hello 和 there
filename='demo2' # 变量
if [ -x "$filename" ]; then # 注意:"if" and "then"需要分隔符
# 思考一下这是为什么?
echo "File $filename exists."; cp $filename $filename.bak
else
echo "File $filename not found."; touch $filename
fi; echo "File test complete."
# 句号/圆点
作为一个文件名的组成部分.,当点.以一个文件名为前缀时,起作用使该文件变成了隐藏文件。这种隐藏文件ls一般是不会显示出来的。
作为目录名时,单个点(.)表示当前目录,两个点(…)表示上一级目录(或称为父目录)。
点(.)字符匹配。作为正则表达式的一部分,匹配字符时,单点(.)表示匹配任意一个字符。
# 引号
引号一个很重要的作用是保护命令行上的一个参数不被shell解释,而把此参数传递给要执行的程序来处理它。
bash$ grep '[Ff]ile' demo*
demo2:filename='demo2'
demo2:if [ -x "$filename" ]; then # 注意:"if" and "then"需要分隔符
demo2: echo "File $filename exists."; cp $filename $filename.bak
引号能改掉echo’s不换行的“习惯”。
bash$ echo $(ls -al)
total 24 drwxr-xr-x 5 kacperwang staff 170 1 22 16:47 . drwxr-xr-x 5 kacperwang staff 170 1 22 13:29 .. -rwxr-xr-x 1 kacperwang staff 58 1 22 16:20 demo1 -rwxr-xr-x 1 kacperwang staff 325 1 22 16:39 demo2 -rwxr-xr-x 1 kacperwang staff 899 1 22 17:16 demo3
bash$ echo "$(ls -al)"
total 24
drwxr-xr-x 5 kacperwang staff 170 1 22 16:47 .
drwxr-xr-x 5 kacperwang staff 170 1 22 13:29 ..
-rwxr-xr-x 1 kacperwang staff 58 1 22 16:20 demo1
-rwxr-xr-x 1 kacperwang staff 325 1 22 16:39 demo2
-rwxr-xr-x 1 kacperwang staff 899 1 22 17:16 demo3
单引号
str='this is a string'
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
单引号字串中不能出现单引号(对单引号使用转义符后也不行)
双引号
your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
双引号里可以有变量
双引号里可以出现转义字符
# 命令替换
命令替换"`",将会重新分配一个命令甚至是多个命令的输出;它会将命令的输出如实地添加到另一个上下文中。demo4
script_name=`basename $0`
echo "The name of this script is $script_name."
textfile_listing=`ls *`
# 变量中包含了当前工作目录下所有的*文件
echo $textfile_listing
通过这个符号,批量删除文件
rm `cat filename` # "filename" 包含了需要被删除的文件列表
# 可能会产生"参数列表太长"的错误
# 更好的方法是 xargs rm -- < filename
# ( -- 同时覆盖了那些以"-"开头的文件所产生的特殊情况 )
# 操作符
# 赋值
变量赋值,初始化或改变一个变量的值,通用的变量赋值操作符,可以用于数值和字符串的赋值
var=27
category=minerals # "="字符后面不能加空白字符.
不要把"="赋值操作符和=测试操作符搞混了。
# = 用于测试操作符
if [ "$string1" = "$string2" ]
# if [ "X$string1" = "X$string2" ] 会更安全,
# 它为了防止其中有一个字符串为空时产生错误信息.
# (增加的"X"字符可以互相抵消.)
then
command
fi
# 计算操作符
| 操作符 | 描述 | 操作符 | 描述 | 操作符 | 描述 |
|---|---|---|---|---|---|
+ |
加 | / |
除 | ** |
求幂 |
- |
减 | * |
乘 | % |
求模demo6 |
# Bash在版本2.02引入了"**"求幂操作符.
let "z=5**3"
echo "z = $z" # z = 125
# 求模(它返回整数整除一个数后的余数)
let "y=5 % 3"
echo "y = $y" # y = 2
| 操作符 | 描述 |
|---|---|
+= |
加等(plus-equal) 把原变量值增加一个常量并重新赋值给变量 |
-= |
减等(minus-equal) 把原变量值减少一个常量并重新赋值给变量 |
*= |
乘等(times-equal) 把原变量值乘上一个常量并重新赋值给变量 |
/= |
除等(slash-equal) 把原变量值除以一个常量并重新赋值给变量 |
%= |
模等(mod-equal) 把原变量值除以一个常量整除(即取模)并重新赋余数的值给变量 |
let "var += 5" # 会使变量var值加了5并把值赋给var.
let "var *= 4" # 使变量var的值乘上4并把值赋给var.
例子:
- 用10种不同的方法计数到11
- 最大公约数
- 整数变量符号的长整数测试,到2.05b版本为止,Bash支持64位的整数,以前的版本会有长度溢出错误。
- Bash不能处理浮点计算,它会把含有小数点的数当成字符串。
# 位操作符
位操作符很少在脚本中使用。他们主要用于操作和测试从端口或sockets中读到的数据。“位运算”更多地用于编译型的语言,比如说C和C++,它们运行起来快地像飞。
| 操作符 | 描述 | 操作符 | 描述 |
|---|---|---|---|
<< |
位左移(每移一位相当乘以2) | ` | ` |
<<= |
位左移赋值 | ` | =` |
>> |
位右移(每移一位相当除以2) | ~ |
位反 |
>>= |
“位右移赋值”(和<<=相反) | ! |
位非 |
& |
位与 | ^ |
位或 |
&= |
位于赋值 | ^= |
位或赋值 |
# <<=
# "位左移赋值"
let "var <<= 2" 结果使var的二进制值左移了二位(相当于乘以4)
# 逻辑操作符
逻辑与&&
