shell( shell script, 程序化脚本 ), shell脚本是利用shell的功能所写的一个程序。这个程序是使用纯文本文件, 将一些shell语法与命令( 含外部命令 )写在里面, 搭配正则表达式/管道命令与数据流重定向等功能,以达到我们所想要的处理目的
shell.sh 文件必要要具备可读与可执行( rx )的权限
使用 /home/dmtsai/shell.sh 来执行命令
假设工作目录在 /home/dmtsai/, 则使用./shell.sh来执行
将shell.sh放在PATH指定的目录内,例如~/bin/
通过
bash shell.sh
或sh shell.sh
来执行
#!/bin/bash
# Program:
# this program shows "Hello World" in your screen.
# History:
# 2019/08/04 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World! \a \n"
exit 0
History
历史记录#!bin/bash
# Program:
# User input his first name and last name. Program shows his full name.
# History:
# 2019/08/04 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input your first name: " firstname # 提示用户输入姓
read -p "Please input your last name: " lastname # 提示用户输入名
echo -e "\nYour full name is: ${firstname} ${lastname}" # 输出全名
#!bin/bash
# Program:
# Program creates 3 files, which named by user's input and data command
# History
# 2019/08/04 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 让使用者输入文件名称, 并取得fileuser这个变量
echo -e "I will use 'touch' command to create 3 files."
read -p "Please input your filename: " fileuser
filename=${fileuser:-"filename"} # 判断是否设置文件名
date1=$(date --date='2 days ago' +%Y%m%d)
date2=$(date --date='1 days ago' +%Y%m%d)
date3=$(date +%Y%m%d)
file1=${filename}${date1}
file2=${filename}${date2}
file3=${filename}${date3}
# 创建
touch "${file1}"
touch "${file2}"
touch "${file3}"
#!/bin/bash
# Program:
# user input 2 integer numbers; program will cross these tuo number.
# History:
# 2019/08/04 xiaozuo First realease
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Please input two numbers, I will multiplying them! \n"
read -p "first number: " first
read -p "second number: " second
total=$((${first}*${second}))
echo -e "\nThe result of ${first} x ${second} is ==> ${total}"
bc
echo "123.23*89.89" | bc
此脚本可将CPU调到高负载状态
#!/bin/bash
# Program:
# User input a scale number to calculate pi number.
# History:
# 2019/08/04 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "THis program will calculate pi value. \n"
echo -e "You should input a float number to calculate pi value.\n"
read -p "The scale number (10~10000) ?" checking # 计算几个小数点
num=${checking:-"10"} # 开始判断是否有输入值
echo -e "Starting calculate pi value. Be patient."
time echo "scale=${num}; 4*a(1)" | bc -lq # 4*a(1)是bc主动提供的计算pi的函数
利用
bash
或者sh
来执行脚本的时候, 该脚本都会使用一个新的bash环境来执行脚本内的命令,相当于是在子进程的bash内执行,在子进程完成后,在子进程内的各项变量或操作将会结束而不会传到父进程中
source shell.sh
是在父进程运行的,各项操作都会在原本的bash内生效例如
source ~/.bashrc
和source ~/.zshrc
# 检查/dmtsai是否存在
test -e /dmtsai && echo "exist" || echo "not exist"
# not exist
测试参数 | 说明 |
---|---|
-e | 该【文件名】是否存在 |
-f | 该【文件名】是否存在且为文件(file) |
-d | 该【文件名】是否存在且为目录(directory) |
-z [string] | 判定字符串是否为0,若string为空,返回True |
! | 反相状态,当file不具有某参数时, 返回True |
-o | 两条件任意一个成立,返回True |
-a | 两条件同时成立,返回True |
-gt | n1 大于 n2 |
-lt | n1 小于 n2 |
-eq | 两数值相等 |
-ne | 两数值不相等 |
#!/bin/bash
# Program
# user input a filename, program will check the flowing:
# 1.) exist? 2.) file/directory 3.) file permissions
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Please input a filename, I will check the filename's type and permission. \n\n"
read -p "Inpur a filename: " filename
# 判断用户是否有输入
test -z ${filename} && "You MUST input a filename." && exit 0
# 判断文件是否存在
test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0
# 判断文件属性
test -f ${filename} && filetype="regulare file"
test -d ${filename} && filetype="directory"
test -r ${filename} && perm="readable"
test -w ${filename} && perm="${perm} writable"
test -x ${filename} && perm="${perm} executable"
# 输出
echo "The filename: ${filename} is a ${filetype}"
echo "And the permissions for you are: ${perm}"
中括号的两端都需要空格符来分开
[ -z "${HOME}" ] ; echo $?
#!/bin/bash
# Program:
# This program will show the user's choice
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N) : " yn
[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0
[ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0
表达式 | 说明 |
---|---|
$# | 代表后接的参数【个数】 |
$@ | 代表【"$1" “$2” “$3” “$4”】,每个变量独立 |
$* | 代表【 “$1 $2 $3 $4” 】 |
#!/bin/bash
# Program:
# Program shows the script name, parameters...
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "the script name is ==> ${0}"
echo "Total parameter number is ==> $#"
# 判断参数是否小于2
[ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
echo "Your whole parameter is ==> '$@'"
echo "The 1st parameter ==>${1}"
echo "The 2nd parameter ==>${2}"
造成参数变量号码偏移
#!/bin/bash
# Program:
# Program shows the effect of shift function
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift # 一个变量的shift
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift 3 # 三个变量的shift
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
if 【条件判断式】; then
fi # if反过来写 代表结束
#!/bin/bash
# Program:
# This program shows the user's choice with if then
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N) : " yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
echo "OK continue"
exit 0
fi
if [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
echo "Oh, interrupt!"
exit 0
fi
echo "I don't know what your choice is" && exit 0
if [ 条件判断式一]; then
elif [条件判断式二]; then
else
fi
#!/bin/bash
# Program:
# This program shows the user's choice with if else
# History:
# 2019/08/05 xiaozuo First release
# 2019/08/05 xiaozuo Second release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N) : " yn
if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then
echo "OK continue"
elif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then
echo "Oh, interrupt!"
else
echo "I don't know what your choice is"
fi
#!/bin/bash
# Program:
# Check $1 is equal to "hello"
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
if [ "${1}" == "hello" ]; then
echo "Hello, how are you ?"
elif [ "${1}" == "" ]; then
echo "You MUST input parameters, ex> {${0} someword}"
else
echo "The only parameter is 'hello',ex> {${0} hello}"
fi
获取目前主机启动的服务
# 下载net-tools
sudo apt install net-tools
# 查看目前主机启动的服务
netstat -tuln
#!/bin/bash
# Program:
# Using netstat and grep to detect WWW,SSH,FTP,Mail services.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 提示信息
echo "Now, I will detect yout linux server's services!"
echo -e "The www, ftp, ssh, and mail (smtp) will be detect! \n"
# 开始检测
testfile=/dev/shm/netstat_checking.txt
# netstat -tuln > ${testfile}
testing=$(grep ":80 " ${testfile})
if [ "${testing}" != "" ]; then
echo "WWW is running in your system."
fi
testing=$(grep ":22 " ${testfile})
if [ "${testing}" != "" ]; then
echo "SSH is running in your system."
fi
testing=$(grep ":21 " ${testfile})
if [ "${testing}" != "" ]; then
echo "FTP is running in your system."
fi
testing=$(grep ":25 " ${testfile})
if [ "${testing}" != "" ]; then
echo "Mail is running in your system."
fi
case $变量名称 in
"第一个变量内容")
;;
"第二个变量内容")
;;
*)
exit 1
;;
esac
#!/bin/bash
# Program:
# Show "Hello" from $1 by use case...in...esac
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
case ${1} in
"hello")
echo "Hello, how are you ?"
;;
"")
echo "You MUST input parameters, ex> {${0} someword}"
;;
*) # 相当于通配符, 0~无穷多个任意字符之意
echo "Usage ${0} {hello}"
;;
esac
#!/bin/bash
# Program:
# This script only accepts the flowing parameter: one, two or three.
# Hisstory:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "This program will print your selection !"
read -p "Input your choice: " choice
case ${choice} in
"one")
echo "Your choice is ONE"
;;
"two")
echo "Your choice is TWO"
;;
"three")
echo "Your choice is THREE"
;;
*)
echo "Usage ${0} {one|two|three}"
;;
esac
shell脚本的执行方式是由上而下,由左至右,因此在shell脚本当中的function的设置一定要在程序的最前面
function fname(){
code...
}
#!/bin/bash
# Program:
# This script only accepts the flowing parameter: one, two or three.
# Hisstory:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
function showname(){
echo -n "Your choice is " # 可以不换行继续在同一行显示
}
echo "This program will print your selection !"
case ${1} in
"one")
showname; echo ${1} | tr 'a-z' 'A-Z' # 将参数做大小写转换
;;
"two")
showname; echo ${1} | tr 'a-z' 'A-Z'
;;
"three")
showname; echo ${1} | tr 'a-z' 'A-Z'
;;
*)
echo "Usage ${0} {one|two|three}"
;;
esac
阅读目录:/etc/init.d
#!/bin/bash
# Program:
# This script only accepts the flowing parameter: one, two or three.
# Hisstory:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
function showname(){
echo "Your choice is ${1}" # 这里的${1}必须参考下面命令的执行
}
echo "This program will print your selection !"
case ${1} in
"one")
showname 1 # 函数后 接有参数
;;
"two")
showname 2
;;
"three")
showname 3
;;
*)
echo "Usage ${0} {one|two|three}"
;;
esac
while [ condition ] # 当满足condition时就执行循环
do
code
done
until [ condition ] # 当满足condition时终止循环
do
code
done
while...do...done
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
while [ "${yn}" != "yes" -a "${yn}" != "YES" ] # attention
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
until...do...dine
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
until [ "${yn}" == "yes" -o "${yn}" == "YES" ] # attention
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
#!/bin/bash
# Program:
# Use loop to calculate "1-100" result.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
sum=0
i=0
while [ "${i}" != "100" ] # until [ "${i}" == "100" ]
do
i=$(($i+1))
sum=$(($sum+$i))
done
echo "The result of '1-100' is ==> $sum"
已知循环次数
for var in con1 con2 con3 ...
do
code
done
#!/bin/bash
# Program:
# Using for...loop to print 3 animal
# History:
# 2019/08/05 xaiozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/loacl/sbin:~/bin
export PATH
for animal in cat dog bird
do
echo "The animal is ${animal}"
done
#!/bin/bash
# Program:
# Use id, finger command to check system account's information.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
users=$(cut -d ':' -f1 /etc/passwd) # 选取账号名称
for username in ${users}
do
id ${username}
done
seq
进行ping检测#!/bin/bash
# Program:
# Use PING command to check the network's PC state.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
network="127.0.0" # 定义一个域名的前面部分
for sitenu in $(seq 1 100) # seq为sequence(连续)的缩写
do
# 下面的程序在获取PING的返回值是正确的还是错误的
ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
# 开始显示结果是正确的启动(UP)还是错误的没有连通(DOWN)
if [ "${result}" == 0 ]; then
echo "Server ${network}.${sitenu} is UP."
else
echo "Server ${network}.${sitenu} is DOWN."
fi
done
#!/bin/bash
# Program:
# Use input dir name, check the permission of files.
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 先检测是否存在
read -p "Please input a directory: " dir
if [ "${dir}" == "" -o ! -d "${dir}" ]; then
echo "The ${dir} is NOT exist."
exit 1
fi
# 开始测试文件
filelist=$(ls ${dir})
for filename in ${filelist}
do
perm=""
test -r "${dir}/${filename}" && perm="${perm} readable"
test -w "${dir}/${filename}" && perm="${perm} writable"
test -x "${dir}/${filename}" && perm="${perm} executable"
echo "The file ${dir}/${filename}'s permission is ${perm}"
done
for (( 初始值; 限制值; 赋值运算 ))
do
code
done
i=1
i<100
i++
#!#!/bin/bash
# Program:
# Use for to calculate 1-?
# History:
# 2019/08/05 xiaozuo First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input a number, I will count for 1-?" num
sum=0
for (( i=1; i<=${num}; i++ ))
do
sum=$((${sum}+${i}))
done
echo "The result of '1-${num}' is ==> ${sum}"
#!/bin/bash
# Program:
# try to decide what you eat
# History;
# 2019/08/05 xiaozuo First release
# 2019/08/05 xiaozuo Second release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
eat[1]="手抓饼"
eat[2]="快乐套餐"
eat[3]="方便面"
eat[4]="面条"
eat[5]="火锅"
eat[6]="串串"
eat[7]="奶茶"
eat[8]="瓜子"
eat[9]="不吃"
eatnum=9
# 只输出一个值
# check=$(( ${RANDOM} * ${eatnum}/32767+1 ))
# echo "you may eat ${eat[${check}]}"
eated=0
while [ "${eated}" -lt 3 ]; do
check=$(( ${RANDOM} * ${eatnum} / 32767 + 1 ))
mycheck=0
if [ "${eated}" -ge 1 ]; then
for i in $(seq 1 ${eated})
do
if [ ${eatedcon[$i]} == $check ]; then
mycheck=1
fi
done
fi
if [ ${mycheck} == 0 ]; then
echo "you may eat ${eat[${check}]}"
eated=$((${eated} + 1))
eatedcon[${eated}]=${check}
fi
done
sh [-nvx] shell.sh
-n : 不要执行脚本,仅检查语法问题
-v : 执行脚本前,先将脚本文件内容输出到屏幕上
-x : 将使用到的脚本内容显示到屏幕上(重要)
bash -x random.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/xz/bin
+ export PATH
+ eat[1]=手抓饼
+ eat[2]=快乐套餐
+ eat[3]=方便面
+ eat[4]=面条
+ eat[5]=火锅
+ eat[6]=串串
+ eat[7]=奶茶
+ eat[8]=瓜子
+ eat[9]=不吃
+ eatnum=9
+ eated=0
+ '[' 0 -lt 3 ']'
+ check=3
+ mycheck=0
+ '[' 0 -ge 1 ']'
+ '[' 0 == 0 ']'
+ echo 'you may eat 方便面'
you may eat 方便面
+ eated=1
+ eatedcon[${eated}]=3
+ '[' 1 -lt 3 ']'
+ check=1
+ mycheck=0
+ '[' 1 -ge 1 ']'
++ seq 1 1
+ for i in $(seq 1 ${eated})
+ '[' 3 == 1 ']'
+ '[' 0 == 0 ']'
+ echo 'you may eat 手抓饼'
you may eat 手抓饼
+ eated=2
+ eatedcon[${eated}]=1
+ '[' 2 -lt 3 ']'
+ check=5
+ mycheck=0
+ '[' 2 -ge 1 ']'
++ seq 1 2
+ for i in $(seq 1 ${eated})
+ '[' 3 == 5 ']'
+ for i in $(seq 1 ${eated})
+ '[' 1 == 5 ']'
+ '[' 0 == 0 ']'
+ echo 'you may eat 火锅'
you may eat 火锅
+ eated=3
+ eatedcon[${eated}]=5
+ '[' 3 -lt 3 ']'