『一步一脚印』Shell编程

『简介』

 Shell指的是一种应用程序,这个应用程序能够直接和系统内核直接沟通,然后让内核来操作系统的硬件。狭义的Shell可能指的是命令列下的软件,好像平时用的bash、zsh等,广义的Shell还包括图形界面的软件,因为图形界面其实都可以操作各种应用程序来呼叫内核来工作。
 本文只会记录一下基本语法和自己的练习记录,用于回忆,希望对您有帮助。

『语法』

基本结构

#!/bin/bash
# Author:
#		Gavinjou大笨象
# Date:
#		2019-05-02
# Description:
#		基本结构
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
echo -e "Hello World! \a \n"
exit 0
  1. 第一行【#!/bin/bash】告诉这个script要使用哪个Shell:
    因为当前使用的是bash,所以必须使用【#!/bin/bash】。当这个脚本被执行时,他就能载入bash的相关环境。这行是必须的,因为有可能其他Shell的语法有区别,所以指定Shell很关键
  2. 程序内容:
    除了第一行是声明Shell外,其他【#】都是注解,所以第二行的注解最好说明该Shell的用途包括:内容与功能,版本资讯,作者联系方式,建档日期,历史记录等
  3. 环境变量声明
    建议还是将运行环境变量设定好,因为可以下达一些【外部指令】的时候,不用写绝对路径。如果只用【内建指令】其实可以不写,查看命令是否为【内建命令】可以使用type指令
  4. 主程部分
    就是那个【echo】那句话
  5. 执行结果返回值
    就是那个【exit】语句,正常执行的话,最好还是返回一个值

变量

基本变量定义

#!/bin/bash
myname="Gavinjou大笨象" #基本变量定义,等号不能有空格
echo -e "${myname}" #输出时推荐都用花括号包裹
exit 0 

输出结果

 Gavinjou大笨象 

只读变量

#!/bin/bash
myname="Gavinjou大笨象"
readonly myname #只读变量
echo -e "${myname}"
exit 0

输出结果

 Gavinjou大笨象 

删除变量

#!/bin/bash
myname="Gavinjou大笨象"
echo -e "${myname}"
unset myname	# 删除变量
echo -e "!-> ${myname}"
exit 0

输出结果

 Gavinjou大笨象
 !->

字符串变量

#!/bin/bash
# 在shell中默认类型是字符串
myname1="Gavinjou大笨象" #双引号字符串
myname2='Gavinjou大笨象' #单引号字符串
# 双引号和单引号区别
echo -e "${myname1}  ${myname2}"
echo -e '${myname1}  ${myname2}'
exit 0

输出结果

Gavinjou大笨象  Gavinjou大笨象
${myname1}  ${myname2}

拼接字符串

#!/bin/bash
myname1="Gavinjou大笨象" 
myname2='hello' 
greeting1="${myname2} ${myname1}\n" #双引号拼接
greeting2='${myname2} ${myname1}\n' #单引号拼接
echo -e ${greeting1} ${greeting2}
exit 0

输出结果

hello Gavinjou大笨象
 ${myname2} ${myname1}

获取字符串长度

#!/bin/bash
myname1="Gavinjou大笨象" 
echo -e ${#myname1} #获取长度
exit 0

输出结果

17

提取子字符串

#!/bin/bash
myname="Gavinjou大笨象" 
echo -e ${myname:1:4} # 提取字符串
exit 0

输出结果

avin

查找子字符串

#!/bin/bash
myname="Gavinjou大笨象" 
echo -e `expr index ${myname} jou` # 查找jou的位置
exit 0

输出结果

6

数组

#!/bin/bash
array1=('G' 'a' 'v' 'i' 'n') # 数组定义第一种形式
# 数组定义第二种形式
array2[0]='G'
array2[1]='a'
array2[2]='v'
array2[3]='i'
array2[4]='n'
array2[10]='test' #可以单独定义分量
# 读取数组
echo -e "读取:${array1[0]} - ${array2[0]}\n"
# 获取所有元素
echo -e "所有元素:${array1[@]}\n"
# 取得数组元素个数
echo -e "array2数组元素个数:${#array2[@]}" # 第一种方式
echo -e "array1数组元素个数:${#array1[*]}" # 第二种方式
# 取得数组单个元素的长度
echo -e "array2的0号元素长度:${#array2[0]}"
exit 0

输出结果

读取:G - G

所有元素:G a v i n

array2数组元素个数:6
array1数组元素个数:5
array2的0号元素长度:1

注释

#!/bin/bash
# 单行注释
:<<EOF  # EOF可以换其他字符,推荐EOF
多行注释
EOF
echo -e "test"
exit 0

输出结果

test

参数传递

参数传递

#!/bin/bash
# 执行脚本命令
# 第一种方式:sh sh01.sh 1 2 3 4
# 第二种方式:./sh01.sh 1 2 3 4
# 参数传递
echo "传递参数实例"
echo "执行的文件名:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第三个参数为:$3"
exit 0

输出结果

传递参数实例
执行的文件名:sh01.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

特殊字符用法
用法

#!/bin/bash
# 执行脚本命令
# 第一种方式:sh sh01.sh 1 2 3 4
# 第二种方式:./sh01.sh 1 2 3 4

# $* 与 $@ 区别
echo -e '$*执行'
k=1
for val in "$*"; 
do
    echo "$val  - 次数:$k" 
	k=$((k + 1))
done

echo -e '$@执行'
k=1
for val in "$@"; 
do
    echo "$val  - 次数:$k" 
	k=$((k + 1))
done

exit 0

输出结果

$*执行
1 2 3  - 次数:1
$@执行
1  - 次数:1
2  - 次数:2
3  - 次数:3

基本运算符

算术运算符
算术

#!/bin/bash

a=10
b=20
val1=`expr $a \* $b` #形式一,乘法要加斜杠,其他运算符不用加斜杠。
val2=$(($a * $b)) #形式二,其他运算符都不用加斜杠
echo -e "a * b = ${val1} \n"
echo -e "a * b = ${val2} \n"

if [ $a != $b ]; 	# 其他比较运算符也是
then
	echo "a != b"
fi

exit 0

输出结果

a * b = 200 

a * b = 200 

a != b

关系运算符

#!/bin/bash
# 关系运算符只支持数字,除非字符串是数字
a=10
b=20

if [ $a -eq $b ] #其他关系运算符也是如此
then
	echo "$a -eq $b :等于"
else
	echo "$a -eq $b :不等于"
fi

exit 0

输出结果

10 -eq 20 :不等于

布尔运算符

#!/bin/bash
a=10
b=20

if [ $a -lt $b -o $a -eq $b ] #其他布尔运算符也是如此
then
	echo "符合要求"
else
	echo "不符合要求"
fi

exit 0

输出结果

符合要求

逻辑运算符

#!/bin/bash
a=10
b=20

if [[ $a -gt $b || $a -eq $b ]] #其他逻辑运算符也是如此
then
	echo "符合要求"
else
	echo "不符合要求"
fi

exit 0

输出结果

不符合要求

字符串运算符

#!/bin/bash
a="a"
b="b"

if [ $a = $b ] #其他字符串运算符也是如此
then
	echo "等于"
else
	echo "不等于"
fi

exit 0

输出结果

不等于

文件测试运算符

#!/bin/bash
# 生成文件 touch test.sh
# 执行脚本 ./sh04.sh
file="./test.sh"

if [ -r $file ] # 其他文件运算符也是如此
then
   echo "文件可读"
else
   echo "文件不可读"
fi

exit 0

输出结果

文件可读

ECHO命令

echo命令

#!/bin/bash
# 显示普通字符串
echo "gavinjou" # 推荐
echo gavinjou # 可以省略,但是不推荐
# 显示转义字符
echo "\"gavinjou\"" # 推荐
echo \"gavinjou\"	# 可以省略,但是不推荐
# 显示变量
name="test"
echo "${name}"
# 显示换行
echo -e "test \n" 	#-e开启转义
echo "test \n" 		#不开启转义
# 显示不换行
echo -e "OK! \c" # -e 开启转义 \c 不换行
echo "It is a test"
# 显示结果定向至文件
echo "It is a test" > myfile
# 原样输出字符串,不进行转义或取变量(用单引号)
echo '$name\"'
# 显示命令执行结果
echo `date`
exit 0

输出结果

gavinjou
gavinjou
"gavinjou"
"gavinjou"
test
test 

test \n
OK! It is a test
$name\"
Thu May 2 03:02:29 UTC 2019

PRINTF命令

和C语言基本一样
printf命令

#!/bin/bash
# 简单输出
printf "Hello World\n" 
# 对齐和格式化输出
printf "%-10s %8s %-4s\n" 姓名 性别 体重kg 
# 双引号
printf "%d %s\n" 1 "abc" 
# 单引号
printf '%d %s\n' 1 "abc"  #和双引号效果一样
# 无引号
printf %s abcdef # 不推荐
# 只指定一个参数,格式会重用,但这些技巧都不推荐
printf %s !abc def
# 如果没有参数 %s用NULL %d用0代替
printf "%s and %d \n" 
exit 0

输出结果

Hello World
姓名       性别 体重kg
1 abc
1 abc
abcdef!abcdef

TEST命令

数值测试

#!/bin/bash
# test可以用于检查某个条件是否成立,
# 它可以进行数值、字符和文件三个方面的测试。
num1=100
num2=100
# 换成字符串形式也可以执行
# num1="100"
# num2="100"
if test $[num1] -eq $[num2];
then
	echo "相等"
else 
	echo "不相等"
fi

# []代表执行基本的算数运算 
#不建议用这种方式来计算,在云上测试是不会计算的
result=$[num1+num2] 
echo ${result}

exit 0

输出结果

相等
200

字符串测试

#!/bin/bash
str1="gav"
str2="vin"
if test $str1 = $str2;
then
	echo '两个字符串相等'
else
	echo '两个字符串不相等'
fi
exit 0

输出结果

两个字符串不相等

文件测试

#!/bin/bash
# 脚本命令执行
# touch ./bash
# ./sh05.sh
# 	Shell还提供了与( -a )、或( -o )、
# 	非( ! )三个逻辑操作符用于将测试条件连接起来
if test -e ./bash -a -e ./nofile;
then 
	echo '文件已经存在'
else
	echo '文件不存在'
fi

exit 0

输出结果

文件不存在

流控制

IF-ELIF-ELSE

#!/bin/bash
a=10
b=20
if [ $a == $b ]
then 
	echo "a 等于 b"
elif [ $a -gt $b ] 
then
	echo "a 大于 b"
else 
	echo "a 小于 b"
fi

# 和test一起用也可以
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
	echo "两个数字相等"
else
	echo "两个数字不相等"
fi

exit 0

输出结果

a 小于 b
两个数字相等

FOR循环

#!/bin/bash

# in列表可以包含替换、字符串和文件名
# 顺序输出列表中的数字
for loop in 1 2 3 4 5
do
	echo "The value is : $loop"
done
# 输出数字的第2种形式
for((i=1;i<=5;i=i+1))
do
	echo "The new value is : $i"
done

# 顺序输出字符串
k=1
for str in 'This is a String'
do
	echo -e "$str$k次 \n"
	k=$(($k + 1))
done

exit 0

输出结果

The value is : 1
The value is : 2
The value is : 3
The value is : 4
The value is : 5
This is a String 第1次 

WHILE语句

#!/bin/bash
inte=1

while [ $[inte] -lt 5 ]
# 另一种形式 while(( $inte <= 5))
do
	echo ${inte}
	let "inte++"
done

exit 0

输出结果

1
2
3
4

UNTIL循环

#!/bin/bash
a=0
until [ ! $a -lt 5 ]
do
   echo $a
   a=`expr $a + 1`
done

输出结果

0
1
2
3
4

CASE

#!/bin/bash

anum=1
case $anum in
	1) echo "选择了1"
	;;
	2) echo "选择了2"
	;;
	*) echo "没了"
	;;
esac

exit 0

输出结果

选择了1

跳出循环

#!/bin/bash

echo -e "用break跳出\n"
for((i=1;$i<5;i++))
do
	
	if [ $i == 2 ]
	then
		break
	else
		echo $i
	fi
done

echo -e "用continue跳出\n"
for((i=1;$i<5;i++))
do	
	if [ $i == 2 ]
	then
		continue
	else
		echo $i
	fi
done

exit 0

输出结果

用break跳出

1
用continue跳出

1
3
4

函数

函数
处理函数参数

#!/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
exit 0

输出结果

第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

输入输出重定向

输入输出重定向

#!/bin/bash

# 标准输出重定向
who > "file1"
# 标准输出重定向追加
echo "who" >> "file1"
# 输入重定向
num=`wc -l < "file1"`
echo $num

# 标准输入文件(stdin):
#	stdin的文件描述符为0,Unix程序默认从stdin读取数据。
# 标准输出文件(stdout):
#	stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
# 标准错误文件(stderr):
#	stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

# 计算行数
num=`wc -l << EOF
	GAVIN
	jou
	大笨象
EOF
`
echo $num

# 屏蔽stdout 和 stderr
echo "hello" > /dev/nul 2>&1

exit 0

输出结果

1
3

文件包含

文件包含

# sh07.sh
#!/bin/bash
echo "HelloWorld\n"

#exit 0 千万别加这条语句,因为包含
# 		有点像C的include复制粘贴效果,否则提早退出
# sh08.sh
#!/bin/bash
. ./sh07.sh # 或者用source ./sh07.sh

echo "HelloWorld2\n"
exit 0

输出结果

HelloWorld\n
HelloWorld2\n

『练习补充』
GITHUB

『参考链接』
鸟哥私房菜
菜鸟教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值