文章目录
1、统计文件和目录的个数(不包括子目录)
- 方法一(会把软连接作为文件计算)
#!/bin/bash
path="/home/learner1/dir1211/*"
i=0
j=0
for file in $path ; do
if [ -f $file ]; then
echo "file : $file"
((i++))
fi
if [ -d $file ]; then
echo "dir : $file"
((j++))
fi
done
echo "文件的数量是 $i"
echo "目录的数量是 $j"
- 方法2(不会把软连接作为文件计算)
#!/bin/bash
fileCount=`ls -l ~/dir1211|grep -c "^-"`
dirCount=`ls -l ~/dir1211 |grep -c "^d"`
echo "文件数量是 $fileCount"
echo "目录数量是 $dirCount"
2、批量创建文件。
在家目录下,创建一个子目录apples,在apples目录中创建10个文件,
文件名
a0.txt
a1.txt
a2.txt
…
echo "切换到家目录"
cd ~
if [ -d ~/apples ]
then
echo "目录已存在"
else
echo "创建了新目录apples"
mkdir apples
fi
cd ~/apples
for (( i=0; i<10 ; i++ ))
do
touch a$i.txt
done
echo "结束"
3、批量修改文件名
- 只修改当前目录
#!/bin/bash
for files in `ls`
do
# 截取文件名的前两个字符
fname=${files:0:2}
# 截取文件的后四个字符
bname=${files:0-4}
# 拼接成文件名
filename=$fname$bname
# 更改文件名
mv $files $filename
done
- 修改当前目录及子目录中文件后缀名(父目录作为参数传递)
mvFileName(){
for element in `ls $1` ; do
obj=$1"/"$element
if [ -d $obj ]; then
mvFileName $obj
else
oriName=${obj%.txt}
echo $oriName
mv $obj $oriName'.data'
fi
done
}
mvFileName $1
4、根据端口号获取进程pid(不适用centos7)
#!/bin/bash
echo "请输入您要查询的端口号"
read addresspid=`sudo netstat -anp |grep :$address |cut -c 89- | cut -d / -f 1 `
#echo "$pid"
if [[ -n $pid ]];then
#echo ${pid%/*} | cut -f 7 -d " "
echo $pid
else
echo "该端口号不存在"
fi
5、批量拷贝
- (1)将当前目录下的.c文件拷贝到指定的目录,并按文件大小显示出移动后指定的目录的内容。
#!/bin/bash
for file in *.c
do
cp ${file}${1}
done
ls ${1} –S
- (2)拷贝指定目录中,小于2日内修改的文件到target目录
#!/bin/bash
for tmpFile in `find . -mtime -2`; do
if [ -f "$tmpFile" ]; then
cp $tmpFile ~/target
fi
done
6、while 练习
- (1) 用户输入数值,直到用户输入"end"停止
unset var
while [ "$var" != "end" ]; do
echo -n "please input a number: "
read var
if [ "$var" = "end" ]; then
break
fi
echo "var is $var"
done
- (2) 使用者输入yes 或者是 YES 才结束程序的执行,否则就一直进行告知用户输入字符串
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
while [ "${yn}" != "yes" -a "${yn}" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
- (3) 计算1到100的和
#!/bin/bash
# Program:
# Use loop to calculate "1+2+3+...+100" result.
s=0 # 这是加总的数值变数
i=0 # 这是累计的数值,亦即是 1, 2, 3....
while [ "${i}" != "100" ]
do
i=$(($i+1)) # 每次 i 都会增加 1
s=$(($s+$i)) # 每次都会加总一次!
done
echo "The result of '1+2+3+...+100' is ==> $s"
7、case 练习
写一个脚本实现如下功能:输入一个数字,然后运行对应的一个命令。显示命令如下:cmd meau* 1–date 2–ls 3–who 4–pwd 当输入1时,会运行date命令,输入2时会运行ls,以此论推。
#! /bin/bash
echo "*cmd meau**"
echo "1--date"
echo "2--ls"
echo "3--who"
echo "4--pwd"
read -p "please input a num:" n
case $n in
1)
date
;;
2)
ls
;;
3)
who
;;
4)
pwd
;;
*)
echo "please input 1-4"
;;
esac
8、如果文件的group类型用户没有写权限,添加写权限。
#!/bin/bash
path=~/dir1211/learnShell/multiFileDir/
for X in ${path}* ; do
a=`ls -l $X | cut -c 6`
if [ "$a" == "-" ] ; then
chmod g+w $X
fi
done
9、根据日期生成文件
提示用户输入文件名(如:ws),然后生成前天、昨天、今天的文件(如ws20181214 ws20181215 ws20181216)。
#!/bin/bash
# Program:
# Program creates three files, which named by user's input and date command.
# 1. 让使用者输入文件名,并取得 fileuser 这个变量;
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示信息
read -p "Please input your filename: " fileuser # 提示使用者输入
# 2. 为了避免使用者随意按 Enter ,利用变量功能分析档名是否有设定?
filename=${fileuser:-"filename"} # 开始判断有否配置文件名
# 3. 开始利用 date 指令来取得所需要的档名了;
for (( VAR = 0; VAR < 3; ++VAR )); do
date1=$(date --date="${VAR} days ago" +%Y%m%d) # 前N天的日期
file1=${filename}${date1}
touch "${file1}"
done
10. 检查以下端口是否开启
常见的 port 与相关网络服务的关系是
80: WWW
22: ssh
21: ftp
25: mail
#!/bin/bash
i=0
a=(:80
:22
:21
:25)
for X in 'WWW' 'ssh ' 'ftp' 'mail' ; do
a=`sudo netstat -nltp | grep ${a[$i]}`
if [ -n "$a" ] ; then
echo $X已经开启
else
echo $X没有开启
fi
((i++))
done
11 .计算日期之间差值
#!/bin/bash
# Program:
# You input your demobilization date, I calculate how many days before you demobilize.
# 1. 告知用户这支程序的用途,并且告知应该如何输入日期格式?
echo "This program will try to calculate :"
echo "How many days before your demobilization date..."
read -p "Please input your demobilization date (YYYYMMDD ex>20150716): " date2
# 2. 测试一下,这个输入的内容是否正确?利用正规表示法啰~
date_d=$(echo ${date2} |grep '[0-9]\{8\}') # 看看是否有八个数字
if [ "${date_d}" == "" ]; then
echo "You input the wrong date format...."
exit 1
fi
# 3. 开始计算日期啰~
declare -i date_dem=$(date --date="${date2}" +%s) # 退伍日期秒数
declare -i date_now=$(date +%s) # 现在日期秒数
declare -i date_total_s=$((${date_dem}-${date_now})) # 剩余秒数统计
declare -i date_d=$((${date_total_s}/60/60/24)) # 转为日数
if [ "${date_total_s}" -lt "0" ]; then # 判断是否已退伍
echo "You had been demobilization before: " $((-1*${date_d})) " ago"
else
declare -i date_h=$(($((${date_total_s}-${date_d}*60*60*24))/60/60))
echo "You will demobilize after ${date_d} days and ${date_h} hours."
fi
12 .for 练习
- (1) 由于系统上面的各种账号都是写在 /etc/passwd 内的第一个字段,你能不能透过管线命令的 cut 捉出单纯的账号名称。
#!/bin/bash
# Program
# Use id, finger command to check system account's information.
# History
# 2015/07/17 VBird 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
- (2).ping 局域网内100台机器,看是否可用
#!/bin/bash
# Program
# Use ping command to check the network's PC state.
network="192.168.1" # 先定义一个网域的前面部分!
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
- (3).设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30。
#!/bin/sh
i=1
groupadd class1
while [ $i -le 30 ]
do
if [ $i -le 9 ] ;then
USERNAME=stu0${i}
else
USERNAME=stu${i}
fi
useradd $USERNAME
mkdir /home/$USERNAME
chown -R $USERNAME /home/$USERNAME
chgrp -R class1 /home/$USERNAME
i=$(($i+1))
done