Linux学习之路(三)Shell脚本初探
本文参考链接:http://www.runoob.com/linux/linux-shell.html
基本说明
Shell脚本(shell script)是一种为shell编写的脚本程序。其中shell常见的种类包括:
- Bourne Shell:对应的命令(/usr/bin/sh或/bin/sh)
- Bourne Again Shell:对应的命令(/bin/bash)
- C Shell:对应的命令(/usr/bin/csh)
- K Shell:对应的命令(/usr/bin/ksh)
- Shell for Root:对应的命令(/sbin/sh)
- ......
Shell脚本文件命名没有特殊要求,跟Linux的要求一样就行,至于文件一般以.sh作为后缀以区分其他文件类型。不加后缀或使用其他后缀也行,只要里面的文本内容符合Shell脚本格式要求就行。
Shell脚本格式要求:第一行开头必须以#!开头,这告诉系统其后的路径(即上面说的不同类型的脚本环境(解析器)的路径)所指定的程序即是解释此脚本文件的 Shell 程序。
一个简单的Shell脚本如下:
#!/bin/bash //告诉系统这行以下的命令都使用/bin/bash环境执行
echo "Hello World !" //输出字符串
运行Shell脚本的方法:
1、脚本文件名作为解析器的参数
root@454009d432a4:/workdir# bash test.sh //使用bash命令执行test.sh脚本
hello world! //脚本输出结果
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
2、作为可执行程序
将文件添加x可执行权限,直接运行文件。
这种脚本执行方式有一点必须注意,就是Linux只能执行格式为unix格式的脚本,如果脚本是在windows下编辑传到Linux系统下执行的话文件的格式为doc格式。
要解决这种问题只要将文本格式转换为unix即可。具体方法为使用vi编辑器打开文件,在命令模式中使用命令:set ff=unix修改后保存退出或者直接使用dos2unix 命令执行 dos2unix test.sh 即可:
#!/bin/bash
echo "hello world!"
~
~
:set ff=unix
具体实行命令如下:
root@454009d432a4:/workdir# cd /workdir //进入文件所在目录
root@454009d432a4:/workdir# chmod +x ./test.sh
root@454009d432a4:/workdir# ./test.sh
bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory
注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
变量使用
定义变量时,变量名不加美元符号($,PHP语言中变量需要)
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线"_"
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
#!/bin/bash
echo '----------------------------------------------------'
# 变量使用
name="walter"
echo "hello ${name}!"
# 标识变量为只读
# readonly name
# 标识为readonly的变量不能修改包括unset
# 删除变量
unset name
name=""
echo "hello ${name}"
echo '----------------------------------------------------' # 字符串使用
# Shell字符串单双引号
# 单引号内的字符都是原样输出,不能变量注入。
# 单引号内可以出现任意双引号,原样输出。
# 而且单引号内不能存在单独的单引号,如果是一对单引号则会作为字符串拼接的功能出现
# 单引号内不支持单引号转义输出
str='I am ${name} "long time no see" '
echo $str
# 双引号内的字符可以使用${}进行变量注入。
# 双引号内可以出现任意单引号,原样输出。
# 而且双引号内不能存在单独的双引号,如果是一对双引号则会作为字符串拼接的功能出现
# 双引号内支持双引号的转义输出
str="I'm ${name} \"long time no see\" "
echo $str
# 获取字符串长度
echo ${#str}
# 截取字符串从索引1开始截取一直截取6个字符
echo ${str::}
# 反引号的使用:将反引号(` `)内的字符串当作shell命令来执行,返回值是命令的执行的结果,起到的是一个命令的替换作用
echo `expr index "$str" l6`
echo '----------------------------------------------------' # 数组使用
# bash只支持以为数组,不限定数组大小
# 数组索引由0开始
# 数组定义用括号表示,数组中元素用空格分割
name_list=(walter check ford lucy)
# 也可以这样
name_list=(
walter
check
ford
lucy
)
name_list[]=walter
name_list[]=check
name_list[]=ford
name_list[]=lucy
echo ${name_list[]}
echo ${name_list[]}
echo ${name_list[]}
echo ${name_list[]}
# 默认返回第一个数组值
echo $name_list
# []会作为一个独立的字符串输出,跟前面的$name_list没关系
echo $name_list[]
# 使用@或*符号可以获取数组中的所有元素
echo ${name_list[*]}
echo ${name_list[@]}
# 取得数组元素的个数
echo ${#name_list[@]}
# 或者
echo ${#name_list[*]}
# 取得数组单个元素的长度
echo ${#name_list[]}
调用脚本的时候还可以向脚本里面传递参数,脚本内获取参数的格式为:$n。n代表一个数字1为第一个参数,以此类推
root@454009d432a4:/workdir# ./test.sh param1 param2 //调用脚本传入两个参
#!/bin/bash
echo $1 //第一个参
echo $2 //第二个参
另外还有几个特殊字符用了处理参数供以后参考:
- $# 传递到脚本的个数
- $* 以一个单字符串显示所有向脚本传递的参数。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数
- $$ 脚本运行的当前进程ID号
- $! 后台运行的最后一个进程的ID号
- $@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
- $- 显示Shell使用的当前选项,与set命令功能相同
- $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误
运算
原生的bash不支持直接数学运算,需要借助上面说的反引号(` `)通过bash命令expr等进行运算
#!/bin/bash
a=
b=20 #注意expr命令后面的运算表达式中各元素间必须用空格分割开,作为条件表达式时同理
#乘法运算中*号必须通过\号进行转义
#在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "\"
result=`expr $a + $b`
result=`expr $a - $b`
result=`expr $a \* $b`
result=`expr $a / $b`
result=`expr $a % $b`
#expr后面可以接条件表达式但是返回结果的时候与php类似是以1、0表示true、false。
echo `expr $a == $b`
条件表达式
条件表达式中关系运算符只支持数字或数字类型的字符串。
关系运算符如下:
- -eq 是否相等
- -ne 是否不相等
- -gt 左边大于右边
- -lt 左边小于右边
- -ge 左边大于等于右边
- -le 左边小于等于右边
布尔运算符:
- ! 非运算
- -o 或运算
- -a 与运算
逻辑运算符:
- && 逻辑的AND
- || 逻辑的OR
字符串运算符:
- = 两个字符串是否相等
- != 两个字符串是否不相等
- -z 字符串长度是否为0 为0返回true
- -n 字符串长度是否为0 不为0返回true
- str 字符串是否为空 不为空返回true
文件测试运算符,用于检测unix文件各种属性:
- -b 检测文件是否是块设备文件 是则返回true
- -c 检测文件是否字符设备文件 是则返回true
- -d 检测文件是否目录 是则返回true
- -f 检测文件是否普通文件(既不是目录也不是设备文件) 是则返回true
- -g 检测文件是否设置了SGID位 是则返回true
- -k 检测文件是否设置了粘着位(Sticky Bit) 是则返回true
- -p 检测文件是否有管道 是则返回true
- -u 检测文件是否设置了SUID位 是则返回true
- -r 检测文件是否刻度 是则返回true
- -w 检测文件是否可写 是则返回true
- -x 检测文件是否可执行 是则返回true
- -s 检测文件是否为空(文件大小是否大于0) 不为空则返回true
- -e 检测文件(包括目录是否存在) 是则返回true
#!/bin/bash
a=
b=
a=$b
echo `expr $a == $b`
#以下两种条件判断语句的格式都可以,不知道其他版本是不是也这样支持
#注意在条件判断语句中表达式必须放于[]中括号中,并且表达式前后与中括号之间要有空格分割
##############if 与 then 在不同行中##################
if [ $a != $b ]
then
#statements
echo 'no'
fi
###############if 与 then在同一行中以逗号分割#################
if [ $a == $b ]; then
#statements
echo 'yes'
fi
if [ $a = $b ]; then
#statements
echo 'yes'
fi
################################
if [ $a -eq $b ]; then
#statements
echo 'equal'
else
echo 'no equal'
fi
################################
if [ $a -ne $b ]
then
echo 'no equal'
else
echo 'equal'
fi
################################
file='/workdir/check.log' if [ -e $file ]; then
#statements
echo 'file exist'
else
echo 'file not exist'
fi
Linux学习之路(三)Shell脚本初探的更多相关文章
- Linux学习Day6:编写Shell脚本
Shell脚本命令的工作方式有两种: 交互式(Interactive):用户每输入一条命令就立即执行. 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多 ...
- Linux学习之路:shell变量(二)环境变量
1.env (environment 的缩写)和export显示所有环境变量 2. 环境变量说明 环境变量 意义 HOME 用户主文件夹相当于“~” SHELL Linux默认为/bin/bash H ...
- Linux学习之路:shell变量(一)
一.变量的显示与设置 1.变量的显示运用echo命令 +$符号: 上图例子显示的是系统变量,咱们可以自己设置变量 2.设置变量运用“=”符号 设置了变量NIU 值为“niunai” 变量设置规则: ( ...
- Linux学习笔记:使用shell脚本实现ftp的自动上传下载
在 Linux 下可以利用 Shell 实现 ftp 文件的自动上传和下载,封装至 crontab 更可实现定时调度. 1.ftp自动登录批量下载文件 ##### 从ftp服务器上的/home/dat ...
- Linux学习之路三:重要概念之Linux系统层次结构
上图来自Unix编程圣经<APUE>英文第二版.如图,处于最中心的是系统内核,负责机器硬件资源管理,进程管理等:shell,函数库(值得记住的是C标准函数库)和某些应用程序均直接构建于内核 ...
- Linux学习之路-Linux-at及cron命令【7】---20171215
Linux学习之路-Linux-at及cron命令[7]---20171215 DannyExia000人评论986人阅读2017-12-24 17:28:03 ntpdate 命令 [root@ ...
- linux c程序中获取shell脚本输出的实现方法
linux c程序中获取shell脚本输出的实现方法 1. 前言Unix界有一句名言:“一行shell脚本胜过万行C程序”,虽然这句话有些夸张,但不可否认的是,借助脚本确实能够极大的简化一些编程工作. ...
- 学习之路三十九:新手学习 - Windows API
来到了新公司,一开始就要做个程序去获取另外一个程序里的数据,哇,挑战性很大. 经过两周的学习,终于搞定,主要还是对Windows API有了更多的了解. 文中所有的消息常量,API,结构体都整理出来了 ...
- Linux自动安装JDK的shell脚本
Linux自动安装JDK的shell脚本 A:本脚本运行的机器,Linux B:待安装JDK的机器, Linux 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装jdk的机器B上,然后就可以在 ...
随机推荐
- 阿里云或本地部署服务器(一)---nginx本地和服务器代理
具体步骤: 1.nginx下载 2.在G:\nginx-1.15.8\conf/nginx.conf改三处路径:nginx.conf 文件中配置的路径和端口要映射到vue项目工程 a.改 映射端口: ...
- 排错:Windows系统异常导致Filebeat无法正常运行
Windows 下Filebeat排错Case实例一份,请查收. 问题描述: Windows Server下Filebeat Agent服务无法正常启动,导致网络数据打点无法正常进行,影响大范围用户网 ...
- Error:"Java patch PatchPasswordEncryption_J10001 is being applied by some other process" when starting Ranger Admin
SupportKB Problem Description: When starting Ranger admin, it fails to start up with the following e ...
- Nginx反向代理解决iframe跨域问题
前言 这几天有个需求:做个表单页面,要求后台人员能自定义发布表单,用户来填写表单.我一想,这不麦克表单有现成的吗,拿来就用!发布表单后,可以选择使用iframe方式嵌入网站,一切顺利. 当时的网站是h ...
- F#正则表达式
此词法分析器允许您使用F#计算表达式以非常声明的方式定义基于正则表达式的规则. F# 打开 Lexer 让 定义= lexerDefinitions { 做!addNextlineDefinition ...
- Docker 搜索镜像
文章首发个人网站: https://www.exception.site/docker/docker-search-image 本文中,您将学习 Docker 如何搜索镜像? 一.search 命令 ...
- python接口自动化(十)--post请求四种传送正文方式(详解)
简介 post请求我在python接口自动化(八)--发送post请求的接口(详解)已经讲过一部分了,主要是发送一些较长的数据,还有就是数据比较安全等.我们要知道post请求四种传送正文方式首先需要先 ...
- ES 07 - Elasticsearch查询文档的六种方法
目录 1 Query String Search(查询串检索) 2 Query DSL(ES特定语法检索) 3 Query Filter(过滤检索) 4 Full Text Search(全文检索) ...
- 泥瓦匠想做一个与众不同的技术"匠"
点击蓝字,关注泥瓦匠 本文阅读大约 3 分钟.感谢阅读 喝了最后一口百事可乐,想到它的 slogan:新一代的选择.新一代的选择,每个人选择不同,人生道路历程也不同.就像我刚毕业的时候,毕业选择不一样 ...
- Spring Boot Web 开发注解篇
本文提纲 1. spring-boot-starter-web 依赖概述 1.1 spring-boot-starter-web 职责 1.2 spring-boot-starter-web 依赖关系 ...