《Linux 命令行与 shell 脚本编程大全》
文章目录
- 1. 编写简单的脚本实用工具
- 1.1 自动备份
- 1.1.1 按日备份
- 1.1.2 按小时归档
- 1.2 管理用户账户
- 1.3 检测磁盘空间
- 2. 电子邮件脚本
- 3. 一些小有意思的脚本
- 3.1 发送消息
- 3.2 获取格言
- 3.3 编造借口
1. 编写简单的脚本实用工具
1.1 自动备份
1.1.1 按日备份
可以借助配置文件,将需要备份的目录列出:
jiaming@jiaming-VirtualBox:~/Documents$ cat ./archive/Files_To_Backup
/home/jiaming/Documents/emaillist.txt
/home/jiaming/Desktop/vim/tags
jiaming@jiaming-VirtualBox:~/Documents$ cat Daily_archive.sh
# gather current date
DATE=$(date +%y%m%d)
# set archive file name
FILE=archive$DATE.tar.gz
# set configuration and destination file
CONFIG_FILE=~/Documents/archive/Files_To_Backup
DESTINATION=~/Documents/archive/$FILE
# check backup config file exists
if [ -f $CONFIG_FILE ]
then
echo
else
echo
echo "$CONFIG_FILE does not exit."
echo "Backup not completed due to missing configuration file."
echo
exit
fi
# buile the names of all the files to backup
FILE_NO=1 # start on line 1 of config file
exec < $CONFIG_FILE # redirect std input to name of config file
read FILE_NAME
while [ $? -eq 0 ]
do
# make sure the file or directory exits.
if [ -f $FILE_NAME -o -d $FILE_NAME ]
then
# if file exits, add its name to the list.
FILE_LIST="$FILE_LIST $FILE_NAME"
else
# if file doesn't exit, issue warning
echo
echo "$FILE_NAME, doesn't not exit."
echo "Obviously, I will not include it in this archive."
echo "It is listed on line $FILE_NO of the config file."
echo "Continuing to build archive list..."
echo
fi
FILE_NO=$[$FILE_NO + 1] # increase line/file number by one.
read FILE_NAME # read next record
done
echo "Starting archive..."
echo
tar -czf $DESTINATION $FILE_LIST 2> /dev/null
echo "Archive completed"
echo "Resulting archive file is: $DESTINATION"
echo
exit
1.1.2 按小时归档
不必将所有归档文件都放到同一目录中,可以为归档文件创建一个目录层级。月的序号作为目录名,每月的目录中又包含了当月各天对应的目录。
base
month 01
day 01
day 02
month 02
CONFIG_FILE=~/Documents/archive/hourly/Files_To_Backup
BASEDEST=~/Documents/archive/hourly
DAY=$(date +%d)
MONTH=$(date +%m)
TIME=$(date +%k0%M)
mdkir -p $BASEDEST/$MONTH/$DAY
DESTINATION=$BASEDEST/$MONTH/$DAY/archive$TIME.tar.gz
# ...
1.2 管理用户账户
删除账户的四个步骤:
- 获得正确的待删除用户账户名;
- 杀死正在系统上运行的属于该账户的进程;
- 确认系统中属于该账户的所有文件;
- 删除该用户账户;
jiaming@jiaming-VirtualBox:~/Documents$ bash Delete_User.sh
Step #1 - Determine User Account name to Delete
Please enter the username of the user
account you wish to delete from system: user008
Is user008 the user account
you wish to delete from the system? [y/n] y
I found this record:
user008:x:1008:1008::/home/aoko:/bin/bash
Is this the correctrrect User Account [y/n] y
Step #2 - Find process on system belonging to user account
There are no processes for this account currently running.
Step #3 - Find files on system belonging to user account
Creating a report of all files owned by user008
It is recommended that you backup/archive these files,
and then do one of two things:
1) Delete the files
2) Change the files' ownership to a current user account.
Please wait. This may take a while...
Report is complete.
Name of report: user008_Files_210207.rpt
Location of report: /home/jiaming/Documents
Step #4 - Remove user account
Remove user008's account from system? [y/n] y
userdel: Permission denied.
userdel: cannot lock /etc/passwd; try again later.
User account, user008, has been removed
jiaming@jiaming-VirtualBox:~/Documents$ cat Delete_User.sh
function get_answer {
unset ANSWER
ASK_COUNT=0
while [ -z "$ANSWER" ]
do
ASK_COUNT=$[ $ASK_COUNT + 1 ]
case $ASK_COUNT in
2)
echo
echo "Please answer the question."
echo
;;
3)
echo
echo "One last try...please answer the question."
echo
;;
4)
echo
echo "Since you refuse to answer the question..."
echo "exiting program."
echo
exit
;;
esac
echo
if [ -n "$LINE2" ]
then
echo $LINE1
echo -e $LINE2" \c"
else
echo -e $LINE1" \c"
fi
read -t 60 ANSWER
done
unset LINE1
unset LINE2
} # end of get_answer function
function process_answer {
case $ANSWER in
y|Y|YES|yes|Yes|yEs|yeS|YEs|yES)
#If your answers "yes", do nothing
;;
*)
# If user answers anything but "yes", exit script
echo
echo $EXIT_LINE1
echo $EXIT_LINE2
echo
exit
;;
esac
# Do a little variable clean-up
unset EXIT_LINE1
unset EXIT_LINE2
} # End of process_answer function
echo "Step #1 - Determine User Account name to Delete "
echo
LINE1="Please enter the username of the user "
LINE2="account you wish to delete from system:"
get_answer
USER_ACCOUNT=$ANSWER
# Double check with script user that this is the correct User Account
LINE1="Is $USER_ACCOUNT the user account "
LINE2="you wish to delete from the system? [y/n]"
get_answer
# Call program function:
# if user answers anything but "yes", exit script
EXIT_LINE1="Because the account, $USER_ACCOUNT, is not "
EXIT_LINE2="the one you wish to delete, we are leaving the script..."
process_answer
# check that USER_ACCOUNT is really an account on the system
USER_ACCOUNT_RECORD=$(cat /etc/passwd | grep -w $USER_ACCOUNT)
if [ $? -eq 1 ] # If the account is not found, exit script
then
echo
echo "Account, $USER_ACCOUNT, not found. "
echo "Leaving the script..."
echo
exit
fi
echo
echo "I found this record:"
echo $USER_ACCOUNT_RECORD
LINE1="Is this the correctrrect User Account [y/n]"
get_answer
EXIT_LINE1="Because the account, $USER_ACCOUNT, is not."
EXIT_LINE2="the one you wish to delete, we are leaving the script..."
process_answer
# search for any running processes that belong to the User Account
echo
echo "Step #2 - Find process on system belonging to user account"
echo
ps -u $USER_ACCOUNT >/dev/null # are user processes running
case $? in
1)
# No processes running for this User Account
echo "There are no processes for this account currently running."
echo
;;
0)
# processes running for this User account.
# Ask script User if wants us to kill the processes.
echo "$USER_ACCOUNT has the following processes running: "
echo
ps -u $USER_ACCOUNT
LINE1="Would you like me to kill the process(es)? [y/n]"
get_answer
case $ANSWER in
y|Y|YES|yes|Yes|yEs|yEs|yeS|YEs|yEs)
echo
echo "Killing off process(es)..."
# List user processes running code in variable, COMMAND_1
COMMAND_1="ps -u $USER_ACCOUNT --no-heading"
# Create command to kill processs in variable, COMMAND_3
COMMAND_3="xargs -d\\n /usr/bin/sudo /bin/kill -9"
# Kill processes via piping commands together
$COMMAND_1 | gawk '{print $1}' | $COMMAND_3
echo
echo "Process(es) killed."
;;
*)
# If user answers anything but "yes", do not kill.
echo
echo "Will not kill the process(es)"
echo
;;
esac
;;
esac
# create a report of all files owned by User Account
echo
echo "Step #3 - Find files on system belonging to user account"
echo
echo "Creating a report of all files owned by $USER_ACCOUNT"
echo
echo "It is recommended that you backup/archive these files,"
echo "and then do one of two things:"
echo " 1) Delete the files"
echo " 2) Change the files' ownership to a current user account."
echo
echo "Please wait. This may take a while..."
REPORT_DATE=$(date +%y%m%d)
REPORT_FILE=$USER_ACCOUNT"_Files_"$REPORT_DATE".rpt"
find / -user $USER_ACCOUNT > $REPORT_FILE 2>/dev/null
echo
echo "Report is complete."
echo "Name of report: $REPORT_FILE"
echo "Location of report: $(pwd)"
echo
# Remove User Account
echo
echo "Step #4 - Remove user account"
echo
LINE1="Remove $USER_ACCOUNT's account from system? [y/n]"
get_answer
# Call process_answer function:
# if user answers anything but "yes", exit script
EXIT_LINE1="Since you do not wish to remove the user account,"
EXIT_LINE2="$USER_ACCOUNT at this time, exiting the script..."
process_answer
userdel $USER_ACCOUNT
echo
echo "User account, $USER_ACCOUNT, has been removed"
echo
exit
1.3 检测磁盘空间
du
命令能够显示出单个文件和目录的磁盘使用情况。-s
选项用来总结目录一级的整体使用情况。
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -s /home/jiaming/Documents/
12756 /home/jiaming/Documents/
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -s /home/*
4 /home/aoko
4 /home/byf
4 /home/djy
148140 /home/jiaming
4 /home/lhb
4 /home/lhm
4 /home/sj
2520 /home/wxc
4 /home/yx
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -s /var/log/*
8 /var/log/alternatives.log
40 /var/log/alternatives.log.1
364 /var/log/apt
8 /var/log/auth.log
84 /var/log/auth.log.1
4 /var/log/boot.log
56 /var/log/bootstrap.log
0 /var/log/btmp
0 /var/log/btmp.1
32 /var/log/cups
4 /var/log/dist-upgrade
384 /var/log/dpkg.log
1288 /var/log/dpkg.log.1
8 /var/log/faillog
8 /var/log/fontconfig.log
4 /var/log/gdm3
4 /var/log/gpu-manager.log
8 /var/log/hp
724 /var/log/installer
73756 /var/log/journal
0 /var/log/kern.log
852 /var/log/kern.log.1
40 /var/log/lastlog
4 /var/log/speech-dispatcher
32 /var/log/syslog
180 /var/log/syslog.1
44 /var/log/syslog.2.gz
44 /var/log/syslog.3.gz
76 /var/log/syslog.4.gz
192 /var/log/syslog.5.gz
184 /var/log/syslog.6.gz
12 /var/log/tallylog
244 /var/log/unattended-upgrades
4 /var/log/vboxadd-install.log
4 /var/log/vboxadd-setup.log
4 /var/log/vboxadd-setup.log.1
4 /var/log/vboxadd-setup.log.2
4 /var/log/vboxadd-setup.log.3
4 /var/log/vboxadd-setup.log.4
4 /var/log/vboxadd-uninstall.log
24 /var/log/wtmp
12 /var/log/wtmp.1
52 /var/log/Xorg.0.log
52 /var/log/Xorg.1.log
-S
选项为每个目录和子目录分别提供了总计信息。
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -S /var/log/
73752 /var/log/journal/4e099a704ede4a4aa9a20f35bf22f7c8
4 /var/log/journal
364 /var/log/apt
244 /var/log/unattended-upgrades
4 /var/log/dist-upgrade
724 /var/log/installer
4 /var/log/gdm3
4 /var/log/hp/tmp
4 /var/log/hp
32 /var/log/cups
4 /var/log/speech-dispatcher
3720 /var/log/
排序:
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -S /var/log/ | sort -rn
73752 /var/log/journal/4e099a704ede4a4aa9a20f35bf22f7c8
3720 /var/log/
724 /var/log/installer
364 /var/log/apt
244 /var/log/unattended-upgrades
32 /var/log/cups
4 /var/log/speech-dispatcher
4 /var/log/journal
4 /var/log/hp/tmp
4 /var/log/hp
4 /var/log/gdm3
4 /var/log/dist-upgrade
jiaming@jiaming-VirtualBox:~/Documents$ sudo du -S /var/log/ |
> sort -rn |
> sed '{11, $D; =}' |
> sed 'N; s/\n/ /' |
> gawk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
1: 73752 /var/log/journal/4e099a704ede4a4aa9a20f35bf22f7c8
2: 3720 /var/log/
3: 724 /var/log/installer
4: 364 /var/log/apt
5: 244 /var/log/unattended-upgrades
6: 32 /var/log/cups
7: 4 /var/log/speech-dispatcher
8: 4 /var/log/journal
9: 4 /var/log/hp/tmp
10: 4 /var/log/hp
jiaming@jiaming-VirtualBox:~/Documents$ cat Big_Users.sh
CHECK_DIRECTORIES=" /var/log /home" # Directories to check
DATE=$(date '+%m%d%y')
exec > disk_space$DATE.rpt
echo "Top Ten Disk Space Usage"
echo "for $CHECK_DIRECTORIES Directories"
for DIR_CHECK in $CHECK_DIRECTORIES
do
echo ""
echo "The $DIR_CHECK Directory:"
# Create a listing of top ten disk space users in this dir
du -S $DIR_CHECK 2>/dev/null |
sort -rn |
sed '{11, $D; =}' |
sed 'N; s/\n/ /' |
gawk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
done
exit
Top Ten Disk Space Usage
for /var/log /home Directories
The /var/log Directory:
1: 73752 /var/log/journal/4e099a704ede4a4aa9a20f35bf22f7c8
2: 3724 /var/log
3: 724 /var/log/installer
4: 364 /var/log/apt
5: 244 /var/log/unattended-upgrades
6: 32 /var/log/cups
7: 4 /var/log/speech-dispatcher
8: 4 /var/log/journal
9: 4 /var/log/hp/tmp
10: 4 /var/log/hp
The /home Directory:
1: 36948 /home/jiaming/.cache/mozilla/firefox/ecbxuag8.default-release/cache2/entries
2: 19500 /home/jiaming/.cache/mozilla/firefox/ecbxuag8.default-release/startupCache
3: 13672 /home/jiaming/.mozilla/firefox/ecbxuag8.default-release/storage/permanent/chrome/idb
4: 13360 /home/jiaming/.mozilla/firefox/ecbxuag8.default-release
5: 12488 /home/jiaming/Documents/bin
6: 4496 /home/jiaming/.mozilla/firefox/ecbxuag8.default-release/security_state
7: 3156 /home/jiaming/.local/share/Trash/files/vim/sqlite
8: 3156 /home/jiaming/Desktop/vim/sqlite
9: 2004 /home/jiaming/.local/share/Trash/files
10: 1560 /home/jiaming/.cache/gnome-software/icons
2. 电子邮件脚本
sudo apt-get install mailutils
sudo apt-get install sendmail
sudo apt-get install Mailx
mail [-eIinv] [-a header] [-b addr] [-c addr] [-b subj] to-addr
参数 | 描述 |
-a | 指定额外的 SMTP 头部行 |
-b | 给消息增加一个 BCC:收件人 |
-c | 给消息增加一个 CC:收件人 |
-e | 如果消息为空,不要发送消息 |
-i | 忽略 TTY 中断信号 |
-I | 强调 Mailx 以交互模式运行 |
-n | 不要读取 /etc/mail.rc 启动文件 |
-s | 指定一个主题行 |
-v | 在终端上显示投递细节 |
jiaming@jiaming-VirtualBox:~$ echo "This is a test message" | mailx -s "Test message" user001
user001@jiaming-VirtualBox:~$ mail
"/var/mail/user001": 1 message 1 new
>N 1 jiaming 一 2月 8 13:1 15/631 Test message
?
Return-Path: <jiaming@jiaming-VirtualBox>
Received: from jiaming-VirtualBox (localhost [127.0.0.1])
by jiaming-VirtualBox (8.15.2/8.15.2/Debian-10) with ESMTP id 1185Fu8R017659
for <user001@jiaming-VirtualBox>; Mon, 8 Feb 2021 13:15:56 +0800
Received: (from jiaming@localhost)
by jiaming-VirtualBox (8.15.2/8.15.2/Submit) id 1185FuCC017651;
Mon, 8 Feb 2021 13:15:56 +0800
Date: Mon, 8 Feb 2021 13:15:56 +0800
From: jiaming <jiaming@jiaming-VirtualBox>
Message-Id: <202102080515.1185FuCC017651@jiaming-VirtualBox>
Subject: Test message
To: <user001@jiaming-VirtualBox>
X-Mailer: mail (GNU Mailutils 3.4)
This is a test message
jiaming@jiaming-VirtualBox:~$ cat factmail.sh
# mailing the answer to a factorial
MAIL=$(which mailx)
factorial=1
counter=1
read -p "Enter the number: " value
while [ $counter -le $value ]
do
factorial=$[$factorial * $counter]
counter=$[$counter + 1]
done
echo The factorial of $value is $factorial | $MAIL -s "Factorial answer" $USER
echo "The result has been mailed to you.":
jiaming@jiaming-VirtualBox:~$ bash factmail.sh
Enter the number: 6
The result has been mailed to you.:
jiaming@jiaming-VirtualBox:~$ mail
"/var/mail/jiaming": 1 message 1 new
>N 1 jiaming 一 2月 8 13:2 15/638 Factorial answer
? 1
Return-Path: <jiaming@jiaming-VirtualBox>
Received: from jiaming-VirtualBox (localhost [127.0.0.1])
by jiaming-VirtualBox (8.15.2/8.15.2/Debian-10) with ESMTP id 1185PL1H017732
for <jiaming@jiaming-VirtualBox>; Mon, 8 Feb 2021 13:25:21 +0800
Received: (from jiaming@localhost)
by jiaming-VirtualBox (8.15.2/8.15.2/Submit) id 1185PLU2017729;
Mon, 8 Feb 2021 13:25:21 +0800
Date: Mon, 8 Feb 2021 13:25:21 +0800
From: jiaming <jiaming@jiaming-VirtualBox>
Message-Id: <202102080525.1185PLU2017729@jiaming-VirtualBox>
Subject: Factorial answer
To: <jiaming@jiaming-VirtualBox>
X-Mailer: mail (GNU Mailutils 3.4)
The factorial of 6 is 720
jiaming@jiaming-VirtualBox:~$ cat diskmail.sh
# sending the current disk statistics in an e-mail message
date=$(date +%m/%d/%Y)
MAIL=$(which mailx)
TEMP=$(mktemp tmp.XXXXXX)
df -k > $TEMP
cat $TEMP | $MAIL -s "Disk stats for $date" $1
rm -f $TEMP
jiaming@jiaming-VirtualBox:~$ mail
"/var/mail/jiaming": 1 message 1 new
>N 1 root 一 2月 8 13:3 40/2364 Disk stats for 02/08/2021
? 1
Return-Path: <root@jiaming-VirtualBox>
Received: from jiaming-VirtualBox (localhost [127.0.0.1])
by jiaming-VirtualBox (8.15.2/8.15.2/Debian-10) with ESMTP id 1185YR3j01
7791
for <jiaming@jiaming-VirtualBox>; Mon, 8 Feb 2021 13:34:27 +0800
Received: (from root@localhost)
by jiaming-VirtualBox (8.15.2/8.15.2/Submit) id 1185YRbs017790;
Mon, 8 Feb 2021 13:34:27 +0800
Date: Mon, 8 Feb 2021 13:34:27 +0800
From: root <root@jiaming-VirtualBox>
Message-Id: <202102080534.1185YRbs017790@jiaming-VirtualBox>
Subject: Disk stats for 02/08/2021
To: <jiaming@jiaming-VirtualBox>
X-Mailer: mail (GNU Mailutils 3.4)
Filesystem 1K-blocks Used Available Use% Mounted on
udev 4052620 0 4052620 0% /dev
tmpfs 815352 1568 813784 1% /run
/dev/sda1 10253588 6046504 3666516 63% /
tmpfs 4076756 0 4076756 0% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 4076756 0 4076756 0% /sys/fs/cgroup
/dev/loop2 2560 2560 0 100% /snap/gnome-calculator/826
/dev/loop1 56832 56832 0 100% /snap/core18/1944
/dev/loop0 91264 91264 0 100% /snap/core/8268
/dev/loop3 4352 4352 0 100% /snap/gnome-calculator/544
/dev/loop4 384 384 0 100% /snap/gnome-characters/570
/dev/loop5 3840 3840 0 100% /snap/gnome-system-monitor/127
/dev/loop7 1024 1024 0 100% /snap/gnome-logs/81
/dev/loop8 166784 166784 0 100% /snap/gnome-3-28-1804/145
/dev/loop9 66432 66432 0 100% /snap/gtk-common-themes/1514
/dev/loop10 164096 164096 0 100% /snap/gnome-3-28-1804/116
/dev/loop11 46080 46080 0 100% /snap/gtk-common-themes/1440
/dev/loop12 2304 2304 0 100% /snap/gnome-system-monitor/148
/dev/loop13 15104 15104 0 100% /snap/gnome-characters/399
/dev/loop15 100352 100352 0 100% /snap/core/10583
/dev/loop14 1024 1024 0 100% /snap/gnome-logs/100
/dev/loop16 56832 56832 0 100% /snap/core18/1988
tmpfs 815348 28 815320 1% /run/user/121
tmpfs 815348 36 815312 1% /run/user/1000
/dev/sr0 59206 59206 0 100% /media/jiaming/VBox_GAs_6.1.12
? q
Saved 1 message in /home/jiaming/mbox
Held 0 messages in /var/mail/jiaming
3. 一些小有意思的脚本
3.1 发送消息
启动消息功能:mesg y
who -T
消息状态已经变成了加号,表明她可以接收他人的消息了。
使用 write 命令通过其他登录用户的用户名和当前终端向其发送信息。
jiaming@jiaming-VirtualBox:~/Documents$ bash mu.sh user001 Hello user001, biu...user001 is not logged on.
Exiting script...
jiaming@jiaming-VirtualBox:~/Documents$ cat mu.sh
# save the username parameter
muser=$1
# determine if user is logged on:
logged_on=$(who | grep -i -m 1 $muser | gawk '{print $1}')
if [ -z $logged_on ]
then
echo "$muser is not logged on."
echo "Exiting script..."
exit
fi
# determine if user allows messaging:
allowed=$(who -T | grep -i -m 1 $muser | gawk '{print $2}')
if [ $allowed != "+" ]
then
echo "$muser does not allowing messaging."
echo "Exiting script..."
exit
fi
# determine if a message was included:
if [ -z $2 ]
then
echo "No message parameter included."
echo "Exiting script..."
exit
fi
# determine if there is more to the message.
shift
while [ -n "$1" ]
do
whole_message=$whole_message' '$1
shift
done
# send message to user
uterminal=$(who | grep -i -m 1 $muser | gawk '{print $2}')
echo $whole_message | write $logged_on $uterminal
exit
3.2 获取格言
jiaming@jiaming-VirtualBox:~/Documents$ bash get_quote.sh
jiaming@jiaming-VirtualBox:~/Documents$ cat /tmp/daily_quote.txt
jiaming@jiaming-VirtualBox:~/Documents$ cat get_quote.sh
quote_url=www.quotationspage.com/qotd.html
check_url=$(wget -nv --spider $quote_url 2>&1)
if [[ $check_url == *error404* ]]
then
echo "Bad web address"
echo "$quote_url invalid"
echo "Exiting script..."
exit
fi
# Download web site's information
wget -o /tmp/quote.log -O /tmp/quote.html $quote_url
# extract the desired data
sed 's/<[^>]*//g' /tmp/quote.html |
grep "$(date +%B' '%-d,' '%Y)" -A2 |
sed 's/>//g' |
sed '/ /{n ; d}' |
gawk 'BEGIN{FS="NBSP;"} {print $1}' |
tee /tmp/daily_quote.txt > /dev/null
exit
3.3 编造借口
使用 curl 工具,以及提供免费 SMS 消息发送服务的网站(http://textbelt.com/text),这个网站允许你每天发送最多 75 条短信。
curl http://textbelt.com/text \
-d number=YourPhoneNumber \
-d "message=Your Text Message"
jiaming@jiaming-VirtualBox:~/Documents$ cat send_txt.sh
phone="xxxx"
SMSrelay=http://textbelt.com/text
text_message="System Code Red"
curl -s $SMSrelay -d \
number=$phone \
-d "message=$text_message" > /dev/null
exit