创建及执行
#!/bin/bash #约定标记
echo "Hello World !"
shell执行:
chmod +x shell.sh
./shell.sh
shell变量
变量名= "变量值"
for file in `ls .`;do
echo "$file"
done
# 列出当前目录下的文件名
只读变量
readonly 变量名
删除变量
unset 变量名
字符串
单双引号区别
字符串拼接
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
获取字符串长度
string="abcd"
echo ${#string} #输出 4
字符串截取
# ## 删除左边,保留右边 echo ${var##*字符} 两个#表示最后一个字符
% %% 删除右边,保留左边 echo ${var%字符*} 两个%表示最后一个字符
单行注释
# 注释
多行注释
:<<EOF
注释内容
EOF
shell传参
./test.sh 参数1 参数2 参数3 ...
$0 执行的文件名及路径
$1 $2 $3 第1、2、3个参数
$* 显示传递的所有参数
$@ 分别显示传递的所有参数
echo "-- \$* 演示 ---"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示 ---"
for i in "$@"; do
echo $i
done
$ chmod +x test.sh
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3
shell数组
定义数组
array_name=(value1 value2 ... valuen)
读取数组
${array_name[index]}
获取数组所有元素
${array_name[@]}
${array_name[*]}
获取数组长度
${#array_name[@]}
${#array_name[*]}
例:
#!/bin/bash
test_array = (a b c d)
echo "第3个元素是:${test_array[2]}"
echo "所有元素:${test_array[*]}"
echo "数组长度:${#test_array[@]}"
#输出结果
第3个元素是:c
所有元素:a b c d
数组长度:4
shell运算符
- 算数运算符
#!/bin/bash
a=10
b=10
val=`expr $a + $b` # expr 用``包含
echo "a + b : $val"
if [[ $a == $b ]] # 条件表达式要放在方括号之间,并且要有空格。
then
echo "a等于b"
fi
# 使用 [[ ... ]] 条件判断结构,而不是 [ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、< 和 > 操作符能够正常存在于 [[ ]] 条件判断结构中,但是如果出现在 [ ] 结构中的话,会报错。
- 关系运算符
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
- 布尔运算符
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
- 字符串运算符
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否不相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n "$a" ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
- 文件测试运算符
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
echo 命令
#!/bin/sh
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"
输出:OK!It is a test
实例, 文件 test.sh:
read -p "请输入一段文字:" -n 6 -t 5 -s password
echo -e "\npassword is $password"参数说明:
-p 输入提示文字
-n 输入字符长度限制(达到6位,自动结束)
-t 输入限时
-s 隐藏输入内容
./test.sh
请输入一段文字:
password is abcdef
frintf命令
printf format-string [arguments...]
$ printf "%d %-2s %c %-3.2f\n" 1111 "abc" "def" 3.1413
1111 ab d 3.14
%-2s 指一个宽度为 2 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 2 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-3.2f 指格式化为小数,其中 .2 指保留2位小数
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。
shell test命令
数值测试
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
字符串测试
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真
文件测试
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真
-O 判断对象是否存在,并且属于当前用户
-G 判断对象是否存在,并且属于当前用户组
-nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ]
另外,Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低。例如:
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
流程控制
if else
if condition1
then
command1
command2
elif condition2
then
command3
else
commadn4
fi
For 循环
for loop in 1 2 3
do
echo "$loop"
done
While语句
while condition
do
command
done
无限循环
while :
do
command
done
或者
for (( ; ; ))
until循环
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
Case...esac
case 值 in
模式1)
command
;; #;;表示break
模式2)
command
;;
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
调出循环
break
continue
shell函数
function funname [()]
{
action;
[return int;]
}
例:
#!/bin/bash
function demofun1(){
echo "shell函数demo"
return 0
}
demofun1
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 之间的内容作为输入。
ls >> ls.txt
cat ls.txt
command 2>>file #报错追加到文件末尾
command >> file 2>&1
文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
command > /dev/null # /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃
command > /dev/null 2>&1 # 禁止输出
输入重定向
command1 < file1
Here Document :它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
command << delimiter
document
delimiter
例:
shell文件包含
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
例:
#!/bin/bash
# shell1.sh
name=(1 2 3 4 5) #定义那么数组
#!/bin/bash
# shell2.sh
. ./shell1.sh # 引用shell1.sh
for i in ${name[*]};do # 循环显示数组元素
echo "$i"
done
[root@VM-16-2-centos ~]# ./shell2.sh
1
2
3
4
5