Shell Script入门到入土
前言
什么是Shell ?
shell (计算机壳层)
在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(commandinterpreter,命令解析器)。它类似于DOS下的COMMAND.COM和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。
Shell是介于用户和内核间的交互器,不同系统的Shell结构大体相似。本文主要记录与Kernel内核相关系统的,以Linux、Unix为首的系统Shell Scrip。基础语法不细说,在代码块中学习吧。
中文名:壳
外文名:shell
性质:命令解析器
用途:接收用户命令。
入门
查看支持解释器
➜ ~ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
#!/bin/bash
#shell第一行的 #! 是一种约定标记, 它可以告诉系统这个脚本需要什么样的解释器来执行
查看当前shell解释器并切换
重启终端窗口生效
➜ ~ echo $SHELL
/bin/zsh
➜ ~ chsh -s /bin/sh
Changing shell for zjk.
Password for zjk:
四种基本执行方式
当前用户对此文件要有执行权限
➜ ~ . a.sh
➜ ~ . ./a.sh
➜ ~ source a.sh
➜ ~ source ./a.sh
#调试执行:以bash为例
➜ ~ bash -x hello.sh '可以查看脚本执行过程'
➜ ~ bash -n hello.sh '可以查看脚本语法问题'
传参
命令 | 返回值 |
---|---|
$# | 参数的个数 |
$@ | 参数列表 |
$0 | 命令本身(和C的argv[0] 同理) |
$1 、$2 … | 第一个参数、第二个参数… |
$? | 执行上面命令后的状态码 |
$name | 用户自己在脚本里定义的name变量值 |
shift n | 从参数列表中跳过n个参数,输入参数个数<时会报错 |
getopt -o optstring -- parameters | getopt - 解析命令行选项(加强版) |
set -- a b… | 准备n个参数为a和b…,如此,之后$1 表示点就是a |
eval | 对之后的命令进行二次解析 |
➜ ~ cat a.sh
shift 2;
echo '命令本身:'$0
echo '参数列表:'$@
echo '参数个数:'$#
echo '第1个参数:'$1
echo '第2个参数:'$2
echo '第3个参数:'$3
echo '第4个参数:'$4
echo '命令返回码:'$?
str='我是变量'
echo $str
echo ${date xxxaaa}
echo $0'命令返回码:'$?
➜ ~ ./a.sh 1 2 3 4 5 6
命令本身:./a.sh
参数列表:3 4 5 6
参数个数:4
第1个参数:3
第2个参数:4
第3个参数:5
第4个参数:6
命令返回码:0
我是变量
./a.sh: line 14: ${date xxxaaa}: bad substitution
./a.sh命令返回码:1
日期
一般地,会把带函数的 有返回值的 表达式,使用 `包裹
#输入一个参数,参数名为datehour eg:2021091223
datehour=$1
echo "datehour is "${datehour}
#字符串截取
year=`expr substr ${datehour} 1 4`
month=`expr substr ${datehour} 1 6`
day=`expr substr ${datehour} 1 8`
hour=`expr substr ${datehour} 1 10`
#使用date函数获取日期
cur_date1=`date -d "$day" +%Y%m%d`
cur_date2=`date -d "$day" +%Y-%m-%d`
#使用date函数获取日期和时间
cur_dateTime=`date +%Y-%m-%d,%H:%m:%s`
#获取指定日期$day的前几天 $day:20210912
yesterday2=`date -d "$day -2 days" +%Y%m%d`
beforeyear3=`date -d "$day -3 years" +%Y-%m-%d`
beforeyear1=`date -d "$day -1 years" +%Y-%m-%d`
#获取明天的日期
nextday=`date -d next-day +%Y%m%d`
#获取昨天的日期
lastday=`date -d last-day +%Y%m%d`
#获取上个月的年和月
lastmonth=`date -d last-month +%Y%m`
#获取下个月的年和月
nextmonth=`date -d next-month +%Y%m`
#获取明年的年份
nextyear=`date -d next-year +%Y`
%
后面跟一个字符什么含义?
- %Y 年(例如:1970,1996等)
- %y 年的最后两个数字( 1999则是99
- %m 月(01…12)
- %D 日期(mm/dd/yy)
- %d 一个月的第几天(01…31)
- %H 小时(00…23)
- %I 小时(01…12)
- %M 分(00…59)
- %S 秒(00…59)
source
#func.sh: 计算所有参数的和
function sum(){
local total=0
for n in $@
do
((total+=n))
done
return $total
}
#!/bin/bash
#main.sh: 使用source调func.sh的sum方法
source func.sh
echo $(sum 10 20 55 15)
内置命令的一种,它会读取 filename 文件中的代码,并依次执行所有语句。
你也可以理解为,source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。
循环
1、for
语法:
for 变量名 in 取值列表
do
命令序列(命令行)
done
eg:
#!/bin/bash
#数字循环累加
for value in {1..5}
do
#累加这么写
let "sum+=value"
echo "value is $sum"
done
2、until
语法:
until 条件测试操作
do
命令序列
done
eg:
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
当a大于等于10时,才会跳出循环,所以换行地输出 1~9
3、while
语法:
while condition
do
statements
done
eg:
#!/bin/bash
i=1
sum=0
while ((i <= 100))
do
((sum += i))
((i++))
done
echo "The sum is: $sum"
输出 1~100的累加结果
4、 嵌套循环+break+continue
continue eg:
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
当输入大于5的数字时,循环不会结束,且是跳过"Game is over!"执行
break eg:
#!/bin/bash
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
如上,break 2 表示直接跳出外层循环。
break 用来结束所有循环,循环语句不再有执行的机会;continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环。
debug
1、自带脚本的debug方法,以bash为例
语法:
sh [-nxv] 脚本名字
-n,读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。
-v,一边执行脚本,一边将执行过的脚本命令打印到标准输出。
-x,提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。
你也可以直接在shell头部这么写
#!/bin/bash -x
2、ShellCheck脚本检测工具
ShellCheck是一个Shell脚本分析工具,可以为bash/sh shell脚本提出警告和建议。
3、set ±
在脚本中用set命令[启用/禁用]参数:其中set -x表示启用,set +x表示禁用。
运算符
详见标题内转链接↑
变量
- 命名规则:以字母、数字、下划线命名,不能以数字开头,不能使用关键字
- 表达式:
$变量A
或${变量A}
都表示变量A的值 - 显式给变量赋值:
va=${变量A}
;隐式给变量赋值:for file in $(ls /etc)
,遍历/etc目录所有文件名赋值给变量file - 设置变量为只读:
readonly 变量A
- 省略各种数据类型的变量操作
?
?
?
?
?
?
9999+ 展开全部
入土
九九乘法表
之for循环练习
#!/bin/bash
for i in `seq 9`
do
for j in `seq $i`
do
echo -n "$j*$i=$[i*j] "
done
echo
done
轮询ping主机
之for循环练习
Shell ping语法详见Linux手册-> 11、ping
#!/bin/bash
for i in {1..254}
do
ping -c 1 -i 0.3 110.242.68.$i > /dev/null
if [ $? -eq 0 ] ;then
echo "110.242.68.$i is yes"
else
echo "110.242.68.$i is no"
fi
done
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)