跳到主要内容

Shell 入门

变量​

  • 定义变量是变量名 不加 $ 读取的时候 +$

字符串​

双引号​

  • 双引号可以有变量
  • 双引号可以出现转义字符

单引号​

  • 单引号李的任何字符串原样输出,单引号字符串变量无效
  • 单引号字符串中不能出现单独一个单引号,可以成对出现,作为字符串拼接使用

获取字符串长度​

str ="test"
echo ${#str} # 输出 4

提取子字符串​

第一个开始位置 2长度

str ="test"
echo ${str:1:2} #

查找字符串​

查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):

str="testestt"
echo `expr index "$str" io`

数组​

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

定义数组​

arr=(1,2,3,4)

# 或
arr=(
1,
2,
3,
4
)

读取数组​

arr=(1,2,3,4)
echo ${arr[1]}
# @ 表示所有
echo ${$arr[@]}

获取数组长度​

arr=(1,2,3,4,5,6)
length=${#arr[@]}
length=${#arr[*]}
# 获取单个数组元素长度
length=${#arr[n]}

Shell 注释​

以 # 开头的行就是注释,会被解释器忽略。

#单行注释

:<<注释 (EOF)


注释

Shell 传递参数​

我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……


#!/bin/bash

# 使用脚本需要赋予权限 chmod +x xxx.sh

echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

参数处理参数说明
$#传递到脚本个数
$*以一个单字符串显示所有脚本传递参数
$$获取当前进程ID
$!后台运行的最后一个进程的ID
$@与 $*相同 并在引号中返回每个参数
$-显示Shell使用的当前选项
$?显示最后命令退出的状态,0表示没有错误 ,其它显示有错误

Shell运算符​

关系运算符​

运算符说明举例
-eq检查是否相等[$a -eq $b]
-ne检查两个数是否相等
-gt检查左边是否大于右边
-lt检查右边是否小于左边
-ge检查左边的是否大于右边
-le检查左边的数是否小于右边

布尔运算符​

运算符说明举例
-o或运算符
!非运算符![false]
-a与运算符

字符串运算符​

运算符说明举例
=检查两个字符串是否相等 相等返回true[$a=$b]
!=检查两个字符串是否不相等
-z检查字符串长度是否为0
-n检查字符串长度是否不为0
$检查字符串是否不为空

文件测试运算符​

操作符说明举例
-b file检查文件是否为块元素
-c file检查文件是否是字符串文件
-d file检查文件是否为目录
-f file检查文件是否为普通文件
-g file检查文件是否设置SGID位
-k file检查文件是否设置了粘着位
-p file检查文件是否有管道名
-u file检查文件是否设置了SUiD
-r file检查文件是否可读
-w file检查文件是否可写
-x file检查文件是否可执行
-s file检查文件是否为空
-e file检查文件是否存在
  • -S 判断文件是否是socket
  • -L 检查文件是否存在一个符号链接

Shell echo命令​

显示结果定向至文件​

echo ''>file.log # 置空文件
echo '你好'>file.log # 写入文件 (阿里云密码忘记,后台执行echo '本地ssh_pub'>~/.sshd/authorized_keys 进行免密码登录)

显示命令执行结果​

echo `date` # 获取当前时间 date "+%Y-%m-%d %H:%M:%"
echo -e # 开启转义

printf 命令​

printf 命令模仿 C 程序库(library)里的 printf() 程序。

printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n

printf fomat-string [args]

参数说明

  • format-string: 为格式控制字符串
  • args : 参数列表

🏳️

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

printf 的转义序列​

序列说明
\a警告字符
\b后退
\c抑制(不显示)输出结果中任何结尾的换行字符
(只在%b格式指示符控制下的参数字符串中有效),
而且,任何留在参数里的字符、
任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f换页
\n换行
\r回车
\t水平字符表
\v垂直制表符
\\一个字面上的\
\ddd表示1到3位数八进制的字符.仅在格式字符串中有效
\0ddd表示1到3位的八进制字符

Shell test 命令​

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

参数说明
-eq等于
-ne不大于
-gt大于
-ge大于等于
-lt小于
-le小于等于
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi

流程控制​

if else fi​

if condition
then
command1
command2
...
commandN
fi

if else​

if condition
then
command1
command2
...
commandN
else
command
fi

if else-if else​

if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

for 循环​

与其他编程语言类似,Shell支持for循环。

for循环一般格式为:

for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
# 写成一行
for var in item1 item2 ... itemN; do command1; command2… done;

while 语句​

while 循环用于不断执行一系列命令,也用于从输入文件中读取数据。其语法格式为:

while condition
do
command
done

无限循环​

while :
do
command
done


for (( ; ; ))

until 循环​

until 循环执行一系列命令直至条件为 true 时停止。

until 循环与 while 循环在处理方式上刚好相反。

一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。

until 语法格式:

until condition
do
command
done

case ... esac​

case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分支选择结构,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。

可以用 case 语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。

case ... esac 语法格式如下:

case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac

跳出循环​

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell 使用两个命令来实现该功能:break 和 continue。

break 命令​

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​

continue 命令与 break 命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

#!/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 函数​

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。

shell中函数的定义格式如下:

[ function ] funname [()]

{

action;

[return int;]

}
#1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
# 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"

函数返回值在调用该函数后通过 $? 来获得。

函数参数​

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...

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
参数说说明
$#传递到脚本或函数的参数个数
$*以一个单个字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID
$!后台运行的最后一个进程ID
$@与$*相同,但是使用时加引号,并在引号中返回每个参数
$-显示shell使用的当前选项,与set命令相同
$?显示最后命令的退出状态,0表示没有错误,其它表示有错误

Shell 输入/输出重定向​

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

命令说明
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。

/dev/null 文件​

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

如果希望屏蔽 stdout 和 stderr,可以这样写:

command > /dev/null 2>&1

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。

Shell 文件包含​

和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。

. filename # 注意点号(.)和文件名中间有一空格
# 或
source filename