Shell语法大全-极简

在浏览器按Ctrl+F查找所需内容。
***.sh文件都用bash命令运行,sh命令有些不兼容。

一、Shell基础-变量

#!/bin/bash

echo "Hello World!"
#赋值
name="liu"
echo ${name}

for skill in Ada Java Coffe; do
        echo "I am ${skill}"
done

for fileName in $(ls /mydata); do
        echo "${fileName}"
done

# 赋值并修改值
age=12
echo $age
age=24
echo $age

# 只读变量,不能被修改,修改会报错
myCat="Tom"
readonly myCat
myCat="Jorry"

# 删除变量
myPhone="Redmi Note 7 pro"
unset myPhone
echo $myPhone

# 字符串,这里只说双引号
# 字符串长度
str="abcd"
echo ${#str}
# 提取子串
string="myPhone switch Redmi K40"
echo ${string:15:25}
# 查找子字符串,查找i和o的位置,谁先出现就计算谁
string="I am best, I am beautiful"
echo `expr index "${string}" io`

# 数组:支持一维数组,不支持多维数组
# 定义数组,下标范围是没有限制的
array0=(2 3 6 3 6 90)
array1[0]="two"
array1[1]="three"
array1[2]="six"
array1[10]="nine"
# 读取数组
echo ${array0[0]}
echo ${array1[10]}
echo ${array0[@]}
# 获取数组长度
# 数组元素个数
length0=${#array0[@]}
length1=${#array0[*]}
length2=${#array1[1]}
length3=${#array1[@]}
echo "${length0}+${length1}+${length2}+${length3}"

# 多行注释,EOF也可以用其他符号代替,如:!
:<<EOF
echo "sport"
echo "my"
EOF

二、Shell传递参数

#!/bin/bash

# 参数传递:
# 脚本内获取参数的格式为:$n。n 代表一个数字,
# 1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推
echo "文件名:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"

:<<EOF
$# 传递到脚本的参数个数

$* 以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2$n"的形式输出所有参数。

$$ 脚本运行的当前进程ID号

$! 后台运行的最后一个进程的ID号

$@$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。

$- 显示Shell使用的当前选项,与set命令功能相同。

$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
EOF

echo "--------------"
echo "第一个参数:$1"
echo "参数个数:$#"
echo "传递的参数以字符显示:$*"

# $*,$@两者的区别
echo "--------------"
echo "-- \$* 演示:结果是一个参数 ---"
for i in "$*"; do
        echo $i
done

echo "-- \$@ 演示:结果是多个参数--"
for i in "$@"; do
        echo $i
done

三、Shell数组

#!/bin/bash
  
# 数组:只支持一维数组,不支持多维,无需定义大小,下标从0开始,元素之间用空格分隔开
# 定义
array=(A B "C" D)
array[4]=E
array[5]="F"
#读
echo "${array[1]}"
echo "${array[2]}"
echo "${array[4]}"
echo "${array[5]}"

#获取所有元素:*或@
echo "${array[*]}"
echo "${array[@]}"
# 数组长度
echo "${#array[@]}"

四、运算符

#!/bin/bash
val=`expr 2 + 5`
echo "两数之和为:$val"
# 注意:1、表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
#       2、完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

# 算数运算符:+ - * / % = == !=
# 例:
a=10
b=20
val=`expr $a - $b`
echo "${val}"

val=`expr $a \* $b`
echo "${val}"

if [ $a == $b ]
then
        echo "a=b"
fi
if [ $a != $b ]
then
        echo "a!=b"
fi
# 注意:1、乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
#       2、if...then...fi 是条件语句,后续将会讲解。
#       3、在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "\" 。

# 关系运算符:关系运算符只支持数字,不支持字符串,除非字符串的值是数字
# 符号:-eq:= -ne:!= -gt:> -lt:< -ge:>= -le:<=
x=20
y=10

if [ $x -eq $y ]
then
        echo "x=y"
else
        echo "x!=y"
fi

# 布尔运算符
# 符号:!:非 -o:或 -a:与
if [ $x -ne $y -a $x -gt $y ]
then
        echo "x大于y"
else
        echo "x+y!=2x"
fi

# 逻辑运算符
# 符号:&&:逻辑与 ||:逻辑或
if [ $a -gt $b || $a -eq $b ]
then
        echo "a>=b"
else
        echo "a<=b"
fi

# 字符串运算符
# 符号:= != -z:长度是否为0(为0反true) -n:长度是否不为0(不为0true) $:是否为空(不为空反true)
str="abd"
string="qwert"
if [ $str = $string ]
then
        echo "相等"
else
        echo "不等"
fi

if [ -z "$string" ]
then
        echo "字符串长度为0"
else
        echo "字符串长度不为0"
fi

if [ $str ]
then
        echo "字符串不为空"
else
        echo "字符串为空"
fi
:<<EOF
# 注意:
        1、-n $a:$a这里应该加上双引号
        a=""
        if [ -n "$a" ]
        then 
                echo "true"
        else
                echo "false"
        fi
        2、条件判断这里用if [[ ... ]],能够防止脚本中的许多逻辑错误。
比如,&&、||、< 和 > 操作符能够正常存在于 [[ ]] 条件判断结构中,
但是如果出现在 [ ] 结构中的话,会报错。
        3、
        EQ 就是 EQUAL等于
        NE 就是 NOT EQUAL不等于 
        GT 就是 GREATER THAN大于  
        LT 就是 LESS THAN小于 
        GE 就是 GREATER THAN OR EQUAL 大于等于 
        LE 就是 LESS THAN OR EQUAL 小于等于
EOF

# 文件测试运算符
:<<EOF
-b file 检测文件是否是块设备文件,如果是,则返回 true。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。       
-d file 检测文件是否是目录,如果是,则返回 true。       
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file 检测文件是否是有名管道,如果是,则返回 true。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true.
-r file 检测文件是否可读,如果是,则返回 true。
-w file 检测文件是否可写,如果是,则返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true.
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。     
EOF

file="/mydata/shellTest/Shell-数组.sh"
if [ -r $file ]
then
        echo "文件可读"
else
        echo "文件不可读"
fi

五、echo命令

#!/bin/bash
# 显示普通字符
echo "I hava a Tom"
echo I hava a Tom
# 显示转义字符
echo "\"I hava a Jarry\""
echo \"I hava a Jarry\"
# 显示变量
#read:read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
read name
echo "$name is a man"
# 开启转义:-e
echo -e "OK! \n"
echo "I am fine!"
# 显示不换行
echo -e "Are you OK! \c"
echo "OK!"
# 显示结果定向至文件
echo "OK!" > test.txt
# 原样输出字符串
echo '$name\"l'
# 显示命令执行结果
echo `date`

六、printf命令

#!/bin/bash
# printf与C语言里的printf()类似
# 实例
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
:<<EOF
%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,
%c 输出一个字符,%f 输出实数,以小数形式输出。

%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),
任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%-4.2f 指格式化为小数,其中 .2 指保留2位小数。

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

七、test命令

#!/bin/bash
# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
# 个人感觉用起来比if [ ... ]简单
a=10
b=20
if test $a -eq $b;then
        echo "相等"
else
        echo "不等"
fi
# 注意:
#       如果 then 另起一行的话 then 前不需要加 ; 否则需要在 then 前加 ;

八、流程控制

#!/bin/bash
# 流程控制

# if ... else ...
a=10
b=10
if [ $a -eq $b ];then
        echo "a==b"
else
        echo "a!=b"
fi
# 结尾的fi是if倒过来
# if ...
if [ $(ps -ef | grep -c ssh) -eq 3 ];then
        echo "ssh相关有三个在运行"
fi
# if ... else-if ... else
x=10
y=2
if [ $x -eq $y ];then
        echo "x==y"
elif [ $x -gt $y ];then
        echo "x>y"
elif [ $x -lt $y ];then
        echo "x<y"
else
        echo "x和y无关系"
fi
# 注意:if else 语句经常与 test 命令结合使用

# for循环
# 实例
# 输出数字
for loop in 1 2 3 4 5 6;do
        echo "sum$loop : $loop"
done
# 输出字符串
for str in I have a Tom;do
        echo $str
done

# while语句
int=1
while(($int<=5));do
        echo $int
        let "int++"
done
# 实例使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量
# 上面实例的写法需要用bash 去运行,用sh会报错,它不支持这种 C 语言格式的循环写法
# while循环读取键盘信息
echo "按下 <CTRL-D> 退出"
echo -n "输入你最喜欢的网站名: "
while read file
do
        echo "$file 是个好网站"
done
# echo -n:-n是不换行的意思
# 无限循环
:<<EOF
while :
do 
 ...
done
或
while true
do 
 ...
done
或
for ((;;))
EOF

# until循环
:<<EOF
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
我并不理解上面这说的啥,但必须粘上
EOF
# 实例
a=0
until [ ! $a -lt 10 ];do
        echo $a
        a=`expr $a + 1`
done

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

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

case 工作方式如上所示,取值后面必须为单词 in,每一模式必须以右括号结束。
取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。

取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。
如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
EOF
echo -n "请输入1-2:"
read num
case $num in
        1) echo "你选择的是1"
        ;;
        2) echo "你选择的是2"
        ;;
        *) echo "没有选择"
        ;;
esac

site="one"
case "$site" in
        "one") echo "one"
        ;;
        "two") echo "two"
        ;;
esac

# 跳出循环:break和continue
:<<EOF
break命令允许跳出所有循环(终止执行后面的所有循环)。
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
EOF

九、函数

#!/bin/bash
:<<EOF
格式
[ function ] funname [()]
{
    action;
    [return int;]
}
说明
1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
EOF

# 实例
demoFun(){
        echo "有史以来我定义的第一个Shell函数!"
}

echo "来吧,展示"
demoFun
echo "结束"
# 实例:带return
funWithReturn(){
        echo "这个函数会对输入的两个数字进行相加运算..."
        echo "输入第一个数字: "
        read aNum
        echo "输入第二个数字: "
        read anotherNum
        echo "两个数字分别为 $aNum$anotherNum !"
        return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
# 注意:函数返回值在调用该函数后通过 $? 来获得。
#       先定义才能使用,与C一样
# 实例:带参数
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
# 注意:$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
:<<EOF
处理参数的特殊字符
$#      传递到脚本或函数的参数个数
$*      以一个单字符串显示所有向脚本传递的参数
$$      脚本运行的当前进程ID号
$!      后台运行的最后一个进程的ID号
$@$*相同,但是使用时加引号,并在引号中返回每个参数。
$-      显示Shell使用的当前选项,与set命令功能相同。
$?      显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
EOF

十、输入、输出重定向

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

/dev/null文件

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

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

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

$ command > /dev/null 2>&1

**注意:**0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

这里的 2> 之间不可以有空格,2> 是一体的时候才表示错误输出。

例子:清空日志:cat /dev/null > test.log

十一、文件包含

引用其他文件:

​ 语法格式:

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

或

source filename

实例:

test1.sh

#!/bin/bash
url="www.liu.com"

test2.sh

#!/bin/bash
source ./test1.sh
echo "网址:$url"

给予test2.sh可执行权限:chmod 744 test2.sh

运行:bash test2.sh

结果:网址:www.liu.com

**注:**被包含的文件 test1.sh 不需要可执行权限。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值