7 very practical Shell script examples!

Posted by alecapone on Sun, 16 Jan 2022 01:39:14 +0100

The day before yesterday, I saw a reader sharing several Shell script example topics in the group. I simply saw them. Why not write and consolidate the basic knowledge, as follows:

1. Concurrently obtain the hostname from several machines, record the time spent returning the information, and redirect to a file hostname Txt, output the CPU information of the machine that takes the shortest time after all is completed.

#!bin/bash  


# Therefore, the host is separated by spaces
ALL_HOSTS=(IP address IP address)

for host in ${ALL_HOSTS[*]}
do
{
    start_time=$(date +'%s')
    ssh $host "hostname" &>/dev/null
    sleep 2
    stop_time=$(date +'%s')
    time_consuming=$((stop_time-start_time))
    echo "$host: $time_consuming" >>hostname.txt
}&
done

wait

host=$(sort -n -k 2 hostname.txt | head -1 | awk -F':' '{print $1}')

ssh $host "top -b -n 1"

2. Count the number of Linux processes under the / proc category, and output the total number of processes, running processes, stopped processes, sleeping processes and zombie processes.

Output all zombie processes to zombie Txt kills all zombie processes.

#!/bin/bash

ALL_PROCESS=$(ls /proc/ | egrep '[0-9]+')

running_count=0
stoped_count=0
sleeping_count=0
zombie_count=0

for pid in ${ALL_PROCESS[*]}
do
    test -f /proc/$pid/status && state=$(egrep "State" /proc/$pid/status | awk '{print $2}')
    case "$state" in
        R)
            running_count=$((running_count+1))
        ;;
        T)
            stoped_count=$((stoped_count+1))
        ;;
        S)
            sleeping_count=$((sleeping_count+1))
        ;;
        Z)
            zombie_count=$((zombie_count+1))
            echo "$pid" >>zombie.txt
            kill -9 "$pid"
        ;;
    esac
done


echo -e "total: $((running_count+stoped_count+sleeping_count+zombie_count))\nrunning: $running_count\nstoped: $stoped_count\nsleeping: $sleeping_count\nzombie: $zombie_count"

3. Change the suffix of all files with ". sh" suffix in the current directory (including subdirectories) to ". shell", and then delete the second line of each file.

#!/bin/bash


ALL_SH_FILE=$(find . -type f -name "*.sh")
for file in ${ALL_SH_FILE[*]}
do
    filename=$(echo $file | awk -F'.sh' '{print $1}')
    new_filename="${filename}.shell"
    mv "$file" "$new_filename"
    sed -i '2d' "$new_filename"
done

4. Judge whether the directory / tmp/jstack exists. If it does not exist, create a new directory. If it does exist, delete all contents under the directory.

Print the jstack information of the acceptor server every 1 hour and print it in jstack_$ {current time} name the file, and delete the oldest file whenever there are more than 10 files in the directory.

#!/bin/bash


DIRPATH='/tmp/jstack'
CURRENT_TIME=$(date +'%F'-'%H:%M:%S')

if [ ! -d "$DIRPATH" ];then
    mkdir "$DIRPATH"
else
    rm -rf "$DIRPATH"/*
fi

cd "$DIRPATH"

while true
do
    sleep 3600
    # Here, you need to change the inceptor to its own java process name
    pid=$(ps -ef | grep 'inceptor' | grep -v grep | awk '{print $2}')
    jstack $pid >> "jstack_${CURRENT_TIME}"
    dir_count=$(ls | wc -l)
    if [ "$dir_count" -gt 10 ];then
       rm -f $(ls -tr | head -1)
    fi
done

5. From test Log intercepts all the gc information logs of the day, and counts the average gc time and the longest gc time.

#!/bin/bash

awk '{print $2}' hive-server2.log | tr -d ':' | awk '{sum+=$1} END {print "avg: ", sum/NR}' >>capture_hive_log.log
awk '{print $2}' hive-server2.log | tr -d ':' | awk '{max = 0} {if ($1+0 > max+0) max=$1} END {print "Max: ", max}'>>capture_hive_log.log

6. Find the top 20 IP addresses with the highest number of requests on port 80, and judge whether the minimum number of requests in the middle is greater than 500. If it is greater than 500, output the system activity report to alert Txt, if not, retry after 600s until there is output.

#!/bin/bash


state="true"

while $state
do
    SMALL_REQUESTS=$(netstat -ant | awk -F'[ :]+' '/:22/{count[$4]++} END {for(ip in count) print count[ip]}' | sort -n | head -20 | head -1)
    if [ "$SMALL_REQUESTS" -gt 500 ];then
        sar -A > alert.txt
        state="false"
    else
        sleep 6
        continue
    fi
done    

7. Transfer the files larger than 10K in the current directory to the / tmp directory, and then output the file name from large to small in the order of file size.

#!/bin/bash


# Target directory
DIRPATH='/tmp'
# View directory
FILEPATH='.'

find "$FILEPATH" -size +10k -type f | xargs -i mv {} "$DIRPATH"
ls -lS "$DIRPATH" | awk '{if(NR>1) print $NF}'

The above is the seven practical Shell script cases shared today.

I hope you can apply what you have learned through these cases and apply it in combination with your own actual scenes, so as to improve your work efficiency.

— EOF —

Topics: Linux shell bash script