美文网首页
shell快速使用笔记

shell快速使用笔记

作者: Mr_Michael | 来源:发表于2019-04-12 11:47 被阅读0次

shell 脚本的第一行以:#!/bin/sh 或 #!/bin/bash 开头

基础变量

1.多行注释

:<<EOF
# #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
# 首次运行出错运行:sed -i -e 's/\r$//' xxx.sh
EOF

2.变量定义与调用

name="michael"  #变量名和等号之间不能有空格      !!!
echo ${name}    #调用变量:$变量名 或 ${变量名}
readonly name   #设置为只读变量
echo "My name is $name"
unset name      #删除变量,不能删除只读变量
var=`ls`  # ` `是命令运行的结果,等价于$( )

注意:赋值的时候,等号两边有空格会报错

3.整型

a=1
#第一种整型变量自增方式
a=$(($a+1))
#第二种整型变量自增方式
a=$[$a+1]
#第三种整型变量自增方式
a=`expr $a+1`
#第四种整型变量自增方式
let a++
#第五种整型变量自增方式
let a+=1
#第六种整型变量自增方式
((a++))

3.字符串

str='this is a string "name" $name' #单引号字符串中的变量是无效的
str2="this is a string \"name\" $name"  #双引号里可以有变量和转义字符
#拼接字符串
str3='hello,'$str''
str4="hello,$str2"
#获取字符串长度
echo ${#name}
#提取子字符串
str5=${str4:0:5}    #第0个字符开始截取5个字符
#判断字符串是否包含某个字符串,方法1
strA="helloworld"
strB="low"
if [ $strA =~ $strB ]
then
  echo "包含"
else
  echo "不包含"
fi
#判断字符串是否包含某个字符串,方法2
strA="long string"
strB="string"
result=$(echo $strA | grep "${strB}")
if [ "$result" != "" ]
then
  echo "包含"
else
  echo "不包含"
fi

4.数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

num=(1 2 3 4 5) #用括号来表示数组,数组元素用"空格"符号分割开
students=("jack" "tom" "mike" "sherry" "ming")
echo ${num[0]}
# 获取数组所有元素
echo "array:,${students[*]}"
# 获取数组元素的个数
echo "length of array:,${#students[*]}"
# 取得数组单个元素的长度
echo "length of array element:,${#students[0]}"

5.脚本参数传递

向脚本传递参数,脚本内获取参数的格式为:$n, n 代表一个数字。
$# 为传递参数的个数
$* 以一个单字符串显示所有向脚本传递的参数。
$@ 作为迭代器返回每个参数,使用时加引号:"$@"
$0 为执行的文件名
$1 为执行脚本的第一个参数, $2 为执行脚本的第二个参数, 当n>=10时,需要使用${n}来获取参数。
$? 最后命令的退出状态,0代表没有错误
echo "执行的文件名:$0"
echo "参数个数:$#"
echo "传递的参数作为一个字符串显示:$*";
echo "第一个参数:$1"
echo "第二个参数:$2"
for i in "$@"; do
    echo $i
done

运算操作

1.算术运算

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr。

val=`expr 2 + 6`    #使用反引号而不是单引号,运算符之间必须用空格隔开
val=`expr 2 \* 6`
val=`expr 12 / 3`
val=`expr 13 % 3`
val=`expr 3 == 3`

#等价于
val=$((2+6))

2.关系运算

-eq #等于
-ne #不等于
-gt #大于
-lt #小于
-ge #大于等于
-le #小于等于
#中括号两边必须有空格
if [ $a -eq $b ]    #等于 [ ]是执行运算
then
    echo "result is true"
else
    echo "result is false"
fi

3.布尔运算

-o #或
-a #且
!  #非
if [ $a -eq $b -o $a -lt $b ]   #或
then
    echo "result is true"
else
    echo "result is false"
fi

if [ ! $a -ne $b ]              #非
then
    echo "result is true"
else
    echo "result is false"
fi
if ($i<5)
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]

4.字符串运算

=   检测两个字符串是否相等
!=  检测两个字符串是否不相等
-z  检测字符串长度是否为0
-n  检测字符串长度是否不为0
$   检测字符串是否为空
if [ $c = $d ]      #用==也可以     
then
    echo "result is true"
else
    echo "result is false"
fi

if [ -z $c ]        
then
    echo "result is true"
else
    echo "result is false"
fi
  1. 文件运算

参数 说明
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真

#这里的-x 参数判断$myPath是否存在并且是否具有可执行权限  
if [ ! -x "$myPath"]; then  
  mkdir "$myPath"  
fi  

#这里的-d 参数判断$myPath是否存在  
if [ ! -d "$myPath"]; then  
  mkdir "$myPath"  
fi  

#这里的-f参数判断$myFile是否存在  
if [ ! -f "$myFile" ]; then  
  touch "$myFile"  
fi  

6.各种括号的用途
shell中各种括号的作用()、(())、[]、[[]]、{}

1)小括号
():括号内的命令会在一个子shell中执行
(( )):将括号内的数值进行比较与运算
$( ):命令替换,等同于反引号` `,将$()内的cmd执行一次,得到其标准输出,再将此输出放到原来命令。
$(( )):整数运算

for ((i=0;i<5;i++));do echo $i;done  

echo $((3+2))
echo $((3>2)) 
echo $((var=2+3))  
echo $((var++)) 

2)中括号
[ ]:条件测试
[[ ]]:支持正则表达式的条件测试
$[ ]:整数运算

if [ $a -ne 1 -a $a != 2 ]  
if [ $a -ne 1] && [ $a != 2 ]  
if [[ $a != 1 && $a != 2 ]]  

3)大括号
{ }:对括号内的一组字符进行操作
${ }:变量的引用

流程控制

1.if else

#格式
if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

2.for循环

#格式
for var in item1 item2 ... itemN    #迭代器
do
    command1
    command2
    ...
    commandN
done
for str in 'This is a string'
do
    echo $str
done

3.while循环

#格式
while condition
do
    command
done
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done
#无限循环
while : #或while true
do
    command
done

for (( ; ; ))
do
    command
done

4.case

#格式
case var in
mode1)
    command1
    command2
    ...
    commandN
    ;;
mode1)
    command1
    command2
    ...
    commandN
    ;;
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

函数

1.函数定义与调用

#格式 []表示可选
[ function ] funname [()]
{
    action;
    [return int;]
}
demoFun(){
    echo "这是一个 shell 函数!"
}

demoFun #函数调用

2.函数参数

与脚本传递参数类似

获取参数的格式为:$n, n 代表一个数字。
$# 为传递参数的个数,不算函数名
$* 以一个单字符串显示所有向函数传递的参数。
$@ 作为迭代器返回每个参数,使用时加引号:"$@"
$0 为执行的函数名
$1 为执行函数的第一个参数, $2 为执行函数的第二个参数, 当n>=10时,需要使用${n}来获取参数。
$? 最后命令的退出状态,0代表没有错误
funWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

输入输出重定向

将一个命令的标准输入/输出 重定向到其他文件。

1.重定向命令列表

命令 说明
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 之间的内容作为输入。

文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)

#输出重定向 从默认的标准输出设备(终端)重定向到指定的文件。
echo "hello" > test.c

#输入重定向 本来需要从键盘获取输入的命令会转移到文件读取内容。
echo < test.c

#输入重定向 将标记之间的内容作为输入
cat << EOF
hello
world
EOF

2./dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null

echo "hello" > /dev/null

文件包含

在脚本中调用别的脚本

test2.sh 代码

#!/bin/bash

#使用 . 号来引用test1.sh 文件
. ./test1.sh

#使用 source来引用test1.sh 文件
source ./test1.sh

文件操作

  • 读取文件中的内容,并将其存入到变量中
    var=$(cat name.txt)  #或
    metric=`cat name.txt` #` `是命令执行的结果
    
  • 读取文件中的某一行的内容
    sed -n '1p' filename #打印文件的第1行
    sed '/user/d' filename #删除包含“user”的行
    sed '2d' filename #删除第2行
    sed '$d' filename #删除最后一行
    
  • 读取文件中的某一行某一列的内容
    sed -n ‘1p’ filename | cut -d ' ' -f1 #打印文件的第1行第1列的内容
    
  • 读取文件中的某一行某一字段的内容
    sed -n ‘1p’ filename | awk 'NR==1 {print $1}'  #打印文件的第1行第1字段的内容
    

常用字符

1.shell通配符

字符 含义 实例
* 匹配 0 或多个字符 a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, axyzb, a012b, ab。
? 匹配任意一个字符 a?b a与b之间必须也只能有一个字符, 可以是任意字符, 如aab, abb, acb, a0b。
[list] 匹配 list 中的任意单一字符 a[xyz]b a与b之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
[!list] 匹配 除list 中的任意单一字符 a[!0-9]b a与b之间必须也只能有一个字符, 但不能是阿拉伯数字, 如axb, aab, a-b。
[c1-c2] 匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b... a9b。
{string1,string2,...} 匹配 sring1 或 string2 (或更多)其一字符串 a{abc,xyz,123}b a与b之间只能是abc或xyz或123这三个字符串之一。

2.元字符 (特殊字符)

字符 说明
IFS 由 <space> 或 <tab> 或 <enter> 三者之一组成(我们常用 space )。
CR 由 <enter> 产生。
= 设定变量。
$ 作变量或运算替换(请不要与 shell prompt 搞混了)。
> 重导向 stdout。 *
< 重导向 stdin。 *
| 命令管线。 *
& 重导向 file descriptor ,或将命令置于后台执行。 *
( ) 将其内的命令置于 nested subshell 执行,或用于运算或命令替换。 *
{ } 将其内的命令置于 non-named function 中执行,或用在变量替换的界定范围。
; 在前一个命令结束时,而忽略其返回值,继续执行下一个命令。 *
&& 在前一个命令结束时,若返回值为 true,继续执行下一个命令。 *
|| 在前一个命令结束时,若返回值为 false,继续执行下一个命令。 *
! 执行 history 列表中的命令。*

3.转义字符

字符 说明
‘’(单引号) 又叫硬转义,其内部所有的shell 元字符、通配符都会被关掉。注意,硬转义中不允许出现’(单引号)。
“”(双引号) 又叫软转义,其内部只允许出现特定的shell 元字符:$用于参数代换 `用于命令代替
(反斜杠) 又叫转义,去除其后紧跟的元字符或通配符的特殊意义。

相关文章

网友评论

      本文标题:shell快速使用笔记

      本文链接:https://www.haomeiwen.com/subject/qqzqwqtx.html