1、简介
2、read
3、运算工具
4、if/then结构
5、while循环
6、for循环
 
一、简介
1、什么是shell
shell是用户与系统交互作用的界面。shell是一种命令解释程序,同时也是一种高级程序设计语言
2、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)
其中:Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统默认的Shell;
3、shell局限性
1.1、需要耗费大量资源的任务,特别是对执行速度要求较高的场合
1.2、涉及大量的数学计算
1.3.、关键性应用(数据库,网站等)
1.4.、设计图形或者GUI的应用
1.5.、需要直接访问硬件
1.6.、开发闭源的应用(相对于开源)
4、基础
文件系统:Linux 的文件系统是一个包含了目录和文件的分层的组织结构,位于最顶端的叫做根目录(root directory),用斜杠/ 来表示
目录: 是一种包含目录项的文件,每个目录项中都包含了文件名
文件名: 目录的内容称为目录项,目录项包含了文件名,只有两种字符不允许出现在文件名中:斜杠,空字符(ASCII 值为0),斜杠用于分隔路径中的文件名,空字符用来表示路径的结尾。文件名的长度通常可以达到255个字符
路径: 一系列文件名连起来,用斜杠分隔,就叫做路径,路径用于表示文件的位置;以斜杠开头的路径叫做绝对路径,否则为相对路径,相对路径相对于当前工作目录
返回码:所有命令都有一个返回值,用0-255之间的整数来表示;脚本就是一个命令,它也有返回值,另外,脚本里面的函数也有返回值
退出脚本的正规方法是明确地用命令exit [code]来退出,如:exit 0;exit $?
 
二、read
1、定义
read是一个buildin命令,主要完成对参数的赋值,类似C语言中的scanf;
其不仅可以赋值变量,还可以赋值数组;
其输入不仅是屏幕,还可以是文件描述符
2、实操
# read a --输入字符串,将字符串赋值给变量 a;# echo $a
hello world!!
# read name sex age --同时分别给三个变量赋值,输入分隔符默认为 空格符
zhangsan male 50
# unset name sex age --删除变量
# IFS=';' --将 read 的输入分隔符改为 ';'
# vim test.sh
#!/bin/bash
prompt="Please enter your name:"
read -p "$prompt" name
echo "Greetings $name"
 
三、运算工具
1、简单数学运算
# echo $((1+2**2-3*4/5%6)) --输出计算结果到屏幕
# a=$((1+2**2-3*4/5%6)) --把计算结果赋给变量a
# ((a=1+2**2-3*4/5%6)) --同上
# echo "scale=3;10/3" | bc --bc计算器;保留小数点后三位
# echo "2^10" | bc --bc计算器;计算2的10次方
# awk 'BEGIN{print 1/3}' --awk计算
2、获取随机数
# od -N4 -tu4 /dev/urandom | sed -n '1s/.* //p' --获取一个7位数的号码
# od -Ad -w24 -tu4 /dev/urandom --获取随机数
# od -tu8 /dev/urandom --获取随机数
# od -tu8 /dev/urandom | sed -r 's/^[0-9]+\s+//' | sed -r 's/\s+/\n/g' |cut -b1-8 |sed -r -n '/^.{8}$/p' | sed 's/^/186/' |head -n5000 |vi - --获取一万个电话号码
# od -N40000 -tu4 /dev/urandom | sed -r 's/^[0-9]+(\s+)?//' | sed -r 's/\s+/\n/g' | grep -vE '^\s*$' > 10k_random --生成一万个随机数
# sed -r -n '/^.{8}$/p' 10k_random | head -n 100000 | sed 's/^/186/' > phone_num
3、获取数字序列
# seq 10 --获取1到10
# seq 1 2 10 --获取1到10,步长为2
# seq 10 100 --获取10到100
# seq 10 -1 1 --倒序,10到1
 
四、if/then实例
1、判断字符 "a" 是否等于 "A"
# vim test.sh
#!/bin/bash
if [[ "a" = "A" ]]; then
if [ "a" = "A" ]; then
  echo "a equals A"
else
  echo "a no equals A"
fi
2、判断/root/test/test.sh是否存在并具有可执行权限
# vim test.sh
#!/bin/bash
if test -x /root/test/test.sh;then
  echo "/root/test/test.sh is executable"
fi
3、判断系统是否存在 root 用户
# vim test.sh
#!/bin/bash
if grep -E --color=auto ^root: /etc/passwd; then
  echo "user root exists"
fi
4、判断文件类型
# vim test.sh
#!/bin/bash
function isSymbolicLink() {
  file=$1
  flag=$(ls -ld $file | cut -b1)
  test "$flag" = "1"
  return $?
}
file=$1
if isSymbolicLink $file; then
  echo "Symbolic Link"
elif test -d $file; then
  echo "Directory file"
elif test -f $file; then
  echo "Regular file"
elif test -b $file; then
  echo "Block special"
elif test -c $file; then
  echo "Character special"
elif test -p $file; then
  echo "Named pipe"
elif test -S $file; then
  echo "Socket"
else
  echo "Unkown"
fi
5、判断输入数字的大小
# vim test.sh
#!/bin/bash
num=$1
if test "$num" -lt 10 ;then
  echo "小数字"
elif test "$num" -lt 20;then
  echo "中数字"
elif test "$num" -lt 30;then
  echo "大数字"
else
  echo "超大数字"
fi
6、从标准输入获取一个数字,并根据其大小输出指定字符串
# vim test.sh
#!/bin/bash
echo -n "Enter a number: "
read num
if [ "$num" -lt 100 ]; then
echo "小于100"
elif [ "$num" -ge 100 -a "$num" -lt 200 ]; then
echo "大于等于100小于200"
elif [ "$num" -ge 200 -a "$num" -lt 300 ]; then
echo "大于等于200小于300"
else
echo "其它数字"
fi
 
五、wihle循环
1、认识
测试 while 关键字后面一条命令的返回码,条件为真时,程序读入while循环体中的指令;0为真。循环体如下:
while [] --while 后面运行 [ ] 命令,测试 [ ] 命令的返回码
cat /filename | while read line       --while 后面运行read 命令,测试 read 命令的返回码
do
......
done
2、循环控制语句
continue --终止当前循环,开始下一个循环
break --终止当前循环,并退出循环体
exit --终止当前脚本
3、实例
# vim test.sh --区分 continue 与 break 的区别
#!/bin/bash
while true
do
sleep 1
echo test
continue/break
echo
done
# vim test.sh --区分 break 与 exit 的区别
#!/bin/bash
while test -e /data/test/test.sh
do
echo "exists"
sleep 1
break/exit
done
echo "loop end"
# vim test.sh --寻找我们给定的路径,直到寻到为止
#!/bin/bash
if test $# -ne 1;then
echo "wrong paraneter" >&2
exit
fi
path=$1
while test ! -e "$path"
do
sleep 1
echo "don't found!!!"
done
echo "found"
# vim test.sh --脚本运行指定的时间,时间一到就退出;单位为 s
#!/bin/bash
if test $# -ne 1;then
echo "Usage: $(basename $0) TIME" >&2
exit 1
fi
timeLength=$1
beginTime=$(date +%s)
endTime=$(( $beginTime + $timeLength ))
---------------------------------------------------------
while test $(date +%s) -lt "$endTime"
do
echo "processing....."
sleep 1
done
---------------------------------------------------------
while true
do
if test $(date +%s) -ge "$endTime";then
break
fi
echo "processing......"
sleep 1
done
---------------------------------------------------------
echo "time out"
# vim test.sh --循环读取文件的每一行,并计算每行的字符个数
#!/bin/bash
file=$1
---------------------------------------------------------
totalLines=$(wc -l < $file)
line=1
while test $line -le $totalLines
do
lineData=$(sed -n "${line}p" $file)
len=$(echo -n $lineData | wc -c)
echo "line ${line}: $len"
line=$(( $line + 1 ))
done
---------------------------------------------------------
line=1
while read lineData
do
len=$(echo $lineData | wc -c)
echo "line ${line}: $len"
line=$(( $line + 1 ))
done < $file
---------------------------------------------------------
# vim test.sh -- 打印出10行hello world;<(seq 10)相当于一个文件路径;称之为进程置换
#!/bin/bash
while read num
do
echo "hello world"
done < <(seq 10)
---------------------------------------------------------
n=1
while [ $n -le 10 ]
do
echo "hello world"
n=$((n+1))
done
---------------------------------------------------------
# vim test.sh --创建一个不尽的循环,要求循环运行1分钟后自动终止
#!/bin/bash
start_time=$(date +%s)
while true
do
cur_time=$(date +%s)
test $((cur_time - start_time)) -ge 10 && break
time=$((cur_time - start_time))
echo "time is $time......"
sleep 1
done
# vim test.sh --先用while 循环创建100个.txt文件;再将所有文件后缀名改为 .html
#!/bin/bash
count=100
---------------------------------------------------------
seq $count | while read i
do
touch ${i}.txt
done
ls -1 *.txt | while read oldname
do
newname=$(echo $oldname | sed 's/.txt$/.html/')
mv $oldname $newname
done
---------------------------------------------------------
while read i
do
touch ${i}.txt
done < <( seq $count )
while read oldname
do
newname=$(echo $oldname | sed 's/.txt$/.html/')
mv $oldname $newname
done < <(ls -1 *.txt )
# vim test.sh --计算出1000 之内的偶数的和;不能使用管道,因为管道会生成子进程
#!/bin/bash
sum=0
while read num
do
sum=$(( $sum + $num ))
done < <(seq 2 2 998)
echo "sum: $sum "
# vim test.sh --批量添加100个邮件用户,用户名为u1 至u100,密码为abc,登录shell 为/sbin/nologin,只属于email组
#!/bin/bash
password=abc
group=email
grep -Eq "^${group}:" /etc/group || groupadd $group
while read i
do
useradd u${i} -N -g $group -s /sbin/nologin
passwd u${i} --stdin <<< "$password"
done < <(seq 100)
# vim test.sh --批量删除刚刚创建的100个邮件用户
#!/bin/bash
while read i
do
userdel -r u${i}
done < <(seq 100
 
六、for 循环
在一系列由分隔符隔开的字符串中,按顺序每次取其中之一,当取完之后,循环结束
每次取出的字符串会被保存在一个变量中,可以在循环体内使用该变量
由分隔符隔开的字符串可以通过以下方法提供:
1、手动输入字符串,用于循环指定次数
# vim test.sh
#!/bin/bash
for i in 1 2 3
do
echo $i
don
2、由变量提供字符串
# vim test.sh
#!/bin/bash
FILES="/bin/bash /bin/ls /bin/cat"
for file in $FILES
do
echo $file
done
3、程序生成的字符串
# vim test.sh
#!/bin/bash
for n in $(seq 11)
do
  echo $n
done
4、由shell 展开而生成,循环目录中的文件
# vim test.sh
#!/bin/bash
for f in /etc/init.d/*
do
echo $f
done
# vim test.sh
5、打印出/dev 下面所有以 loop 开头的文件的文件名
# vim test.sh
#!/bin/bash
for file in /dev/loop*
do
echo $(basename $file)
done
6、计算出1000 之内的偶数的和
# vim test.sh
#!/bin/bash
sum=0
for number in $(seq 2 2 998)
do
  sum=$(( $sum + $number ))
done
echo "total: $sum"
7、批量添加100个邮件用户,用户名为u1 至u10,密码为abc,登录shell 为/sbin/nologin,只属于email组
# vim test.sh
#!/bin/bash
function checkGid() {
gid=$1
if ! grep -qE "^$gid:" /etc/group; then
groupadd $gid
fi
}
function isRoot() {
id=$(id | awk -F "[=(]" '{print $2}')
if test "$id" -ne 0; then
echo "must be root" >&2
exit 1
fi
}
count=10
namePrefix=u
password=abc
shell=/sbin/nologin
gid=email
isRoot
checkGid $gid
for num in $(seq $count)
do
name=${namePrefix}${num}
useradd $name -s $shell -g $gid &> /dev/null
if test $? -ne 0; then
echo "failed to create $name" >&2
else
echo "created successfully -- $name"
echo "$password" | passwd --stdin $name &> /dev/null
if test $? -ne 0; then
echo "failed to change password for $name" >&2
else
echo "password changed successfully -- $name"
fi
fi
done
8、获取局域网内所有电脑的IP 和MAC 地址的对应表
# vim test.sh
#!/bin/bash
ipPrefix=192.168.1.
startIp=1
endIp=254
for num in $(seq $startIp $endIp)
do
ip=${ipPrefix}$num
ping -W1 -c1 $ip &>/dev/null &
done
wait
arp -n | sed '/incomplete/d' | awk '{print $1,$3}'| cat | sort -n -t '.' -k4,4 | column -t
9、打印出九九乘法表
# vim test.sh
#!/bin/bash
for row in $(seq 9)
do
for col in $(seq $row)
do
echo -n "${col}x${row}=$(( $col * $row )) "
done
echo
done | column -t
10、简陋计算器
#!/bin/bash
varnum=3
if test "$#" -ne "$varnum"; then
echo "wrong argument" >&2
exit 1
fi
num1=$1
num2=$3
operator=$2
if test "$operator" = "x";then
operator="*"
fi
if test "$operator" = "/" -a "$num2" = 0; then
echo "division by 0" >& 2
exit 1
fi
result=$(( $num1 $operator $num2 ))
echo "$result"
注意:乘法的处理;被除数为0时的处理
11、把指定目录下的某些文件复制到指定的目录,要求:
#1. 从命令行参数接收两个参数,分别是源目录和目标目录
#2. 如果源目录不存在,应该报错
#3. 如果目标目录不存在,就创建一个
#4. 如果目标已经存在但不是目录,就报错
#5. 只复制常规文件,软链接文件
#6. 对于常规文件,只复制大小小于1M 的文件
# vim /test.sh
#!/bin/bash
function displayHelp()
{
echo "Usage: $(basename $0) SRCDIR DSTDIR"
}
function getSize()
{
file=$1
size=$(ls -l $file | awk '{print $5}')
echo $size
}
if test $# -ne 2; then
displayHelp >&2
exit 1
fi
srcdir=$1
dstdir=$2
if test ! -d "$srcdir"; then
echo "$srcdir not exists or is not a directory" >&2
exit 1
fi
if test ! -e "$dstdir"; then
mkdir "$dstdir"
fi
if test ! -d "$dstdir"; then
echo "$dstdir is not a directory" >&2
exit 1
fi
for file in $srcdir/*
do
if test -L $file; then
cp -a $file $dstdir/
elif test -f $file; then
---------------------------------------------------
size=$(getSize $file)
if test "$size" -lt 1048576; then
cp -a $file $dstdir/
fi
---------------------------------------------------
find $file -type f -size -1024k -exec cp -a {} $dstdir/ \;
---------------------------------------------------
fi
done

shell_script1的更多相关文章

随机推荐

  1. 维特比算法(Viterbi)-实例讲解(暴力破解+代码实现)

    1.简介 维特比算法是一个通用的求序列最短路径的动态规划算法,也可以用于很多其他问题,比如:文本挖掘.分词原理.既然是动态规划算法,那么就需要找到合适的局部状态,以及局部状态的递推公式.在HMM中,维 ...

  2. python上安装requests

    首先需要配置好python的环境变量. 测试是否成功配置,进入命令行,输入python. 如下图为配置成功. 去第三方库的网站下载安装包,解压在python的安装目录 ,下载地址:https://py ...

  3. Centos调整时间时区

    一台VPS的时间出错,使用常规手段修改均失败.提示hwclock failed : ntpdate stdtime.sinica.edu.tw 如果你的 VPS 提示没有 ntpdate 这个命令,可 ...

  4. MySQL数据库25条规范解读

    一.基础规范 (1)必须使用UTF8字符集 解读:万国码,无需转码,无乱码风险,节省空间(由于移动设备原因最好使用utf8mb4) (2)禁止使用存储过程.视图.触发器.Event 解读:高并发大数据 ...

  5. C和C++结构体的区别

    C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许该函数是虚函数.所以C的结构体是没有构造函数.析构函数.和this指针的. C的结构体对内部成员变量的访问权限只能是public,而C++ ...

  6. C#的OpenFileDialog的简单用法

    1.OpenFileDialog 中文名字叫做 打开文件对话框 OpenFileDialog的效果如图: private void btnSelectFile_Click(object sender, ...

  7. php发送post请求的三种方法

    引用:http://blog.sjzycxx.cn/post/435/ 1.使用 file_get_contents() /** * 发送post请求 * @param string $url 请求地 ...

  8. 2019.2.1 现有vue-cli项目引入ESLint

    ESLint 不管是多人合作还是个人项目,代码规范是很重要的.这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性. 可能在早期建立项目的时候,因为一些原因没有引入eslint.单元测试等, ...

  9. Node.js之HTPP URL

    几乎每门编程语言都会包括网络这块,Node.js也不例外.今天主要是熟悉下Node.js中HTTP服务.其实HTTP模块是相当低层次的,它不提供路由.cookie.缓存等,像Web开发中不会直接使用, ...

  10. Uploadify火狐出现302错误

    $(function () { var auth = "@(Request.Cookies[FormsAuthentication.FormsCookieName] == null ? st ...