运行
test.sh
echo "test"
默认情况下 test.sh
并没有运行权限,需要使用以下的命令:
$ chmod +x test.sh
变量
var="runoob.com"
## 用语句赋值
## for file in `ls /etc`
## 或
## for file in $(ls /etc)
## 使用变量
echo $var
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
## 重新定义变量
var="My.com"
echo ${var}
## 只读变量
my="https://www.google.com"
#readonly my
## my="https://www.runoob.com" ## 这个不可以
## 删除变量
## unset my ## 只读变量不可删除
unset var ## 可以!
string 字符串
str='ffffffffffff' ## 所有一切照原样输出
## 转符无效
## 变量使用无效
str="ffffff" ## 可以用变量
## 可以转义
## 拼接字符串
qt="qt"
doc="doc"
io="io"
qt_addr="${qt}.${doc}.${io}"
echo $qt_addr
## 字符串长度
str="abcd"
echo ${#str} # 结果为 4
## 提取子字符串
str="runoob is a great site"
echo ${str:1:4} # 输出 unoo
## 从右边开始提取
str="runoob is a great site"
echo ${str:0-10:5} 61 row # 使用 0- 表示从右边开始提取
# 这一句的意思是,从右边向左 10 个字符
# 然后向左提取 5 个字符
## 提取子字符串的所有字符
url="http://c.biancheng.net/index.html"
echo ${url#*:} # 结果://c.biancheng.net/index.html
## * 通配符,表示任意长度的字符串
## *chars 表示忽略左边的所有字符,直到遇到 chars -- chars
## 最后一个指字的字符串 -- ##
url="http://c.biancheng.net/index.html"
echo ${url#*/} #结果为 /c.biancheng.net/index.html
echo ${url##*/} #结果为 index.html
str="---aa+++aa@@@"
echo ${str#*aa} #结果为 +++aa@@@
echo ${str##*aa} #结果为 @@@
## 查找子字符串
## 查找字符 i 或 o 的位置(哪个先出现就输出哪个的索引)
echo `expr index "$str" io` # 输出 4
数组
printf "\n# 数组\n"
arr=("abc" "efg" "hij")
echo ${arr[@]} ## 输出数组的所有元素
## 数组元素个数
length=${#arr[@]}
## length=${#arr[*]} ## 也可以
## 一个元素的长度
## length=${#arr[n]}
## 向组数中添加元素
arr[3]="fff"
### 用数组长度添加
arr[${#arr[@]}]="jack"
# 或
#arr[${#arr[*]}]="jack"
### 重新创建数组
arr=("${arr[@]}" "abc" "edf")
### 用 += 附加元素
arr+=("f" "f")
printf "\n%s\n" ${arr[@]}
多行注释
:<<EOF
ffff
fjskdlfjsdlfjsdl
jfdlkdsjflsd
EOF
# EOF 可以换成其他的符号
echo 命令
# echo 命令
# --------------------------------------------------------------------------------
echo "It is a test" # 可
echo It is a test # 可
## 显示转义符
echo "\"It is a test\""
# 显示变量
# --------------------------------------------------------------------------------
#read name # 从标准输入读取一行到 name
#echo "${name} It is a test"
# 显示换行
# --------------------------------------------------------------------------------
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
# 显示不换行
# --------------------------------------------------------------------------------
echo -e "OK! \c" # \c 换不行
echo "It is a test"
# 显示结果至定向至文件
# --------------------------------------------------------------------------------
echo "It is a test" > myfile.txt
# 原样输出字符串
# --------------------------------------------------------------------------------
echo '$name \"'
# 显示命令执行结果
# --------------------------------------------------------------------------------
echo `date`
printf 命令
printf "Hello, Shell\n"
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
## - 左对齐
printf %s abcdef
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
printf "%s and %d \n"
test 命令
# 数值测试 -- 判断
# 数字
# -eq ==
# -ne !=
# -gt >
# -ge >=
# -lt <
# -le <=
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
# [] 执行基本的算数运算,如:
a=5
b=6
result=$[a+b] # 等号两边不能有空格
echo "result 为:${result}"
## 字符串测试 -- 判断
# = 相等
# != 不相等
# -z 字符串 字符串长度为零则为真
# -n 字符串 字符串长度不为零则为真
str1="run1noob"
str2="runoob"
if test $str1 = $str2
then
echo "="
else
echo "!="
fi
## 文件测试
# -e 文件名 存在则为真
# -r 文件名 存在且可读则为真
# -w 文件名 存在且可写则为真
# -x 文件名 存在且可执行则真
# -s 文件名 存在且至少有一个字符则为真
# -d 文件名 存在且为目录则为真
# -f 文件名 存在且为普通文件则为真
# -c 文件名 存在且为字符特殊文件则为真
# -b 文件名 存在且为块特殊文件则为真
cd /bin
pwd
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
## 逻辑操作符
# -a 优先级其次
# -o 优先级最低
# ! 优先级最高
cd /bin
pwd
if test -e ./bash -o -e ./notfile
then
echo '文件存在至少一个!'
else
echo '两个文件都不存在!'
fi
shell 流程控制
# if
# then
# ...
# elif
# then
# ...
# else
# fi
a=10
b=20
if [ $a == $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合条件"
fi
## 使用((...)) 作为条件判断语句
c=15
d=25
if (( $a == $b ))
then
echo "a 等于 b"
elif (( $a > $b ))
then
echo "a 大于 b"
elif (( $a < $b ))
then
echo "a 小于 b"
else
echo "没有符合条件"
fi
for 循环
for loop in 1 2 3 4 56
do
echo The value is: $loop
done
## 字符串
for str in This is a string
do
echo $str
done
printf "\n## 遍历数组\n"
### 一
for ((i=0;i<${#arr[@]};i++))
do
echo ${arr[i]}
done;
### 二
for a in ${arr[@]}
do
echo ${a}
done
### 三
for i in "${!arr[@]}"
do
printf "%s\t%s\n" "$i" "${arr[$i]}"
done
printf "\n## 遍历数组\n"
while 语句
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
## Bash let 命令 -- 变量计中不需要加 $ 来表示变量
#echo '按下 <CTRL-D> 退出'
#echo -n '输入你最喜欢的网站名: '
#while read FILM
#do
#echo "是的!$FILM 是一个好网站"
#done
# 无限循环
# --------------------------------------------------------------------------------
#while :
#do
#command
#done
#while true
#do
#command
#done
#for (( ; ; ))
until
执行一系列命令,直到条件为真时停止
f=0
until [ ! $f -lt 10 ]
do
echo $f
f=`expr $f + 1`
done
# case ... esac
# --------------------------------------------------------------------------------
#echo "输入 1 到 4 之间的数字:"
#echo "你输入的数字为:"
#read aNum
#case $aNum in
#1) echo 你选择了 1
#;;
#2) echo 你选择了 2
#;;
#3) echo 你选择了 3
#;;
#4) echo 你选择了 4
#;;
#*) echo 你没有输入 1 到 4 之间的数字
#;;
#esac
case "$site" in
"runoob") echo "菜鸟教程"
;;
"google") echo "Google 搜索"
;;
"taobao") echo "淘宝网"
;;
esac
跳出循环
#while :
#do
#echo -n "输入 1 到 5 之间的数字:"
#read aNum
#case $aNum in
#1|2|3|4|5) echo "你输入的数字为 $aNum!"
#;;
#*) echo "你输入的数字不在 1 到 5 之间! game over"
#break
#;;
#esac
#done
#while :
#do
#echo -n "输入 1 到 5 之间的数字: "
#read aNum
#case $aNum in
#1|2|3|4|5) echo "你输入的数字为 $aNum!"
#;;
#*) echo "你输入的数字不是 1 到 5 之间的!"
#continue
#echo "游戏结束"
#;;
#esac
#done
function
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
## 有 return 的函数
funWithReturn(){
echo "这个函数会对输入的两个数字进行加法运算..."
echo "输入第一个数字:"
read aNum
echo "输入第二个数字:"
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum + $anotherNum))
}
funWithReturn
echo 输入的两个数字之和为 $? !
## 函数参数
funWithParam(){
echo "para one $1 !"
echo "para two $2 !"
echo "ten $10 !"
echo "ten ${10} !"
echo "eleven ${11} !"
echo "参数总数$# !"
echo "作为一个字符串输出所有参数$* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 3 4 1222
funWithParam 1 2 3 4 5 6 7 8
## 特殊符号
# $# 参数个数
# $* 以一个单字符串显示所有向脚本传递的参数
# $$ 脚本运行的当前进程 ID 号
# $! 后台运行的最后一个进程的 ID 号
# $- 显示 Shell 使用的当前选项,与 set 命令功能相同
# $? 显示最后的通出状态,0 表示没有错误,其他任何值表示有错误
重定向
# command > file 输出定向到 file
# command < file 输入定向到 file
# commnad >> file 输出以追加的方式定向到 file
# n > file 将文件描述符为 n 的文件定向到 file
# n >> file 将文件描述符为 n 的文件以追加方式定向到 file
# n >& m 将输出文件 m 和 n 合并
# n <& m 将输入文件 m 和 n 合并
# << tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入
### 需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
## 重定向解析
#一般情况下,每个 Unix/Linux 命令运行都会打开三个文件:
#标准输入文件(stdin): stdin 的文件描述符为 0 ,Unix 程序默认从 stdin 读取数据。
#标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
#标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
# 默认情况下 command > file 将 stdout 重定向到 file
# command < file 将 stdin 重定向到 fil
# 如果希望将 stderr 重定向到 file:
# command 2> file
# 追加
# command 2>> file
# 如果希望将 stdou 和 stderr 合并后重定向到 file
# command > file 2>&1
# 或
# command >> file 2>&1
# 对 stdin 和 stdou 都重定向
# command < file1 > file2
Here Document
# Here Document 是 shell 中的一种特殊重定向方式,用来将输入重定向到一个交互式 shell 脚本或程序,基本形式:
# command <, delimiter
# document
# delimiter
# 它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
#结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
#开始的delimiter前后的空格会被忽略掉。
/dev/null 文件
#/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
#如果希望屏蔽 stdout 和 stderr,可以这样写:
# command > /deve/null 2>$1
# Shell 文件包含
# 在一个 sh 文件中,可以使用另一个 sh 的内容
# . filename
# 或
# source filename
# 注:被包含的文件 test1.sh 不需要可执行权限。
# 命令行参数 -- 见 ./command-line-args.sh
declare
## -a 声明一个组数
## -i 声明一个整型
## -f 打印所有函数定义
## -F 仅打印函数名字
## -r 声明一个只读变量
## -x 与 export 的作用类似
declare -a distance=("Eulidean" "consine" "motyka")
shell 赋值
a=2
b=3
declare -i reslut='a * b'
计时
# 使用现在的时间,进行计算
#
# # 统计时间
# now=`date +'%Y-%m-%d %H:%M:%S`
# start_time=$(date --date="$now" +%s);
#
# now=`date +'%Y-%m-%Ed %H:%M:%S`
# end_time=$(date --date="$now" +%s);
# echo "used time:"$((end_time-start_time))"s"
参考网址
runoob shell 教程
bash + utilities reference