1. Idea: put the program in the background to execute, and then execute wait, so that you can wait for a serial execution task
Take backup Linux directory as an example, rsync is executed in the background, $! indicates the PID of the latest background, wait command is followed by pid, wait for the pid program to finish executing before continuing, otherwise the main program hangs
The wait command shell
suspends the current process and waits for the specified shell
child process to exit before the wait
command returns
The rsync command is used for copying or file backup, a archive mode, A retains the original ACL, X retains the original attributes z transmission compression --delete keeps the file version up to date
#!/bin/bash backupdir='/root /usr/local /var/log /var/named /boot /etc /var/spool' destination='/home/backup/linux' for dir in $backupdir; do rsync -avAXz --log-file=/home/logs/backupLinux.log $dir $destination --exclude="lost+found" --delete &>/dev/null & wait $! done
2. Find Active Users
The idea is to use the successful login user, rsyslogd will record the user login information to /var/log/wtmp and use the last command to read it, and then extract it with awk
last -f $log read a specific log, so read an earlier log
last -f /var/log/wtmp.1
head -n -2 means that except for the last two lines, the rest of the lines are read, so the rest is all user login information
Extract filter all users redirect to /tmp/users.$$ $$ represents the pid of the script
Parentheses denote subroutine blocks, with two levels of while loops inside.
The first while loop takes /tmp/users.$$ as input and reads the user on each line
while read user;
After reading the user, find the line containing the user in /tmp/log.$$, and then count the number of times, the usage time, and the initial login time
Statistics
nlogins=`cat /tmp/user.$$ | wc -l`
The initial login time, directly read the last line
firstlog=`tail -n 1 /tmp/user.$$ | awk '{print $5,$6}'`
Use time, this while loop time input is the answer I found from the Internet, I don't understand it, ask for advice "< <(cat /tmp/user.$$ | awk '{print $NF}' | tr -d ')( ' | grep '[0-9]' | tr '+' ':')”
while read t do s=`echo $t | awk -F: '{if (NF==3){print($1*60*24+$2*60+$3)}else{print($1*60+$2)}}'` let minutes=minutes+s done< <(cat /tmp/user.$$ | awk '{print $NF}' | tr -d ')(' | grep '[0-9]' | tr '+' ':')
Since more than 24 hours, last will display 1+ format, all awk should judge whether it is more than one day
awk: NR represents the row number, $0 represents the entire row content, NF represents the column number
1 #!/bin/ bash 2 # Use to find active users 3 # 4 5 log=/var/log/ wtmp 6 7 printf " %-4s %-10s %-10s %-6s %-8s\n " " Rank " " User " " Start " " Logins " " Usage_hours " 8 9 last -f $log | head -n - 2 > /tmp/ulog.$$ 10 11 cat /tmp/ulog.$$ | cut -d ' ' -f1 | sort | uniq>/tmp/users.$$ 12 13 ( 14 while read user; 15 do 16 grep ^$user /tmp/ulog.$$ > /tmp/user.$$ 17 minutes=0 18 19 while read t 20 do 21 s=`echo $t | awk -F: '{if (NF==3){print($1*60*24+$2*60+$3)}else{print($1*60+$2)}}'` 22 let minutes=minutes+s 23 done< <(cat /tmp/user.$$ | awk '{print $NF}' | tr -d ')(' | grep '[0-9]' | tr '+' ':') 24 25 firstlog=`tail -n 1 /tmp/user.$$ | awk '{print $5,$6}'` 26 nlogins=`cat /tmp/user.$$ | wc -l` 27 hours=`echo "$minutes /60.0" | bc` 28 printf "%-10s %-10s %-6s %-8s\n" $user "$firstlog" $nlogins $hours 29 done< /tmp/users.$$ 30 ) | sort -nrk 4 | awk '{printf("%-4s %s\n",NR,$0)}' 31 32 rm -f /tmp/users.$$ /tmp/user.$$ /tmp/ulog.$$