#!
告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序$ chmod +x ./test.sh
添加可执行属性
变量
shell 变量
变量命名
正常的变量名字符限制命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
,php
脚本中变量名需要$
符号变量不需要声明,直接赋值使用
unset
删除非readonly
变量变量类型
局部变量:当前shell
脚本生效
环境变量:所有的shell
脚本均生效
字符串
字符串拼接
单引号拼接:'Hello, '$name' and ${name_1}'
双引号拼接:"Hello, "$name" and ${name_1}"
获取字符串长度
${#var_string}
或者expr length "$string"
截取字符串
${var_string:1:4}
是index:count
查找字符串
`expr index "$var_string" ha`
查询变量$var_string
中的h
或者a
字符第一次出现的index
数组
只支持一维
定义
var_array=(value1 value2 value3)
赋值
var_array=value4
取值
${var_array[index]}
,取得所有值${var_array[@]}
数组长度
${#var_array[@]}
,${#var_array[*]}
注释
- 单行
#
- 多行
:<<"
注释内容...
注释内容...
注释内容...
"
EOF可以是其它字符如:单/双引号
Tips:
引号的使用
单引号不能包含变量,只能做常量的字符串处理
双引号可以包含变量和转义双引号中连接的变量写法
$var_name
和${var_name}
都可以,建议使用后者!遍历文件夹
for file in `ls /etc`
# 或
for file in $(ls /etc)
参数传递
脚本参数
执行时传参
echo "File name: $0"; echo "Param1: $1"
参数处理字符
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与[set命令](http://www.runoob.com/linux/linux-comm-set.html)功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
- 包含空格的参数应当使用双引号
" "
运算符
算术运算符
-
*
在非Mac $((表达式))
中需要增加转义 -
==
和!=
应用于数字比较[ $a == $b ]
带空格! -
$(($aNum+$anotherNum))
这个需要两个括号!
关系运算符
-eq 检测两个数是否相等,相等返回 true。
-ne 检测两个数是否不相等,不相等返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。
布尔运算符
- 符号
!
-o
-a
逻辑运算符
- 符号
&&
||
字符串运算符
- 符号
=
!=
-z (length -eq 0)
-n (length -ne 0)
str(null)
文件测试运算符
- 符号
-b file 检测文件是否是块设备文件,如果是,则返回 true
-c file 检测文件是否是字符设备文件,如果是,则返回 true
-d file 检测文件是否是目录,如果是,则返回 true
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true
-p file 检测文件是否是有名管道,如果是,则返回 true
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true
-r file 检测文件是否可读,如果是,则返回 true
-w file 检测文件是否可写,如果是,则返回 true
-x file 检测文件是否可执行,如果是,则返回 true
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true
-e file 检测文件(包括目录)是否存在,如果是,则返回 true
显示echo
不换行
echo "Hello \c"
显示结果到文件
echo "It is a test" > myfile
显示执行结果
`date`
关键字 read
- 输入参数
-p 输入提示文字
-n 输入字符长度限制(达到6位,自动结束)
-t 输入限时
-s 隐藏输入内容
关键字 printf
- 使用格式
printf [控制符] [参数列表]
- 控制符说明
%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。
[%c 自动截取字符串的第一个字符]
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f 换页(formfeed)
\n 换行
\r 回车(Carriage return)
\t 水平制表符
\v 垂直制表符
\\ 一个字面上的反斜杠字符
\ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd 表示1到3位的八进制值字符
流程控制
if(then)
elif
fi
else
for tmp in itme1 itme2 ... itemN; do cmd1; cmd2; ... done;
#!/bin/bash
for((i=1;i<=5;i++));do
echo "这是第 $i 次调用";
done;
- while
while condition
do
cmd
done
- 无限循环
while :
do
command
done
while true
do
cmd
done
for(( ; ; ))
- until
until condition
do
cmd
done
- case
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
*)
command1
command2
...
commandN
;; # break
esac
函数
- 格式:
[ function ] funname [()]
{
action;
[return int;]
}
funname # invoke no '()'
- 函数的参数:
QA
1. ubuntu(linux)下 source、sh、bash、./ 执行脚本的区别是什么?
source
命令用法:
source FileName
作用:在当前bash
环境下读取并执行FileName
中的命令。该filename
文件可以无 "执行权限"。
注:该命令通常用命令.
来替代。sh
、bash
的命令用法:
sh FileName
或bash FileName
作用:打开一个子shell
来读取并执行FileName
中命令。该filename
文件可以无 "执行权限"。
注:运行一个shell
脚本时会启动另一个命令解释器。
3、./
的命令用法:
./FileName
作用: 打开一个子 shell
来读取并执行 FileName
中命令,该 filename
文件需要 "执行权限"。
注:运行一个 shell
脚本时会启动另一个命令解释器。
2. 截取字符串的八种方法
Linux 的字符串截取很有用。有八种方法。
假设有变量 var=http://www.aaa.com/123.htm
#
号截取,删除左边字符,保留右边字符。
echo ${var#*//}
其中var
是变量名,#
号是运算符,*//
表示从左边开始删除第一个//
号及左边的所有字符
即删除http://
结果是 :www.aaa.com/123.htm
##
号截取,删除左边字符,保留右边字符。
echo ${var##*/}
##*/
表示从左边开始删除最后(最右边)一个/
号及左边的所有字符
即删除http://www.aaa.com/
结果是123.htm
%
号截取,删除右边字符,保留左边字符
echo ${var%/*}
%/*
表示从右边开始,删除第一个/
号及右边的字符
结果是:http://www.aaa.com
%%
号截取,删除右边字符,保留左边字符
echo ${var%%/*}
%%/*
表示从右边开始,删除最后(最左边)一个/
号及右边的字符
结果是:http:
从左边第几个字符开始,及字符的个数
echo ${var:0:5}
其中的0
表示左边第一个字符开始,5
表示字符的总个数。
结果是:http:
从左边第几个字符开始,一直到结束。
echo ${var:7}
其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm
从右边第几个字符开始,及字符的个数
echo ${var:0-7:3}
其中的0-7
表示右边算起第七个字符开始,3
表示字符的个数。
结果是:123
从右边第几个字符开始,一直到结束。
echo ${var:0-7}
表示从右边第七个字符开始,一直到结束。
结果是:123.htm
注:(左边的第一个字符是用0
表示,右边的第一个字符用0-1
表示)
描述的有点儿不容易懂,看了好久才勉强明白 #
##
%
%%
#
、##
表示从左边开始删除。一个 #
表示从左边删除到第一个指定的字符;两个 #
表示从左边删除到最后一个指定的字符。
%
、%%
表示从右边开始删除。一个 %
表示从右边删除到第一个指定的字符;两个 %
表示从左边删除到最后一个指定的字符。
删除包括了指定的字符本身。
Practice
- 九九乘法表
#!/bin/bash
number=0
if [ -z "$1" ]
then
read -p "Input the number: " number
else
number=$1
fi
if [ $number -ge 1 ] && [ $number -le 9 ]
then
i=1
while([ $i -le $number ])
do
j=1
while([ $j -le $i ])
do
echo -e "$j*$i=$(($i*$j))\t\c"
# let "j++" # increase
j=`expr $j + 1`
done
echo ""
# let "i++" # increase
i=`expr $i + 1`
done
else
echo "Input number should be 1-9 !!!"
fi
read -p "Any key to exit!"
exit 0
- 随手就是一打
#!/bin/bash
var_name="Nice day" # '=' no whitspace here
echo "var_name = ${var_name}" # '${var_name}' insteand of $'var_name', user '\' to comente
readonly var_name
var_name="Six, six, six" # It is illegal: readonly
unset var_name # cannot unset a readonly var
echo ""
var_name_1="This is a new var"
unset var_name_1
echo "after unset: var_name_1 = ${var_name_1}"
echo ""
echo "after unset:
for i in "$@" var_name_1 = ${var_name_1}"
echo ""
_name="anter"
echo 'hello,' $_name '!'
echo 'length' ${#_name} '!'
echo ${_name:2:-1} # index:count, but -1 ...
echo ""
_name="What is your name"
echo `expr index "$_name" name`
echo ""
echo "File name: $0"
echo "Param: $1"
echo "参数个数: $#"
echo "单行显示所有参数: $*"
echo "当前进程号: $$"
echo "后台程序最后一个进程号: $!"
echo "显示所有参数: $@"
echo "显示Shell使用的当前选项: $-"
echo "显示最后命令的退出状态 0表示没有错误: $?"
echo "参数: " $i
echo ""
a=$1
b=$2
if [ $a == $b ]
then
echo "$a == $b"
fi
file="/c/Users/Anter/Desktop/test1.sh"
if [ -s $file ]
then
echo "File exist"
else
echo "File don't exist"
fi
echo ""
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
:<<EOF
This is a comment, invisiable
This is a comment, invisiable
This is a comment, invisiable
This is a comment, invisiable
This is a comment, invisiable
EOF
read -p "Press any key to exit"
exit 0