2018-06-04 linux shell脚本命令记录
1、变量+字符串+数组
变量
定义变量的原则:
注意,变量名和等号之间不能有空格。
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
#!/bin/bash
# #!指定用什么shell脚本必须放在开头
your_name="runoob.com"
# readonly 设置只读属性,该属性下变量无法删除
readonly your_name
# unset 删除一个变量 echo后会不显示,不报错
unset your_name
# echo 打印到屏幕 $ ${}都可代表变量,后者字符串内用得多
echo $your_name
# 变量可重新赋值
your_name="prohub.com"
echo $your_name
字符串
单引号和双引号都区别:
单引号不支持转义和引入变量,双引号支持。
#!/bin/bash
your_name="hero"
str1='hello! you is /$your_name/'
str2="hello! you is ${your_name}s"
str3="hello! you is\"$your_name\""
echo $str1
echo $str2
echo $str3
# 打印字符串长度
echo ${#str3}
# 切片 参数 字符串:开头位置:步数
echo ${str3::2}
# 判断位置,外层是反引号,不是单引号
echo `expr index "$str3" you`
result:
hello! you is /$your_name/
hello! you is heros
hello! you is"hero"
19
he
5
数组
#!/bin/bash
# 两种定义方式
arr1=(1 2 7)
arr2[0]="hello"
arr2[1]="word"
# 默认打印第一个元素
echo $arr1
# 指定打印哪个索引元素
echo ${arr1[1]}
# @打印所有元素
echo ${arr1[@]}
# 查询整个数组长度
echo ${#arr1[@]}
# 查询数组内某个元素长度
echo ${#arr2[1]}
result:
1
2
1 2 7
3
4
#!/bin/bash
my_array=(A B "C" D)
for i in "${my_array[*]}"; do
echo $i
done
for i in "${my_array[@]}"; do
echo $i
done
result
-------------------------
A B C D
A
B
C
D
2、脚本参数的传递
test.sh
--------------------
#!/bin/bash
echo "文件名:$0";
echo "参数1:$1";
echo "参数2:$2";
echo "参数3:$3";
echo "参数个数:$#"
echo "全部参数合并一个参数:$*"
echo "显示全部参数:$@"
result
-------------------
$ chmod +x test.sh
$ ./test.sh 1 2 3
文件名:./test.sh
参数1:1
参数2:2
参数3:3
参数个数:3
全部参数合并一个参数:1 2 3
显示全部参数:1 2 3
备注:
1.$和$@都是显示所有参数,区别在于通过for循环都话,$是循环一次,结果是1 2 3,$@是循环三次,把参数循环打印出来。(参考数组循环例子)
2.如果要把空格当作一个参数传递都话,记得加单引号或双引号。
3、shell运算
shell支持的运算符类型包括:算数/关系/布尔/字符串/文件测试
算数运算符
#!/bin/bash
# 运算符左右必须有空格,[ ]内部前后也要有空格
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
# *前面要加反斜杠
val=`expr $a \* $b`
echo "a * b : $val"
val=`expr $b / $a`
echo "b / a : $val"
val=`expr $b % $a`
echo "b % a : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
result
----------------------
a + b : 30
a - b : -10
a * b : 200
b / a : 2
b % a : 0
a 不等于 b
关系运算符
#!/bin/bash
a=10
b=20
# -eq 检测两个数是否相等,相等返回 true。
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
# -ne检测两个数是否不相等,不相等返回 true。
if [ $a -ne $b ]
then
echo "$a -ne $b: a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
# 检测左边的数是否大于右边的,如果是,则返回 true。
if [ $a -gt $b ]
then
echo "$a -gt $b: a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
# -lt检测左边的数是否小于右边的,如果是,则返回 true。
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
# -ge 检测左边的数是否大于等于右边的,如果是,则返回 true。
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
# -le 检测左边的数是否小于等于右边的,如果是,则返回 true。
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
result
---------------------------------------------
10 -eq 20: a 不等于 b
10 -ne 20: a 不等于 b
10 -gt 20: a 不大于 b
10 -lt 20: a 小于 b
10 -ge 20: a 小于 b
10 -le 20: a 小于或等于 b
布尔运算符
#!/bin/bash
a=10
b=20
# !非运算
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
# -a 与运算
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
# -o 或运算
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
result
---------------------------------------------------------
10 != 20 : a 不等于 b
10 小于 100 且 20 大于 15 : 返回 true
10 小于 100 或 20 大于 100 : 返回 true
10 小于 5 或 20 大于 100 : 返回 false
逻辑运算符
#!/bin/bash
a=10
b=20
# $$ AND
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
# || OR
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
result
----------------------------------------------
返回 false
返回 true
字符串运算符
#!/bin/bash
a="abc"
b="efg"
# = 检测两个字符串是否相等
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
# != 不等于
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
# -z 字符串长度为0 为0 true
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
# -n 字符串长度不为0 true
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
# str 字符串不为空 true 可写成[ $a ]
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
result
--------------------------------------------
abc = efg: a 不等于 b
abc != efg : a 不等于 b
-z abc : 字符串长度不为 0
-n abc : 字符串长度不为 0
abc : 字符串不为空
文件测试符
#!/bin/bash
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
result
---------------------------
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在
4、echo命令
能否引用变量 | 能否引用转移符 | 能否引用文本格式符(如:换行符、制表符)
单引号 | 否 | 否 | 否
双引号 | 能 | 能 | 能
无引号 | 能 | 能 | 否
#!/bin/bash
echo "Hello World !"
echo Hello World !
echo "\"Hello World !\""
# -e 开启转义 \n换行
echo -e "Hello \nWorld !"
# \c 不换行
echo -e "hi \c"
echo "Hello World !"
echo `date`
result
-------------------------------------------
Hello World !
Hello World !
"Hello World !"
Hello
World !
hi Hello World !
Mon Jun 11 06:28:00 UTC 2018
read 命令一个一个词组地接收输入的参数,每个词组需要使用空格进行分隔;如果输入的词组个数大于需要的参数个数,则多出的词组将被作为整体为最后一个参数接收。
read firstStr secondStr
echo "第一个参数:$firstStr; 第二个参数:$secondStr"
result
------------------------------
$ sh test.sh
一 二 三 四
第一个参数:一; 第二个参数:二 三 四
read -p "请输入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"
result
--------------------------------
-p 输入提示文字
-n 输入字符长度限制(达到6位,自动结束)
-t 输入限时
-s 隐藏输入内容
$ sh test.sh
请输入一段文字:
password is asdfgh
printf 命令
printf 命令模仿 C 程序库(library)里的 printf() 程序。
printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
#!/bin/bash
# format-string为双引号
printf "%d %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"
result
-------------------------------------------
1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j
and 0
d: Decimal 十进制整数 -- 对应位置参数必须是十进制整数,否则报错!
s: String 字符串 -- 对应位置参数必须是字符串或者字符型,否则报错!
c: Char 字符 -- 对应位置参数必须是字符串或者字符型,否则报错!
f: Float 浮点 -- 对应位置参数必须是数字型,否则报错!
如:其中最后一个参数是 "def",%c 自动截取字符串的第一个字符作为结果输出。
$ printf "%d %s %c\n" 1 "abc" "def"
1 abc d
shell循环流程控制
在shell语句里,如果没有条件的话,不要写,比如if else 里的else里没条件,不要写
# if流程控制
if condition
then
command1
command2
...
commandN
fi
# if else流程控制
if condition
then
command1
command2
...
commandN
else
command
fi
# if elif else流程控制
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
eg=======================
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
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
============================
# while流程控制
while condition
do
command
done
eg=====================
#!/bin/sh
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
echo "是的!$FILM 是一个好网站"
done
========================
# 死循环
while :
do
command
done
# until流程控制(直到什么条件才结束)
until condition
do
command
done
#case流程控制
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
eg=================
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
==================
# break终止跳出循环
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
# continue跳出当前循环
#!/bin/bash
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
shell函数
shell里可自定义函数,然后调用。
格式:
# ()可带参数,也可不带
[ function ] funname [()]
{
action;
# 返回数据
[return int;]
}
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
shell输入输出重定向
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
shell文件包含
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
eg:
test1.sh
#!/bin/bash
url="http://www.runoob.com"
test2.sh
#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "$url"
result
======================
$ chmod +x test2.sh
$ ./test2.sh
http://www.runoob.com