心想随性

  • 首页
  • 关于我
  • 友链
Gality
小菜鸡的垃圾桶
  1. 首页
  2. 运维
  3. 正文

Shell脚本编写入门

2020年10月20日 164点热度 0人点赞 0条评论

最近在服务器和自己的电脑上都有用docker快速部署环境的需求,特别是当涉及到数据卷映射时,命令比较长,所以考虑到写sh脚本来自动完成,正好之前一直想学bash脚本的编写,趁机总结一下

目录

  • Shebang 行
  • 注释
  • 脚本参数
  • 变量
    • 定义变量
    • 使用变量
  • 引号
    • 单引号
    • 双引号
    • 字符操作
  • 读入
  • 条件判断
    • case
  • While循环
  • for循环
  • exit命令
  • 推荐

Shebang 行

脚本的第一行通常是指定解释器,即这个脚本必须通过什么解释器执行。这一行以#!字符开头,这个字符称为 Shebang,所以这一行就叫做 Shebang 行。

sh脚本的解释器一般都是bash,所以首行一般写为

#!/bin/bash
或
#!/usr/bin/env bash

如果 Bash 解释器不放在目录/bin,脚本就无法执行了。为了保险,可以写成下面用env的命令的(这个命令总是在/usr/bin目录),返回 Bash 可执行文件的位置

Shebang 行不是必需的,但是建议加上这行。如果缺少该行,就需要手动将脚本传给解释器

# 带Shebang 行时执行方式:
./script.sh
# 不带Shebang行时执行方式:
bash ./script.sh

由于在执行sh脚本时需要指定脚本的路径,如果有比较多的sh脚本的话,建议执行如下操作:

  1. 先在主目录新建一个~/bin子目录,专门存放可执行脚本,然后把~/bin加入$PATH
export PATH=$PATH:~/bin
# 上面命令改变环境变量$PATH,将~/bin添加到$PATH的末尾。可以将这一行加到~/.bashrc文件里面,然后重新加载一次.bashrc,这个配置就可以生效了。

2. 执行

source ~/.bashrc

以后不管在什么目录,直接输入脚本文件名,脚本就会执行,例如: script.sh

注释

Bash 脚本中,#表示注释,可以放在行首,也可以放在行尾。

# 本行是注释
echo 'Hello World!'

echo 'Hello World!' # 井号后面的部分也是注释

脚本参数

调用脚本的时候,脚本文件名后面可以带有参数,例如:

$ script.sh word1 word2 word3

脚本文件内部,可以使用特殊变量,引用这些参数。

  • $0:脚本文件名,即script.sh。
  • $1~$9:对应脚本的第一个参数到第九个参数。
  • $#:参数的总数。
  • $@:全部的参数,参数之间使用空格分隔。
  • $*:全部的参数,参数之间使用变量$IFS值的第一个字符分隔,默认为空格,但是可以自定义。

如果脚本的参数多于9个,那么第10个参数可以用${10}的形式引用,以此类推。

调用时如果多个参数放在双引号里面,视为一个参数

变量

定义变量

定义变量时,变量名不加美元符号($),如:

your_name="qinjx"

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。

除了显式地直接赋值,还可以用语句给变量赋值,如:

for file in `ls /etc`

使用变量

使用一个定义过的变量,只要在变量名前面加美元符号即可,如:

your_name="qinjx"
echo $your_name
echo ${your_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:

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

如果不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。

推荐给所有变量加上花括号,这是个好的编程习惯

引号

单引号

str='this is a string'

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单引号(对单引号使用转义符后也不行)

双引号

your_name='qinjx'
str="Hello, I know your are \"$your_name\"! \n"
  • 双引号里可以有变量
  • 双引号里可以出现转义字符

字符操作

拼接字符串:

your_name="qinjx"
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"

echo $greeting $greeting_1

获取字符串长度:

string="abcd"
echo ${#string} #输出:4

提取子字符串:

string="alibaba is a great company"
echo ${string:1:4} #输出:liba

读入

通过read将用户输入读入变量中

#!/bin/sh

# Author : Zara Ali
# Copyright (c) Tutorialspoint.com
# Script follows here:

echo "What is your name?"
read PERSON
echo "Hello, $PERSON"

输出:

$./test.sh
What is your name?
Zara Ali
Hello, Zara Ali
$

条件判断

if condition1
then
	command1
elif condition2
	command2
else
	commandN
fi

if可以直接判断命令的执行结果(每个命令执行完成后也会有一个返回值,如果命令执行成功则返回0,如果执行失败则返回1), 所以也可以用如下方式写脚本

if cd $some_directory; then
  rm *
else
  echo "Could not change directory! Aborting." 1>&2
  exit 1
fi

当然,更简介的方式是使用逻辑运算符&&和||

# 第一步执行成功,才会执行第二步
cd $some_directory && rm *

# 第一步执行失败,才会执行第二步
cd $some_directory || exit 1

case

case "${opt}" in
	"Install-Puppet-Server" )
		install_master $1
		exit
	;;

	"Install-Puppet-Client" )
		install_client $1
		exit
	;;

	"Config-Puppet-Server" )
		config_puppet_master
		exit
	;;

	"Config-Puppet-Client" )
		config_puppet_client
		exit
	;;

	"Exit" )
		exit
	;;

	* ) echo "Bad option, please choose again"
esac

case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break

While循环

while condition
do
	command
done

for循环

for i in ...; 
do
    ......
done
或
for ((i=0; i<10; i++)); 
do
	......
done

exit命令

exit用于终止当前脚本的执行,并向shell返回一个推出值

如果直接使用exit,会将最后一条命令的退出状态作为整个脚本的退出状态

exit后可以加参数,该参数就是退出状态:

# 退出值为0(成功)
$ exit 0

# 退出值为1(失败)
$ exit 1

退出时,脚本会返回一个退出值。脚本的退出值,0表示正常,1表示发生错误,2表示用法不对,126表示不是可执行脚本,127表示命令没有发现。如果脚本被信号N终止,则退出值为128 + N。简单来说,只要退出值非0,就认为执行出错。

推荐

  • Advanced Bash-Scripting Guide,非常详细,非常易读,大量example,既可以当入门教材,也可以当做工具书查阅
  • 脚本编程30分钟入门

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: sh脚本 入门
最后更新:2020年10月20日

Gality

不困于心,不惑于行

点赞
< 上一篇
下一篇 >

文章评论

取消回复

Gality

不困于心,不惑于行

分类目录
  • CTF
  • C语言
  • PHP
  • Python
  • 二进制
  • 取证
  • 安装/踩坑
  • 开发
  • 读书
  • 运维
最新 热点 随机
最新 热点 随机
MemoryModule项目分析(一) 从内存中加载Dll “人类是大尺度的地衣”——读《看不见的森林》有感 花式找回WordPress密码 Python写二进制文件 Python多线程
MemoryModule项目分析(一)
花式找回WordPress密码 Shell脚本编写入门 MemoryModule项目分析(一) “人类是大尺度的地衣”——读《看不见的森林》有感 CTF中PHP代码审计出题点总结 深入理解Nginx配置文件

COPYRIGHT © 2020 心想随性. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS