目录

以百分数显示使用率最高的前几个java线程.

show-busy-java-threads.sh
下载
#!/bin/bash
# @Function
# Find out the highest cpu consumed threads of java, and print the stack of these threads.
#
# @Usage
#   $ ./show-busy-java-threads.sh
#
# @author Jerry Lee

readonly PROG=`basename $0`
readonly -a COMMAND_LINE=("$0" "$@")

usage() {
    cat <<EOF
Usage: ${PROG} [OPTION]...
Find out the highest cpu consumed threads of java, and print the stack of these threads.
Example: ${PROG} -c 10

Options:
    -p, --pid       find out the highest cpu consumed threads from the specifed java process,
                    default from all java process.
    -c, --count     set the thread count to show, default is 5
    -h, --help      display this help and exit
EOF
    exit $1
}

readonly ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`
[ $? -ne 0 ] && usage 1
eval set -- "${ARGS}"

while true; do
    case "$1" in
    -c|--count)
        count="$2"
        shift 2
        ;;
    -p|--pid)
        pid="$2"
        shift 2
        ;;
    -h|--help)
        usage
        ;;
    --)
        shift
        break
        ;;
    esac
done
count=${count:-5}

redEcho() {
    [ -c /dev/stdout ] && {
        # if stdout is console, turn on color output.
        echo -ne "\033[1;31m"
        echo -n "$@"
        echo -e "\033[0m"
    } || echo "$@"
}

yellowEcho() {
    [ -c /dev/stdout ] && {
        # if stdout is console, turn on color output.
        echo -ne "\033[1;33m"
        echo -n "$@"
        echo -e "\033[0m"
    } || echo "$@"
}

blueEcho() {
    [ -c /dev/stdout ] && {
        # if stdout is console, turn on color output.
        echo -ne "\033[1;36m"
        echo -n "$@"
        echo -e "\033[0m"
    } || echo "$@"
}

# Check the existence of jstack command!
if ! which jstack &> /dev/null; then
    [ -z "$JAVA_HOME" ] && {
        redEcho "Error: jstack not found on PATH!"
        exit 1
    }
    ! [ -f "$JAVA_HOME/bin/jstack" ] && {
        redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack file does NOT exists!"
        exit 1
    }
    ! [ -x "$JAVA_HOME/bin/jstack" ] && {
        redEcho "Error: jstack not found on PATH and $JAVA_HOME/bin/jstack is NOT executalbe!"
        exit 1
    }
    export PATH="$JAVA_HOME/bin:$PATH"
fi

readonly uuid=`date +%s`_${RANDOM}_$$

cleanupWhenExit() {
    rm /tmp/${uuid}_* &> /dev/null
}
trap "cleanupWhenExit" EXIT

printStackOfThread() {
    local line
    local count=1
    while IFS=" " read -a line ; do
        local pid=${line[0]}
        local threadId=${line[1]}
        local threadId0x=`printf %x ${threadId}`
        local user=${line[2]}
        local pcpu=${line[4]}

        local jstackFile=/tmp/${uuid}_${pid}

        [ ! -f "${jstackFile}" ] && {
            {
                if [ "${user}" == "${USER}" ]; then
                    jstack ${pid} > ${jstackFile}
                else
                    if [ $UID == 0 ]; then
                        sudo -u ${user} jstack ${pid} > ${jstackFile}
                    else
                        redEcho "[$((count++))] Fail to jstack Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user})."
                        redEcho "User of java process($user) is not current user($USER), need sudo to run again:"
                        yellowEcho "    sudo ${COMMAND_LINE[@]}"
                        echo
                        continue
                    fi
                fi
            } || {
                redEcho "[$((count++))] Fail to jstack Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user})."
                echo
                rm ${jstackFile}
                continue
            }
        }
        blueEcho "[$((count++))] Busy(${pcpu}%) thread(${threadId}/0x${threadId0x}) stack of java process(${pid}) under user(${user}):"
        sed "/nid=0x${threadId0x} /,/^$/p" -n ${jstackFile}
    done
}


ps -Leo pid,lwp,user,comm,pcpu --no-headers | {
    [ -z "${pid}" ] &&
    awk '$4=="java"{print $0}' ||
    awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}'
} | sort -k5 -r -n | head --lines "${count}" | printStackOfThread

批量下载url地址文件

url_download_scripts_v4.sh
下载
#!/bin/bash

# 定义变量
URL_FILE="files/file.txt"
ENCODED_URL_FILE="files/encoded_urls.txt"
LOG_FILE="logs/download.log"
SUCCESS_FILE="logs/success.log"
FAIL_FILE="logs/fail.log"
DOWNLOAD_DIR="files/downloads"

# 创建下载目录和日志目录
mkdir -p "$DOWNLOAD_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$ENCODED_URL_FILE")"

# 初始化计数器
total=0
success=0
fail=0

# 清空日志文件
> "$LOG_FILE"
> "$SUCCESS_FILE"
> "$FAIL_FILE"

# 记录开始时间
echo "下载开始时间: $(date)" | tee -a "$LOG_FILE"
echo "==========================================" | tee -a "$LOG_FILE"

# 第一步:对URL文件进行编码处理
echo "正在对URL进行编码处理..." | tee -a "$LOG_FILE"
> "$ENCODED_URL_FILE"

while IFS= read -r url || [[ -n "$url" ]]; do
    # 跳过空行
    url=$(echo "$url" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    if [[ -z "$url" ]]; then
        continue
    fi
    
    # 对URL进行编码:空格 -> %20, ( -> %28, ) -> %29
    encoded_url=$(echo "$url" | sed '
        s/ /%20/g;
        s/(/%28/g;
        s/)/%29/g
    ')
    
    echo "$encoded_url" >> "$ENCODED_URL_FILE"
    echo "原始: $url" | tee -a "$LOG_FILE"
    echo "编码: $encoded_url" | tee -a "$LOG_FILE"
    echo "---" | tee -a "$LOG_FILE"
    
done < "$URL_FILE"

echo "URL编码完成!编码后的URL保存在: $ENCODED_URL_FILE" | tee -a "$LOG_FILE"
echo "==========================================" | tee -a "$LOG_FILE"

# 第二步:使用编码后的URL进行下载
echo "开始下载文件..." | tee -a "$LOG_FILE"

# 创建文件映射记录,避免重复
declare -A downloaded_files

while IFS= read -r encoded_url || [[ -n "$encoded_url" ]]; do
    # 跳过空行
    encoded_url=$(echo "$encoded_url" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    if [[ -z "$encoded_url" ]]; then
        continue
    fi

    total=$((total + 1))

    # 从编码后的URL中提取文件名(需要先解码文件名部分)
    original_filename=$(echo "$encoded_url" | sed 's|.*/||' | sed '
        s/%20/ /g;
        s/%28/(/g;
        s/%29/)/g
    ')
    
    # 获取文件扩展名
    extension="${original_filename##*.}"
    if [[ "$extension" == "$original_filename" ]]; then
        extension=""
    else
        extension=".$extension"
    fi
    
    # 生成唯一文件名(添加序号前缀)
    base_filename=$(basename "$original_filename" "$extension")
    filename="${total}_${base_filename}${extension}"
    
    # 检查文件名是否已存在,如果存在则添加时间戳
    if [[ -n "${downloaded_files[$filename]}" ]]; then
        timestamp=$(date +%Y%m%d_%H%M%S)
        filename="${total}_${base_filename}_${timestamp}${extension}"
    fi
    
    downloaded_files[$filename]=1

    # 完整的文件路径
    filepath="${DOWNLOAD_DIR}/${filename}"

    echo "正在下载第 $total 个文件: $filename" | tee -a "$LOG_FILE"
    echo "原始文件名: $original_filename" | tee -a "$LOG_FILE"
    echo "编码URL: $(echo "$encoded_url" | cut -c1-80)..." | tee -a "$LOG_FILE"

    # 使用wget下载文件
    if wget --timeout=30 --tries=3 \
            --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
            -O "$filepath" \
            "$encoded_url" 2>> "$LOG_FILE"; then
        
        # 检查文件是否真的下载成功(文件存在且大小大于0)
        if [[ -f "$filepath" ]] && [[ -s "$filepath" ]]; then
            file_size=$(wc -c < "$filepath")
            echo "✓ 成功下载: $filename ($file_size bytes)" | tee -a "$LOG_FILE"
            echo "$encoded_url -> $filepath ($file_size bytes)" >> "$SUCCESS_FILE"
            success=$((success + 1))
            
        else
            echo "✗ 文件为空或损坏: $filename" | tee -a "$LOG_FILE"
            echo "$encoded_url -> 空文件/损坏" >> "$FAIL_FILE"
            rm -f "$filepath" 2>/dev/null
            fail=$((fail + 1))
        fi
    else
        echo "✗ 下载失败: $filename" | tee -a "$LOG_FILE"
        echo "$encoded_url" >> "$FAIL_FILE"
        fail=$((fail + 1))
    fi

    echo "---" | tee -a "$LOG_FILE"
    
    # 添加延迟,避免对服务器造成太大压力
    sleep 1

done < "$ENCODED_URL_FILE"

# 记录结束时间和统计信息
echo "==========================================" | tee -a "$LOG_FILE"
echo "下载结束时间: $(date)" | tee -a "$LOG_FILE"
echo "==========================================" | tee -a "$LOG_FILE"
echo "总文件数: $total" | tee -a "$LOG_FILE"
echo "成功下载: $success" | tee -a "$LOG_FILE"
echo "下载失败: $fail" | tee -a "$LOG_FILE"

# 使用awk计算成功率(避免bc命令不存在)
if [[ $total -gt 0 ]]; then
    success_rate=$(awk "BEGIN {printf \"%.2f%%\", $success * 100 / $total}")
    echo "成功率: ${success_rate}" | tee -a "$LOG_FILE"
else
    echo "成功率: 0%" | tee -a "$LOG_FILE"
fi

# 输出下载目录的内容和实际文件数
actual_files=$(ls -1 "$DOWNLOAD_DIR" 2>/dev/null | wc -l)
echo "实际下载文件数: $actual_files" | tee -a "$LOG_FILE"

echo "==========================================" | tee -a "$LOG_FILE"
echo "下载目录内容:" | tee -a "$LOG_FILE"
ls -la "$DOWNLOAD_DIR/" | head -15 | tee -a "$LOG_FILE"

# 检查重复文件
echo "==========================================" | tee -a "$LOG_FILE"
echo "检查重复文件..." | tee -a "$LOG_FILE"
ls -1 "$DOWNLOAD_DIR/" | sed 's/^[0-9]*_//' | sort | uniq -d | while read duplicate; do
    count=$(ls -1 "$DOWNLOAD_DIR/" | grep "_${duplicate}$" | wc -l)
    echo "重复文件: $duplicate (出现 $count 次)" | tee -a "$LOG_FILE"
done

# 输出日志文件位置
echo "=========================================="
echo "详细日志: $LOG_FILE"
echo "成功下载列表: $SUCCESS_FILE"
echo "失败下载列表: $FAIL_FILE"
echo "编码后的URL文件: $ENCODED_URL_FILE"
echo "文件下载到: $DOWNLOAD_DIR/"
use_rsync.sh
下载
#!/bin/bash
##########################################
# File Name:use_rsync.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:部署rsync脚本
###########################################

#create color func
#颜色函数
function redecho(){
        input="$@"
        echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
        input="$@"
        echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
        input="$@"
        echo -e "\E[1;36m${input}\E[0m"
}
function yellowecho(){
        input="$@"
        echo -e "\E[1;33m${input}\E[0m"
}

#1.vars


#check user

echo "################################################"
if [ "`whoami`" = "root" ];then
	greenecho "当前为root用户,开始执行脚本"
else
	redecho "请切换root用户执行此脚本"
	exit 0
fi
echo "------------------------------------------------"

#begin server
blueecho "1.检查是否安装rsync软件包: "
if rpm -qa | grep rsync &>/dev/null;then
	greenecho "系统中已有rsync,跳过安装步骤........."
else
	yum install -y rsync &>/dev/null
	if [ $? -ne 0 ];then
		redecho "安装失败,请检查系统网络/yum源" 
		exit 1
	fi
fi
echo "------------------------------------------------"

config_file=/etc/rsyncd.conf
blueecho "2. 书写配置文件:  此处只支持单个模块的配置与配置文件除了模块外的其他项,如果想部署多个模块请修改脚本中66-82行 "
read -p  "请输入接收文件的模块名字: " name
yellowecho "模块名:$name"
read -p  "请输入模块描述: " comment
yellowecho "模块描述: $comment"
read -p  "请输入模块的文件夹位置:" path
yellowecho "模块文件夹位置:$path"

cat > $config_file <<EOF
uid=rsync
gid=rsync
logfile=/var/log/rsyncd.log
auth users=rsync_backup 
secrets file=/etc/rsyncd.password
fake super=yes
use chroot=no
max connections=2000
timeout=600
pid file=/var/run/rsync.pid
lock file=/var/run/rsync.lock
ignore errors=yes
read only=false
list=false
[$name] 
comment=$comment
path=$path
EOF
if [ $? -eq 0 ];then
	greenecho "成功写入配置文件 "
else
	redecho "写入配置失败,请检查"
	exit 2
fi
echo "------------------------------------------------"
#开始执行部署命令
blueecho "创建rsync用户:"
if id rsync  &>/dev/null ;then
	greenecho "已存在rsync用户,跳过创建步骤......"
else
	useradd -s /sbin/nologin -M rsync
	greenecho "已创建rsync用户"
fi
echo "------------------------------------------------"
blueecho "设置自动传输密码文件rsync.client"
password_file=/etc/rsyncd.password
read -p "设置密码文件rsync.client,请直接输入密码 : " password
echo "rsync_backup:$password" > $password_file && chmod 600 $password_file

echo "------------------------------------------------"
blueecho "创建存放备份的目录并设置目录所属主所属组均为rsync用户"
mkdir -p $path  && chown -R rsync:rsync $path &>/dev/null

echo "------------------------------------------------"

if ! systemctl enable --now rsyncd;then
	blueecho "创建systemd文件,存放位置/etc/systemd/system/rsyncd.service"
cat > /etc/systemd/system/rsyncd.service <<EOF
[Unit]
Description=fast remote file copy program daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
ExecReload=/bin/kill -HUP \$MAINPID

[Install]
WantedBy=multi-user.target
EOF
echo "成功创建systemd文件"
fi

echo "------------------------------------------------"
blueecho "启动rsyncd服务"
if systemctl restart rsyncd && systemctl enable --now rsyncd &>/dev/null;then
	greenecho "服务启动成功,已设置开机自启"
else
	redecho "服务启动失败,请检查配置文件/服务管理文件"
	exit 3
fi

echo "------------------------------------------------"
blueecho "防火墙放行873端口,放行rsyncd服务,重启防火墙"
firewall-cmd --permanent --add-port=873/tcp && firewall-cmd --permanent --add-service=rsyncd && firewall-cmd --reload  &>/dev/null


echo "------------------------------------------------"
blueecho "#解除SELinux安全上下文值限制,允许 rsync 完全访问"
semanage fcontext -a -t rsync_data_t "$path(/.*)?"  &&  restorecon -Rv $path &&   setsebool -P rsync_full_access=1 &&  setenforce 1 &>/dev/null


echo "------------------------------------------------"
read -p "请输入密码创建客户端密码文件: " clientpasswd
client_file=/etc/rsync.client
echo "$clientpasswd" $client_file && chmod 600 $client_file  &>/dev/null


echo "------------------------------------------------"
blueecho   "开始本机测试(自己传自己)"
rsync -av /etc/hostname rsync_backup@$HOSTNAME::$name  --password-file=$client_file  &>/dev/null
if [ $? -eq 0 ];then
	greenecho "传输完成,请检查是否传输成功,查看目录:$path"
	ls -l $path
else
	redecho "传输失败,请检查服务状态/配置文件/脚本变量"
	exit 5
fi
sshfenfa.sh
下载
#!/bin/bash
##########################################
# File Name:sshfenfa.sh
# Version:V1.0
# Author:zhangpeng-vxhs888p
# linuxjk.cn
# Desc:
#1. 检查密钥文件是否存在,如果不存在则创建 ~/.ssh/id_rsa
#2. ip列表(变量,文件,数组)分发公钥
#3. for+分发命令
#4. 检查成功,失败
#5. for+批量执行命令
#6. for+ssh命令 hostname -I
###########################################

#颜色函数
function redecho(){
        input="$@"
        echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
        input="$@"
        echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
        input="$@"
        echo -e "\E[1;36m${input}\E[0m"
}

#1.vars
key_file=/root/.ssh/id_rsa
pub_file=/root/.ssh/id_rsa.pub
ip_file=/server/scripts/ip.txt
ips="`cat $ip_file`"
pass=linuxjk.cn666
#ips="10.0.0.7 10.0.0.8 10.0.0.9"
#2.检查密钥文件是否存在,如果不存在则创建 ~/.ssh/id_rsa
blueecho "检查密钥文件是否存在"
if [ ! -f ${key_file} ];then
	ssh-keygen -f $key_file -P '' &>/dev/null
	if [ $? -eq 0 ];then
		greenecho "成功创建密钥文件 $key_file "
	else
		redecho "创建密钥文件失败,请检查脚本!"
		exit 1
	fi
else
	greenecho "已存在密钥对,跳过此步......"
fi

#3.分发密钥
blueecho "开始分发密钥"
for ip in $ips
do
	#3.1检查ip是否能ping通
	if  ! ping -c 1 -W 1 $ip &>/dev/null ;then
		redecho "$ip 尝试访问失败,请检查脚本或服务器开机状态"
		continue
	fi
	#3.2分发
	sshpass -p$pass ssh-copy-id -i $pub_file -o StrictHostKeyChecking=no "root@$ip" &>/dev/null
	if [ $? -eq 0 ];then
		greenecho "$ip 密钥分发成功"
		#3.2.1.验证连接
		if  ssh -o StrictHostKeyChecking=no $ip hostname -I &>/dev/null ;then
			greenecho "$ip SSH连接验证成功"
		else
			redecho "$ip SSH连接验证失败"
		fi
	else
		redecho "$ip 密钥分发失败"
	fi
done

greenecho "所有操作已完成!"
exit 0
ip.txt
下载
lb01
lb02
web01
web02
web03
web04
nfs01
backup
db01
m01

案例01:每次用户登录后显示系统基本信息

01_check_sys_cat.sh
下载
#!/bin/bash
##########################################
# File Name:01_check_sys_cat.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例01:每次用户登录后显示系统基本信息
###########################################

#1.vars变量
hostname=`hostname`
username=`whoami`
loadavg=`w | awk 'NR==1 {print$(NF-2),$(NF-1),$NF}'`
cpus=`lscpu | grep "CPU(s):" | awk 'NR==1 {print $2}'`
#procs=`top -bn1 | awk 'NR==2 {print $2}'`
procs=`ps -e --no-headers | wc -l`
zombies=`top -bn1 | awk 'NR==2 {print $(NF-1)}'`
#top_mem_processes=$(ps -eo %mem,comm --sort=-%mem | awk 'NR<=11 && NR>1 {print $2}')
#top_mem_processes=`top -bn1 -w 512 -o %MEM | awk 'NR>=8&&NR<13 {print $12}'` 显示内存占用前10但发现有重复值
top_mem_processes=`top -bn1 -w 512 -o %MEM | awk 'NR>=8&&NR<21 {print $12}' | uniq -c | awk '{print $NF}'`  #去重处理,只显示前13个进程中靠前的几个

mem_total=`free -h | awk 'NR==2 {print $2}'`
mem_sy=`free -h | awk 'NR==2 {print $NF}'`
swap_total=`free -h | awk 'NR==3 {print $2}'`
swap_sy=`free -h | awk 'NR==3 {print $NF}'`
ips=`hostname -I`
#实现登录时提示,切换用户不提示:判断两个变量是否存在,存在表示远程登陆,不存在就是切换用户
# 严格判断:只有 SSH 登录且父进程是 sshd 时才输出
if [ -n "$SSH_CLIENT" ] && [ -n "$SSH_TTY" ] && [ "$(ps -o comm= -p $PPID)" = "sshd" ]; then
cat<<EOF
主机名:$hostname
ip地址:$ips
用户名:$username
系统负载:$loadavg
CPU核心总数:$cpus
进程总数:$procs
僵尸进程数量:$zombies
内存大小/内存剩余:$mem_total $mem_sy
swap大小/swap剩余:$swap_total $swap_sy
Top 10 内存占用进程:
$top_mem_processes
EOF
else
   exit 1
fi
weather.sh
下载
#!/bin/bash
#curl -s wttr.in/longfeng?lang=zh | awk 'NR <= 17; END { print lines[40 - 2] } { lines[NR] = $0 }'


function redstrongecho(){
	input="$@"
	echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
	input="$@"
	echo -e "\E[1;42m${input}\E[0m"
}
#if [ -n "$SSH_CLIENT" ] && [ -n "$SSH_TTY" ] && [ "$(ps -o comm= -p $PPID)" = "sshd" ]
#then
redstrongecho "今天的天气是:"

curl -s wttr.in/Jiamusi?lang=zh | awk 'NR <= 17; END { print lines[40 - 2] } { lines[NR] = $0 }'
#else
#	exit 1
#fi

案例02:执行脚本时输入用户名判断用户名是否存在

02_check_user_exist.sh
下载
#!/bin/bash
##########################################
# File Name:02check_user_exist.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例02:执行脚本时输入用户名判断用户名是否存在
###############
############################

#1.vars
user=$1
#2.检查参数数量是否不为1,stop and exit
if [ $# -ne 1 ]
then
	echo "参数数量不对,请重新运行脚本!"
	echo "正确格式:sh *.sh username"
	exit 1
fi
#执行命令,下一步根据此处是否执行成功判断输出信息
id ${user} &>/dev/null
#3. id user--check
if [ $? -eq 0 ]
then
	echo "${user} is exist,detailed information:"
	id ${user}
else
	echo "${user} not exist"
fi

案例03:检查ip或域名是否可以访问

03_check_ip_connect.sh
下载
#!/bin/bash
##########################################
# File Name:03_check_ip_connect.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例03:检查ip或域名是否可以访问
###########################################
#1 vars
ip=$1
#2.检查参数数量是否不为1,stop and exit
if [ $# -ne 1 ]
then 
	echo "脚本参数数量不对,请输入1个ip或域名"
        echo "正确格式:sh *.sh ipaddress/domain name"
	exit 1
fi
#3执行命令,下一步根据此处是否执行成功判断输出信息
ping -c1 ${ip}  &>/dev/null
#4 judge $?
if [ $? -eq 0 ]
then
	echo "connected"
else
	echo "please check your net or input"
fi

案例04:shell中的位置变量$n,当n>9时怎么处理?-----${10} ${11}

04_test_arg.sh
下载
#!/bin/bash
##########################################
# File Name:04_test_arg.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例04:shell中的位置变量$n,当n>9时怎么处理?-----${10} ${11}
###########################################
echo $1 $2 $3... $9 ${10} ${11} ${12}

案例05:$#表示运行脚本时输入参数的个数,一般用于与判断结合 (检查输入参数的数量是否正确)

05_test_jing.sh
下载
#!/bin/bash
##########################################
# File Name:05_test_jing.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例05:$#表示运行脚本时输入参数的个数,一般用于与判断结合 (检查输入参数的数量是否正确)
###########################################
echo $1 $2 $3
echo $#

案例06:执行脚本输入1个或多个用户名通过脚本进行输出 (检查这些用户是否存在)

06_check_multi_users.sh
下载
#!/bin/bash
##########################################
# File Name:06_check_multi_users.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例06:执行脚本输入1个或多个用户名通过脚本进行输出 (检查这些用户是否存在)
###########################################
#1.vars
names="$@"

#2.检查脚本参数个数是否为0(输入是否为空),如果输入为空则退出
if [ $# -eq 0 ];then
	echo "please check your input"
	echo "help: sh  $0 user..."
	exit 1
fi

#3.for
for i in ${names}
do
	#用id命令检查用户是否存在
	id ${i} &>/dev/null
if [ $? -eq 0 ]
then
	id ${i}
else
	echo "$i is not exist"
fi
done

案例07:替代rm的回收站脚本

07_rm.sh
下载
#!/bin/bash
##########################################
# File Name:07_rm.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:替代rm的回收站脚本
###########################################

#1. 创建临时目录
tmp_dir=$(mktemp -d -p /tmp rm_sh_XXXXX)
input_dir="$1"  # 直接使用 $1 更简洁

#2. 校验输入非空
if [ -z "$input_dir" ]; then
    echo "错误:未提供目录参数!"
    exit 1
fi

#3. 解析绝对路径(使用 readlink -f 增强兼容性)
jueduipath=$(readlink -f "$input_dir" 2>/dev/null)
if [ $? -ne 0 ] || [ -z "$jueduipath" ]; then
    echo "failed: $input_dir is not exist"
    exit 1
fi

#4. 检查是否为根目录
if [ "$jueduipath" = "/" ]; then
    echo "this is /, stop your rm !"
    exit 1
fi

#5. 移动目标到临时目录
mv -- "$jueduipath" "$tmp_dir"
if [ $? -eq 0 ]; then
    echo "success save to $tmp_dir"
else
    echo "failed"
fi

案例10:通过脚本传参输入任何一个命令并执行,检查这个命令的执行结果是否正确

10_check_cmd.sh
下载
#!/bin/bash
##########################################
# File Name:10_check_cmd.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例10:通过脚本传参输入任何一个命令并执行,检查这个命令的执行结果是否正确
###########################################
#1.vars
cmd="$@"


#2.检查脚本参数个数是否为0(输入是否为空),如果输入为空则退出
if [ $# -eq 0 ]
then
	echo "error!!! please input correct command"
	echo "help: sh $0 cmd"
	exit 1
fi

#3.执行输入的命令,输出定向到空
$cmd &> /dev/null

#4.进行判断上一条命令的返回值,为0则成功
if [ $? -eq 0 ]
then
	echo "${cmd} success!"
else
	echo "${cmd} error!"
fi

案例11:for循环打印下面这一段话中字母数不大于6的单词

I am a teacher welcome to my home thanks everybody yes or no

11_calc_strings.sh
下载
#!/bin/bash
##########################################
# File Name:11_calc_strings.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例11:for循环打印下面这一段话中字母数不大于6的单词
###########################################

#I am a teacher welcome to my home thanks everybody yes or no
#1.vars
strs="I am a teacher welcome to my home thanks everybody yes or no"
num=6
#2.for
for str in $strs
do
	#begin if <= 6 echo $str
	if [ ${#str} -le $num ]
	then
		echo "$str"
	else
	       echo "$str" &>/dev/null	
	fi
done

案例12:书写脚本检查输入的域名(一个或多个)是否可以ping通--通过read命令实现

12_ping_url.sh
下载
#!/bin/bash
##########################################
# File Name:12_ping_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例12:书写脚本检查输入的域名(一个或多个)是否可以ping通--通过read命令实现
source /funcs/func_diy.sh
#调用个人函数库
###########################################
#1.vars:
read -t 40 -p "please input domains: " urls
#-t:40s内无输入则退出 -p:打印后面的提示信息
#2.检查变量是否为空
if [ -z $urls ];then
    echo "Help: 请输入1个或多个域名"
fi
#3.for
for i in ${urls}
do
	ping -c1 ${i} &>/dev/null
	if [ $? -eq 0 ]
	then
		redstrongecho "${i} is yes"
	else
		greenstrongecho "${i} is no"
	fi
done

案例13:计算器传入脚本中2个参数,进行计算,输出结果①命令行传参②read传参

13_num_calc.sh
下载
#!/bin/bash
##########################################
# File Name:13_num_calc.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例13:计算器传入脚本中2个参数,进行计算,输出结果  ①命令行传参
###########################################
#1.vars
num1=$1
num2=$2

#2.检查脚本参数个数是否为2,如果不为2则输出帮助信息并退出
if [ $# -ne 2 ]
then
	echo "help: sh $0 num1 num2"
	exit 3
fi
#3.检查输入的是否为数字
expr 1 + $num1 + $num2 &>/dev/null
if [ $? -ge 2 ]
then
	echo "sh $0 num1 num2"
	exit 1
fi
	
#使用awk计算加减乘除
jia=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1+n2}'`
jian=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1-n2}'`
cheng=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1*n2}'`
chu=`awk -v n1=$num1 -v n2=$num2 'BEGIN{print n1/n2}'`
#4.按照两种格式输出运算结果
cat <<EOF
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu
EOF
echo "
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu"

#3.直接计算并输出
echo "$1 + $2=`echo $num1 + $num2 | bc -l`"
echo "$1 - $2=`echo $num1 - $num2 | bc -l`"
echo "$1 * $2=`echo "$num1 * $num2" | bc -l`"
echo "$1 / $2=`echo $num1 / $num2 | bc -l`"

echo "$1 + $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a+b}'`"
echo "$1 - $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a-b}'`"
echo "$1 * $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a*b}'`"
echo "$1 / $2= `awk -v a=$num1 -v b=$num2 'BEGIN{print a/b}'`"
14_num_calc_read.sh
下载
#!/bin/bash
##########################################
# File Name:13_num_calc_read.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例13:计算器传入脚本中2个参数,进行计算,输出结果  ②read传参
###########################################
#1.vars
read -p "please input two parmeters: " num1 num2

#检查脚本输入是否为空,最多有一个为空则退出
if [ -z "$num1" -o -z "$num2" ]
then
	echo "help: sh $0 num1 num2"
	exit 1
fi
#2.检查参数是否为数字
expr 1 + $num1 + $num2 &>/dev/null
if [ $? -gt 1 ]
then
	echo "error, need input two numbers"
	exit 2
fi

#3.进行计算
#使用 bc计算并直接输出结果
echo "$num1 + $num2= `echo $num1+$num2 | bc -l`"
echo "$num1 - $num2= `echo $num1-$num2 | bc -l`"
echo "$num1 * $num2= `echo $num1*$num2 | bc -l`"
echo "$num1 / $num2= `echo $num1/$num2 | bc -l`"
#使用 awk计算并输出
jia=`awk -v a=$num1 -v b=$num2 'BEGIN{ print a+b}'`
jian=`awk -v a=$num1 -v b=$num2 'BEGIN{print a-b}'`
cheng=`awk -v a=$num1 -v b=$num2 'BEGIN{print a*b}'`
chu=`awk -v a=$num1 -v b=$num2 'BEGIN{print a/b}'`
cat <<EOF
$num1 + $num2 = $jia
$num1 - $num2 = $jian
$num1 * $num2 = $cheng
$num1 / $num2 = $chu
EOF


案例17:通过脚本传参方式传输1个参数,判断是否为文 件,是否为目录,是否具有执行权限.(字符串比较)

17_check_file.sh
下载
#!/bin/bash
##########################################
# File Name:17_check_file.sh
# Version:V3.0
# Author:zhangpeng
# Organization:linuxjk.cn
# Desc: 检查是否为文件,是否为目录,是否具有执行权限.增强文件类型检测(支持软链接)
###########################################

# 参数检查
[ $# -ne 1 ] && { echo "用法: sh $0 文件/目录"; exit 1; }

file="$1"

# 存在性检查
[ ! -e "$file" ] && { echo "错误:$file 不存在!"; exit 1; }

# 类型检测(按检测顺序排序)
#如果软连接指向文件/目录,先检测-f/-d会检测软连接指向的那个文件/目录,所以先检测软连接
if [ -L "$file" ]; then
    type="软链接"
   # target=$(readlink -f "$file")
    
    # 检查目标文件权限
    if [ -x "$target" ]; then
        perm="目标文件有执行权限"
    else
        perm="目标文件无执行权限"
    fi
    
elif [ -f "$file" ]; then
    type="普通文件"
    [ -x "$file" ] && perm="有执行权限" || perm="没有执行权限"
    
elif [ -d "$file" ]; then
    type="目录"
    [ -x "$file" ] && perm="有执行权限" || perm="无执行权限"
    
else
    echo "$file 存在,但无法识别类型(可能是设备文件、管道文件等)"
    exit 1
fi

echo "$file 类型:${type},${perm}"
17_check_file_easy.sh
下载
#!/bin/bash
##########################################
# File Name:17_check_file_1.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查是否为文件,是否为目录,是否具有执行权限.(简化版)
###########################################

#1.vars
file=$1

#2.检查参数个数是否为1
[ $# -ne 1 ] && {
	echo "help: sh $0 file"
        exit 1
}
#3.-d 检查是否为目录
if [ -d $file ]
then
	echo "$file is dir"
else
	echo "$file is not a dir"
fi

#4.-f 检查是否为文件
if [ -f $file ]
then
	echo "$file is file"
else
	echo "$file is not a file"
fi
#5. -x 检查是否具有执行权限.
if [ -x $file ];then
		echo "$file has +x"
else
		echo "$file has not +x"
fi

#6.-L 检查是否为软连接
if [ -L $file ];then
	echo "$file is a softlink"
else
	echo "$file is not a softlink"
fi

案例18-检查selinux是否关闭脚本,如果没有关闭提示是否要关闭,yes则关闭,其他就不关闭

18_check_selinux.sh
下载
#!/bin/bash
##########################################
# File Name:18_check_selinux.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查selinux是否关闭,如果未关闭,提示是否要关闭,yes则关闭,其他就不关闭
###########################################
#1.vars
#/etc/selinux/config中显示的SELINUX=$perm
#getenforce显示的$temp

#2.取出配置文件/命令行中selinx的状态
#awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config
perm=`sed -nr '/^SELINUX=/p' /etc/selinux/config | awk -F= '{print $NF}'`
temp=`getenforce`
#3.判断字符串是否为空
if [[ -z "$perm"  ||  -z "$temp" ]]
then
	echo "无法获取selinux策略:请检查配置文件:/etc/selinux/config"
	exit 1
fi

#3.判断以上两个字符串是否同时等于disabled→→→selinux彻底关闭
if [[ "$perm" = "disabled" ]] &&  { [[ "$temp" = Disabled ]] ||  [[ "$temp" = Permissive ]] ;}
then
	echo "SELINUX 已经关闭"
	exit 1
else
	 
#4.此时需要用户输入是否要关闭,yes
        read -p "SELINUX未关闭,是否关闭selinux:关闭请输入yes:" input
	if [ "$input" = yes ];then
		sed -i "s#SELINUX=.*#SELINUX=disabled#g" /etc/selinux/config
		setenforce 0
		echo "已关闭selinux,重启生效"
		exit 1
	else
		echo "selinux is $temp"
		exit 1
	fi
fi
18_check_selinux_easy.sh
下载
#!/bin/bash
##########################################
# File Name:18.check_selinux_1.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例18-检查selinux是否关闭脚本,如果没有关闭提示是否要关闭,yes则关闭,其他就不关闭
###########################################
#1.vars
selinux_config=`awk -F= '/^SELINUX=/ {print $2}' /etc/selinux/config`
selinux_cmd=`getenforce`
#2 判断是否关闭
#两个条件同时成立在[]中需要使用-a,[ 条件1 -a 条件2 ]相当于[]&&[]或[[ 条件1 && 条件2 ]]
if [ "$selinux_config" = "disabled" -a "$selinux_cmd" = "Disabled" ]
then
	echo "SELINUX已经关闭"
else
	read -p "是否关闭selinux,请输入yes/no: " xuan
	if [ "$xuan" = "yes" ];then
		sed -i '/^SELINUX=/s#=.*#=disabled#g' /etc/selinux/config
		setenforce 0
		echo "关闭成功!"
	else
		echo "SELINUX 未关闭!"
	fi
fi

案例20: 书写一个脚本通过read读取输入,判断 输入是整数,浮点数(小数),还是字符.

20_check_type.sh
下载
#!/bin/bash
##########################################
# File Name:20_check_type.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例20: 书写一个脚本通过read读取输入,判断输入数据类型(整数/浮点/字符串)
###########################################

#1. 获取输入
read -p "pls input: " input

#2. 检查输入非空
if [ -z "$input" ]; then
    echo "error Help: sh $0 input"
    exit 1
fi

#3. 判断数据类型
if [[ $input =~ ^[+-]?[0-9]+$ ]]; then           # 整数(含正负)
    echo "zhengshu"
elif [[ $input =~ ^[+-]?[0-9]+\.[0-9]+$ ]]; then  # 浮点数(含正负)
    echo "fudian"
elif [[ $input =~ ^[a-zA-Z0-9]+$ ]]; then        # 纯字母数字组合字符串
    echo "str"
else
    echo "unknown data"
fi
exit 0

案例21: 书写服务检查脚本,执行的时候输入服务名字检查是否运 行,检查是否开启自启动.

21_check_service.sh
下载
#!/bin/bash
##########################################
# File Name: 21_check_service.sh
# Version: V1.1
# Author: zhangpeng
# Organization: linuxjk.cn
# Desc: 服务状态检查脚本
##########################################

# 1. 获取服务名称read -r禁用转义符
read -rp "Please input a service name: " service

# 2. 检查输入是否为空
if [ -z "$service" ]; then
    echo "Usage: sh $0 <service_name>"
    exit 1
fi

# 3. 检查服务是否存在--type确保只检查服务文件
# 直接通过 systemctl 查询(无需管道)
#if ! systemctl list-unit-files --type=service "$service.service" &>/dev/null
if ! systemctl list-unit-files --type=service | grep -qw "^$service.service"; then
    echo "Error: Service '$service' does not exist."
    exit 2
fi

# 4. 获取状态信息
run=$(systemctl is-active "$service")
auto=$(systemctl is-enabled "$service")

# 5. 判断逻辑优化
# 修正后的代码片段
#systemctl is-active "$service" &>/dev/null
#if [ $? -eq 0 ];then
#echo "$service is running"
#else
#echo "$service is running"
#fi
#和下面的格式不同效果一样:命令返回值为0则正确输出,不为0进入else,
#把命令放在if后的弊端:类似于expr那种成功的返回值为0或1 的命令不行
if systemctl is-active "$service" &>/dev/null
then
	echo "$service is running"
else
	echo "$service is not runing"
fi

if systemctl is-enabled "$service" &>/dev/null
then
	echo "$service is enabled"
else
	echo "$service is disenabled"
fi













#if [ "$run" = "active" ]; then
#    status1="running"
#else
#    status1="not running"
#fi

#if [ "$auto" = "enabled" ]; then
#    status2="enabled"
#else
#    status2="disabled"
#fi

#if [ "$run" = "active" ] && [ "$auto" = "enabled" ]; then
#    echo "$service is $status1, and $status2"
#elif [ "$run" = "active" ] && [ "$auto" != "enabled" ]; then
#    echo "$service is $status1"
#elif [ "$auto" = "disabled" ] && [ "$run" = "active" ]; then
#    echo "$service is $status2"
#else
#    echo "$service is not running and disabled"
#    exit 3
#fi
#exit 0

案例22:检查磁盘分区的情况

22_check_disk.sh
下载
#!/bin/bash
##########################################
# File Name:22_check_disk.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查磁盘分区情况1.有几个分区2.每个分区使用率,超过70%显示磁盘空间不足,没超过显示异常
###########################################
#1.vars
#分区数量
part_cnt=`egrep -v '^$|#|swap' /etc/fstab | wc -l`
#分区名字
part_names=`egrep -v '^$|#|swap' /etc/fstab | awk '{print $2}'`

#2.for 循环依次处理
for part  in $part_names
do
	size=`df -h $part | awk 'NR==2{print $2}'`
	uselv=`df -h $part | awk -F '[ %]+' 'NR==2{print $5}'`
	if [ "$uselv" -le 70 ]  ;then
	echo "$part 磁盘大小:$size,使用率: $uselv%,空间正常"
else
	echo "$part 磁盘大小:$size,使用率: $uselv%,空间不足!!!"
	let i++
	fi
done
echo "磁盘分区数量:$part_cnt"
echo "磁盘分区空间不足分区数量: ${i:-0}"

案例23:书写多分支格式比较大小脚本

23_num_compare.sh
下载
#!/bin/bash
##########################################
# File Name:23_num_compare.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:多分支格式比较两个数字大小
###########################################
#1.vars
read -p "请输入两个数字进行比较大小: " num1 num2
#2.判断输入是否为空
if [ -z $num1 ] || [ -z $num2 ]
then
	echo "Help: sh $0 num1 num2"
	exit 1
fi
#3.判断输入是否为数字
# expr 1 + $num1 + num2 &>/dev/null
#if [ $? -ge 2 ]
#	echo "请输入数字 格式:sh $0 num1 num2"
#	exit 2
#fi
#字符串比较是否为数字(繁琐)
if [[ ! $num1 =~ ^[+-]?[0-9]+(\.[0-9]+)?$ ]] || [[ ! $num2 =~ ^[+-]?[0-9]+(\.[0-9]+)?$ ]]
then
	echo "请输入数字 格式:sh $0 num1 num2"
	exit 2
fi

#4.比较大小
if [ $num1 -gt $num2 ];then
	echo "$num1 > $num2"
elif [ $num1 -lt $num2 ];then
	echo "$num1 < $num2"
else
	echo "$num1 == $num2"
fi

案例24:根据磁盘空间不同使用率设置不同的警告提示

24_check_disk.sh
下载
#!/bin/bash
##########################################
# File Name:22_check_disk.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:检查磁盘分区情况1.有几个分区2.每个分区使用率,根据不同使用率设置不同的警告提示
###########################################
#1.vars
#分区数量
part_cnt=`egrep -v '^$|#|swap' /etc/fstab | wc -l`
#分区名字
part_names=`egrep -v '^$|#|swap' /etc/fstab | awk '{print $2}'`


#2.for 循环依次处理
for part  in $part_names
do
	size=`df -h $part | awk 'NR==2{print $2}'`
	uselv=`df -h $part | awk -F '[ %]+' 'NR==2{print $5}'`
#根据不同使用率设置不同的警告提示
if [ $uselv -ge 60 ] && [ $uselv -le 70 ]
then
	msg="警告"
	let i++
elif [ $uselv -ge 70 ] && [ $uselv -le 80 ];then
	msg="严重"
	let i++	
elif [ $uselv -ge 80 ] && [ $uselv -le 90 ];then
	msg="故障"
	let i++
elif [ $uselv -ge 90 ] && [ $uselv -le 100 ];then
	msg="灾难"
	let i++
else
	msg="磁盘空间充足,利用率为 $uselv"
fi
echo "$part 大小:$size $msg%"

done
echo "磁盘分区数量:$part_cnt"
echo "磁盘空间不足分区数量:${i:-0}"

案例25:输出指定用户信息(用户巡检脚本),未来可以做安全检查

25_check_user.sh
下载
#!/bin/bash
##########################################
# File Name:25_check_user.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:用户巡检脚本,检查用户信息
###########################################

#一次检查一个用户
#1.vars
#read -p "请输入用户名:" user
#2.check -z
#[ -z $user ] && echo "Help: sh $0 username" && exit 1;
#3.check 输入的是否为用户名(用户是否存在)
#id $user &>/dev/null
#if [ $? -ne  0 ]
#then
#	echo "用户不存在"
#	exit 2
#fi
#


#一次检查多个用户
# 提示用户输入用户名(支持多个,空格分隔)
read -p "请输入要检查的用户名(多个用户名用空格分隔):" input_names

# 检查输入是否为空
if [[ -z "$input_names" ]]; then
    echo "错误:未提供任何用户名。" >&2
    exit 1
fi
# 将输入转换为数组(兼容多个空格/制表符分隔)
names=($(echo "$input_names" | tr -s ' '))  # tr -s ' ' 压缩连续空格
#1.vars
names=("$@")  # 声明为数组
# 检查参数数量
if [ $# -eq 0 ]; then
    echo "错误:请提供至少一个用户名作为参数。"
    echo "用法:bash $0 用户名1 用户名2 ..."
    exit 1
fi

for name in "${names[@]}"; do  # 正确遍历数组
    if id "${name}" &>/dev/null; then
        echo "用户 ${name} 存在。"
        # 获取用户信息
        passwd_entry=$(getent passwd "${name}")
        perm=$(awk -F: '{print $NF}' <<<"$passwd_entry")
        [[ "$perm" == "/bin/bash" || "$perm" == "/bin/zsh" ]] && login="可以登录" || login="不可以登录"
        uid=$(id -u "${name}")
        gid=$(id -g "${name}")
        homedir=$(awk -F: '{print $(NF-1)}' <<<"$passwd_entry")
        situation=$(lastlog -u "${name}")

        # 输出用户信息
	echo "正在检查用户:$name"
echo "----------------------------------------"
        cat <<EOF
用户 ${name} 的详细信息:
- 登录权限:${login}
- UID:${uid}
- GID:${gid}
- 家目录:${homedir}
- 最近登录情况:
${situation}
EOF
echo "========================================"
    else
        echo "错误:用户 ${name} 不存在。"
    fi
done

案例26:case语句格式–菜单选择功能

26_taocan.sh
下载
#!/bin/bash
##########################################
# File Name:26_taocan.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例26:case语句格式–菜单选择功能
###########################################
#1.输出信息供用户选择
cat <<EOF
- 1 138套餐) 吃饱套餐
- 2 443套餐) 吃饱喝足套餐
- 3 888套餐) 吃喝拉撒套餐
- 4 1688套餐) 你想干啥就干啥套餐
EOF
read -p "请选择套餐: " taocan
case "$taocan" in
	1)
		echo "in 1"
		;;
	2)echo "in 2" ;;
	3)echo "in 3" ;;
	4)echo "in 4" ;;
	5)echo "in 5" ;;
	*)echo "error pls run again"
esac

案例27:判断用户输入的是yes还是no(选项中| 的使用)

27_yes_no.sh
下载
#!/bin/bash
##########################################
# File Name:27_yes_no.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例27:判断用户输入的是yes还是no(case菜单选项中| 的使用)
###########################################
read -p "please input yes or no: " yesno
case "$yesno" in
#)前可以用|分割多个同义词,结果都指向)后执行的操作
	yes|Yes|y|Y) echo yes;;
	no|n|N|No) echo no;;
	*) echo ???
esac

案例28:函数基本格式及使用

28_test_func.sh
下载
#!/bin/bash
##########################################
# File Name:28_test_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例28:函数基本格式及使用
###########################################
function show() {
echo "welcome to oldboy linux lidao996 class"
echo "你的目标:拿下15k offer"
echo "你的目标:拿下100+ shell脚本"
echo "你的目标:书写总共超过5000行脚本。"
return 0
}
show
#这行表示运行上面刚定义的show函数,作用同下面这种
#function main(){
#    show
#}
#main

案例29:函数传参的使用

29_show_test.sh
下载
#!/bin/bash
##########################################
# File Name:29_show_test.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例29:函数传参的使用
###########################################
function show() {
cat <<EOF
show函数的参数个数:$#
show函数的所有参数:$*
$1.com
$1.cn
$1.org
$1.企业
$1.icu
$1.我爱你
EOF
}
show $*
#使用方法:运行脚本时 sh 29_show_test.sh a b c d e
#命令行传参到函数外部show $* 函数内部$n调用此参数
#显示如下:
#show函数的参数个数:5
#show函数的所有参数:a b c d e
#a.com
#a.cn
#a.org
#a.企业
#a.icu
#a.我爱你

案例30:已有脚本函数化:检查ip是否能访问,将每一步设置为一个函数

30_check_ip_func.sh
下载
#!/bin/bash
##########################################
# File Name:10_ping_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例30:已有脚本函数化
###########################################


#1.vars:
function input_urls(){
read  -p "please input domains: " urls
}
#2.检查参数是否为空
function check_urls(){

if [ -z "$urls" ];then
	echo "Help: sh $0 ip/domains"
	exit 1
fi
}
#2.执行ping命令并判断返回值检测此域名是否能ping通
function ping_if(){
	ping -c1 ${url} &>/dev/null
	if [ $? -eq 0 ]
	then
		echo "${url} is yes"
	else
		echo "${url} is no"
	fi
}
#3.for
function for_urls(){
for url in ${urls}
do
	ping_if
done
return 0
}

#4.运行上面的函数
function main(){
input_urls
check_urls
for_urls
}
main

案例31:个人颜色函数库搭建,不同显示效果用不同的函数表示

31_color_func.sh
下载
#!/bin/bash
##########################################
# File Name:31_color_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例31:个人颜色函数库搭建,不同显示效果用不同的函数表示
###########################################
function redecho(){
	input="$@"
	echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
	input="$@"
	echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
	input="$@"
	echo -e "\E[1;36m${input}\E[0m"
}
function yellowecho(){
	input="$@"
	echo -e "\E[1;33m${input}\E[0m"
}

function redstrongecho(){
	input="$@"
	echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
	input="$@"
	echo -e "\E[1;42m${input}\E[0m"
}

#以下为测试,使用时redecho "内容"
	redecho 1
	greenecho 1
	yellowecho 1
	blueecho 1
	redstrongecho 1
	greenstrongecho 1

案例32:给个人颜色函数库脚本中加入日志方便以后调用

32_func_diy.sh
下载
#!/bin/bash
##########################################
# File Name:/funcs/func_diy.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例32:给个人颜色函数库脚本中加入日志方便以后调用:
###########################################
#1.颜色函数
function redecho(){
        input="$@"
        echo -e "\E[1;31m${input}\E[0m"
}
function greenecho(){
        input="$@"
        echo -e "\E[1;32m${input}\E[0m"
}
function blueecho(){
        input="$@"
        echo -e "\E[1;36m${input}\E[0m"
}
function yellowecho(){
        input="$@"
        echo -e "\E[1;33m${input}\E[0m"
}
function redstrongecho(){
        input="$@"
        echo -e "\E[1;41m${input}\E[0m"
}
function greenstrongecho(){
        input="$@"
        echo -e "\E[1;42m${input}\E[0m"
}
#2.日志函数
function log() {
  log_file=$0.log
  level=$1
  msg=$2
  time=$(date +%F_%T)
  echo "$time [${level}] ${msg}" >> $log_file
}

案例33:检查指定地址的端口是否可以访问

33_check_port.sh
下载
#!/bin/bash
##########################################
# File Name:check_port.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例33:检查指定地址的端口是否可以访问
#use color funcs
source /funcs/func_diy.sh
###########################################
#1.vars
ip=$1
port=$2
#2.检查参数数量是否为2(ip+端口)
#这一步涉及到传参所以需要在主函数里加上$@
num_part(){
if [ $# -ne 2 ];then
redecho "Help: sh $0 IP PORT  "
exit 1
fi
}

#检查nc/telnet命令是否存在,不存在则安装
use_yum(){
if ! which nc &>/dev/null ;then
yum install -y nc &>/dev/null
fi
#yum install -y telnet &>/dev/null
}

#使用ping命令检查到目标ip之间是否通路
use_ping(){
if ! ping -c1 $ip &>/dev/null ;then
	redecho "this ip connect failed!"
	exit 2
fi
}
#检查端口格式(必须为数字)
check_port(){
if [[ ! $port =~ ^[0-9]+$ ]];then
	redecho "port $port is not exist! pls input number(1-65535) "
	exit 3
fi
}
#3.执行nc命令检查端口连接
use_nc(){
if nc -z ${ip} ${port} ;then
	greenecho "success! $ip $port is open"
else
	redecho "failed! $ip $port is closed "
fi
}


function main(){
num_part "$@"
use_yum
use_ping
check_port
use_nc
}
main "$@"

案例34:检查指定web/api是否可以访问

34_check_url.sh
下载
#!/bin/bash
##########################################
# File Name:34_check_url.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例34:检查指定web/api是否可以访问
#color func
source /funcs/func_diy.sh
###########################################
#1.vars
url=$1

#2.检查参数个数是否为1(空也退出)
check_var(){
if [ $# -ne 1 ]
then
	redecho "help: sh $0 xxx.com "
	exit 1
fi
}
#检查系统中是否有curl命令
yum_curl(){
if  ! which curl &>/dev/null ;then
	yum install -y curl &>/dev/null
fi
}

#检查到目标网站之间线路是否通畅
check_net(){
if ! ping -c1 $url &>/dev/null ;then
	echo "net connection failed! or $url is not exist! "
	exit 2
fi
}
#check [[ =~ ]] .com  可以加一步用正则匹配输入的是否为网站(xxx.com等格式)
#使用curl命令检查是否可以访问
check_url(){
if curl -s $url &>/dev/null ;then
	greenecho "$url  can see! "
else
	redecho "$url see failed! "
fi
}
main(){
check_var "$@"
yum_curl
check_net
check_url
}
main "$@"

案例35:检查域名是否过期

35_check_web_date.sh
下载
#!/bin/bash
##########################################
# File Name:35_check_web_date.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例35:检查域名是否过期 
#func
source /funcs/func_diy.sh
###########################################
#1 vars
#url=linuxjk.cn
#用下面的whois命令取出域名过期时间
# whois linuxjk.cn | egrep -i "(expiry date)|(expiration time)" | awk '{print $(NF-1),$NF}'
export LANG=en_US.UTF-8
url="$1"
if [ -z "$url" ]; then
  read -p "请输入域名(如 xxx.com): " url
fi
#2.检查参数是否为空
if [ -z "$url" ];then
	redecho "Help: sh $0 *.com/cn..."
	exit 1
fi
#取出当前的日期和域名过期日期
date_now=$(date "+%F %T")
date_check=$(whois "$url" 2>/dev/null | egrep -i "(expiry date)|(expiration time)" | awk -F'e: ' '{print $NF}')
if [ -z "$date_check" ]; then
  redecho "无法获取域名 $url 的到期时间"
  exit 2
fi
#3.用date +%s -d将两个日期都转化为秒
date_now_second=$(date +%s -d "$date_now")
date_check_second=$(date +%s -d "$date_check")

#4.测试是否成功转化为秒,此处如果有负数或空值说明转化失败
#echo $date_now_second
#echo $date_check_second


#5.用 awk/bc计算两个日期之间的差值(单位秒)
diff_second=$(awk -v a=$date_now_second -v b=$date_check_second 'BEGIN{print b-a}')
#6.差值转化为天
diff_day=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24}')
diff_month=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24/30}')
diff_year=$(awk -v a=$diff_second 'BEGIN{print a/60/60/24/30/12}')
#7.输出信息
#echo "$url have $diff_day day, =$diff_month month, = $diff_year year"
#if [ $diff_day -ge 60 ];then
if (( $(echo "$diff_day >= 60" | bc -l) )); then
	greenecho "域名$url  还有$diff_day 天到期, 还有 $diff_month月到期, 还有$diff_year年到期"
else
	redecho "请及时续费;"
	redecho "域名$url  还有$diff_day 天到期, 还有 $diff_month月到期, 还有$diff_year年到期"
fi

案例36:使用for循环在/oldboy目录下通过随机的10个小写字母加固定字符oldboy批量创建十个html文件

36_random_file.sh
下载
#!/bin/bash
##########################################
# File Name:36_random_file.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例36:使用for循环在/oldboy目录下通过随的10个小写字母加固定字符oldboy批量创建十个html文件
###########################################
#1.vars
fixed=linux
dir=/oldboy/
#检查目录是否为空,为空则创建
if [ ! -d ${dir} ];then
	mkdir -p $dir
fi
#2.run for
for i in {1..10}
do
#利用两种方法取出10个随机小写字母
file=$(mkpasswd-expect -l 10 -d 0 -s 0 -C 0 )
  #file=$(tr -cd 'a-zA-Z0-9' </dev/urandom | head -c10)
  touch ${dir}${file}_${fixed}.html
done

用for循环打印99乘法表

99.sh
下载
#!/bin/bash
##########################################
# File Name:99.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:利用简单的for循环打印九九乘法表
###########################################
#vars
i=1
j=1

for i in {1..9}
do
	for j in {1..9}
	do
		#printf "%d*%d=%-2d " $i $j $((i*j))
		result=`echo -n "$i*$j"|xargs |bc`
		echo -n "$i*$j=$result "
	done
	echo 
done

案例37:输出1到10并计算总和(条件:循环次数等于10)

37_while_for.sh
下载
#!/bin/bash
##########################################
# File Name:37_while_for.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例37:输出1到10并计算总和(条件:循环次数等于10)
###########################################
#vars
i=1
sum=0
#循环执行条件:i<=10,不满足则结束循环
while [ $i -le 10 ]
do
	echo $i
	let sum=sum+i
	let i++  #控制循环次数
done

echo "总和: $sum"

#for i in {1..10}
#do
#echo $i
#done

案例39:生成随机数字(1-100),判断数字是什么

39_guess_number.sh
下载
#!/bin/bash
##########################################
# File Name:39_guess_number.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例39:生成随机数字(1-100),判断数字是什么
###########################################
#vars
correct_answer=$(echo "$RANDOM%100+1" | bc)
guess=0
#可以用while后面的条件控制循环,当满足猜的数不等于正确答案时进行循环
#while [ $guess -ne $correct_answer ];
#或者用下面的死循环表示,while true,但是当猜的数等于正确答案时输出信息并退出脚本
while true
do
	#read
	read -p "pls input a number: " guess
	#check input ? number
	if  [[ ! $guess =~ [0-9]+ ]];then
		echo "please input number! "
		#continue只跳过这一次输入错误的情况,重新输入,break退出循环,exit退出脚本
		continue
	fi
	let i++
	if [ $guess -lt $correct_answer ];then
		echo "your number is small "
	elif [ $guess -gt $correct_answer ];then
		echo "your number is big "
	else
		echo "correct !!! answer is $correct_answer"
		echo "total guess $i times"
		#下面的exit退出脚本可以改为在这里用break退出循环,下面的判断和输出放在循环外执行
	if [ $i -ge 1 ] && [ $i -le 3 ] ;then	
		echo "better than 99.99% person "
	elif [ $i -ge 4 ] && [ $i -le 6 ];then
		echo "better than 80% person "
	else 
		echo "better than 70% person "
	fi
	exit
	fi	
done

案例40:通过while read方式统计ip.txt文件,并ping文件中的ip(以后ping改成firewalld屏蔽)

40_while_ip_ping.sh
下载
#!/bin/bash
##########################################
# File Name:40_while_ip_ping.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例40:通过while read方式统计ip.txt文件,并ping文件中的ip(以后ping改成firewalld屏蔽)
#funcs
source /funcs/func_diy.sh
###########################################
#vars
src_file=/oldboy/files/ip.txt
#while
while read line
do
	ip=`echo $line | awk -F' ' '{print $1}'`
	num=`echo $line | awk -F' ' '{print $2}'`
       if [ $num -ge 5 ];then
	       ping -c1 $ip &>/dev/null
	       if [ $? -eq 0 ];then
		       greenecho "ping $ip successed"
	       else
		       redecho "ping $ip failed"
	       fi
       fi 

done <$src_file
#while read ip num  只有空格分隔的两列可以这样只定义两个变量,如本案例中的ip 次数
#do
#       #echo "ip address: $ip"
#       if [ $num -ge 8 ];then
#	       ping -c1 $ip &>/dev/null
#       fi 
#done <$src_file

案例41:了解方法2和方法3区别:在while前读取命令和在done后用重定向符<读取文件

41_test_while_read.sh
下载
#!/bin/bash
##########################################
# File Name:41_test_while_read.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:了解方法2和方法3区别:在while前读取命令和在done后用重定向符<读取文件
###########################################
#vars
file=/oldboy/files/ip.txt

i=0
j=0
#方法2,利用管道传递,while处理管道内容,循环次数为0
echo "method 2: while + cat"
cat $file | while read ip 
do
	echo $ip
	let i++
done
echo "times: $i"


#方法3,用输入重定向<输入至while中,循环次数为文件行数
echo "method 3: while + <"
while read ipaddr
do
       echo $ipaddr
       let j++
done <$file
echo "times: $j"

案例41:for/while/ until三种循环格式区别及循环条件分析

41_do_until.sh
下载
#!/bin/bash
##########################################
# File Name:do_until.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例41:for/while/ until三种循环格式区别及循环条件分析
###########################################
#vars

echo "until"
#直到变量i大于10时停止,输出1-10
i=1
until [ $i -gt 10 ]
do
	echo $i
	let i++
done
echo "while"
#满足变量j小于等于10的条件时循环,输出1-10
j=1
while [ $j -le 10 ]
do
	echo $j
	let j++
done
echo "for"
#变量m在1-10的范围内进行循环,输出1-10
for m in {1..10}
do
	echo $m
done

案例42:测试read命令赋值数组并输出数组中的内容

42_read_create_array.sh
下载
#!/bin/bash
##########################################
# File Name:42_read_create_array.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例42:测试read赋值数组并输出数组中的内容
###########################################
#定义数组变量
read -p "请输入数组,空格分隔: " -a array
#测试刚才输入的数组是否可以正常输出
echo ${array[@]}
#测试分割情况(是否一次输出一个)
for i in  ${array[@]}
do
	echo $i
done

案例43:试编写一个shell计算器,求出用户输入所有数字的以下计算结果:总和,平均值,最大值,最小值

43_array_calculate.sh
下载
#!/bin/bash
##########################################
# File Name:43_array_calculate.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例43:求出数组中的值的总和,平均值,最大值,最小值
source /funcs/func_diy.sh
###########################################

#1.vars
function input(){
read -p "请输入需要计算的数字,以空格分割,不限制个数:  " -a array
}

#2.检查数组是否为空
function check_z(){
if [ -z $array ];then
	redecho "未获取到内容,请重新输入! "
	exit 1
fi
}

#易错提示:检查输入的数组是否为数字
#(错误,这里的正则匹配会将整个数组合成一个整体的字符串进行正则匹配,
#无法逐个检测数组中的元素是否为数字)
#if [[ ! ${array[@]} =~ ^[+-]?[0-9]+\.?[0-9]+$ ]];then
#	echo "格式错误,请输入数字! "
#	exit 2
#fi

#下面的错误为如果碰到异常数据会直接退出脚本,不会继续运算
#function check_isnumber(){
#for num in "${array[@]}"
#do
#    # 允许整数、小数、负数,排除空值
#    if [[ ! $num =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] || [[ $num == '.'* ]] || [[ $num == *'.' ]]; then
#        redecho "错误:'$num' 不是有效的数字!"
#        exit 2
#
#    fi
#done
#}

#3.检查数组中的每个值是否为数字,如果有不是数字的进行提示并跳过这一项,继续进行下面的值的计算,
#得到一个过滤异常数据之后的新数组
i=0
#从下标0开始传入数据
function check_isnumber(){
for num in "${array[@]}"
do
	if [[ ! $num =~ ^[+-]?[0-9]+([.][0-9]+)?$ ]] || [[ $num == '.'* ]] || [[ $num == *'.' ]]; then
		redecho "错误!$num 不是有效的数字,此项无法参与运算"
		continue
	else
		newarray[i]=$num
		let i++
	fi
done
}
echo ${newarray[@]}
#4.开始计算
function  calculate(){
total=$(echo ${newarray[@]} | tr -s ' ' '+' |bc -l)
averavg=$(awk -v a=${total} -v b=${#newarray[@]} 'BEGIN{print a/b}')
max=$(echo ${newarray[@]} | sed 's# #\n#g' | sort -rn | head -n1)
min=$(echo ${newarray[@]} | sed 's# #\n#g' | sort -n | head -n1)
}

#5.输出结果
function output(){
cat<<EOF
数组中的值的计算结果如下:
总和:$total
平均值:$averavg
最大值:$max
最小值:$min
EOF
}


function main(){
	input "$@"
	check_z
	check_isnumber
	calculate
	output
}
main

案例44:把案例30改为数组形式,从server/files/urls.txt读取内容

44_check_ip_func.sh
下载
#!/bin/bash
##########################################
# File Name:42_check_ip_func.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:案例42:将案例30改为数组形式,从指定文件/server/files/urls.txt读取内容
#cat /server/files/urls.txt
#10.0.0.200
#jd.com
#baidu.com
#taobao.com
#linuxjk.cn
#12306.cn
source /funcs/func_diy.sh
###########################################


#1.vars:
function input_urls(){
urls=(`cat /server/files/urls.txt`)
}
#2.检查参数个数是否为0(是否为空),数组用于检查是否为空时可以和变量用法相同

function check_urls(){

if [ -z $urls ];then
	echo "error"
	exit 1
fi

#if [ ${#urls[@]} -eq 0 ];then
#	echo "Help: 未取出正确的url供本脚本检测,请检查脚本! "
#	exit 1
#fi
}
#2.执行ping命令并判断返回值检测此域名是否能ping通
function ping_if(){
	ping -c1 ${url} &>/dev/null
	if [ $? -eq 0 ]
	then
		greenecho "$url 可以访问"
	else
		redecho "$url 不可以访问"
	fi
}
#3.for
function for_urls(){
for url in ${urls[@]}
do
	ping_if
done
return 0
}

#4.运行上面的函数
function main(){
input_urls
check_urls
for_urls
}
main

案例53:用awk统计ip和每个ip对应的流量,取流量排行前50名进行地址查询和单位换算

53_uniq_ip_times.sh
下载
#!/bin/bash
##########################################
# File Name: 53_uniq_ip_times.sh
# Version:V1.0
# Author:zhangpeng
# 0rganization:linuxjk.cn
# Desc:用awk统计ip和每个ip对应的流量,取流量排行前50名进行地址查询和单位换算
###########################################

#1.vars
file=/server/files/access.log
awk_deal=(`awk '{url[$1]=url[$1]+$10}END{for(n in url)print n,url[n]}' $file | sort -rnk2 | head -50`)
count=0
for i in ${awk_deal[@]}
do
        if (( count % 2 == 0 ));then
                echo -n "ipaddress: $i   "
                echo `curl -s cip.cc/${i} | sed -n '2p'`
                sleep 1.5
        else
                echo -n `awk -v a=$i 'BEGIN{print a/1000/1000}'`
                echo " MB"
        fi
        let count++
done
滚动至顶部