Linux Shell入门
一、shell之环境变量
shell是一门解释性语言,与C, Java 不同,变量的使用,不需要提前进行定义。shell的变量分为:局部变量和环境变量。局部变量只在shell脚本中使用,而环境变量可以在创建他们的shell及其派生出的子进程中使用。
shell中有一些系统变量,可以直接引用,如:
$0: 当前程序的名称
$n: 当前程序的第n个参数
$*: 当前程序的所有参数
$#: 当前程序的参数个数
$?: 命令或程序执行完后的状态,一般返回0代表执行成功
$UID: 当前用户的ID
$PWD: 当前所在的目录
echo 颜色
二、 shell 编程基本语法
1. if else
逻辑运算符:
-f 判断文件是否存在: if [ -f /path/filename ]; then
-d 判断目录是否存在: if [ -d /path/filename ]; then
-eq 等于,用于整数比较
-z 判断是否为空字符串
1 #!/bin/bash 2 if (($1 > $2));then 3 echo "Greater" 4 else 5 echo "Smaller" 6 fi
1 #!/bin/bash 2 DIR=/root/DTV/TestDirectory 3 if [ -d $DIR ]; then 4 echo -e "\033[32m This $DIR exist\033[0m" #####\033[32mtest\033[0m 代表给test加颜色 5 else 6 echo -e "\033[32m---------------\033[1m" #####\033[32m \033[0m 代表从本行开始下面全部加颜色 7 echo "$DIR will be created" 8 mkdir -p $DIR 9 fi
1 #!/bin/bash 2 BACKUP=/root/backup/`date +%Y-%m-%d` ##将date返回的日期格式化成year-month-day 3 #第一步,验证用户是否是root 4 if [[ $UID -eq 0 ]]; then 5 echo "yes, it's root" 6 else 7 echo "please use root to login" 8 fi 9 #第二步,检查当日目录是否存在,否则创建 10 if [ ! -d $BACKUP ]; then 11 echo -e "\033[32m backup directory of this day not exist,will creat\033[0m" 12 mkdir -p $BACKUP 13 else 14 echo "backup directroy is existed" 15 fi 16 cp /var/log/auth.log $BACKUP/auth.log.`date +%H-%M-%S` 17 要求: 每日以root用户执行备份/var/log/auth.log到/root/backup/下面,并命名带上时间戳
1 #!/bin/bash 2 PACKAGENAME=httpd-2.4.46.tar.gz 3 PARENTSDIR=/tmp 4 SONDIR=${PACKAGENAME:0:12} 5 DIR=$PARENTSDIR/$SONDIR 6 function checkDir() 7 { 8 if [ ! -d $PARENTSDIR/$1 ]; then 9 echo "\033[32m Dir isn't exist,will create\033[0m" 10 mkdir -p $PARENTSDIR/$SONDIR 11 else 12 echo "\033[32m Dir is existed\033[0m" 13 fi 14 } 15 16 checkDir $SONDIR 17 18 wget http://mirrors.cnnic.cn/apache/httpd/$PACKAGENAME -P $DIR && cd $DIR && tar -xvf $PACKAGENAME && cd ${PACKAGENAME:0:12}&& ./configure --prefix=$DIR/ 19 20 if [ $? -eq 0 ]; then 21 make && make install 22 echo "\033[32m Successfully \033[0m" 23 else 24 echo "\033[32m Failed \033[0m" 25 fi
2. 字符串操作
1 root@test:~# a=a1b2c3 2 root@test:~# echo ${a:0:4} ######0表示从左边第一个字符开始,4代表字符的总个数 3 a1b2
3. 循环
for 循环
1 #!/bin/bash 2 j=0 3 for((i=1;i<100;i++)) 4 do 5 j=`expr $j + $i` 6 done 7 echo $j
1 #!/bin/bash 2 FILES=$* 3 if [ -z $* ]; then 4 echo -e "\033[32musage: {$0 Director|filesname}\033[0m" 5 exit 6 fi 7 for i in `echo 192.168.0.2 127.0.0.1 10.0.0.1` 8 do 9 scp -p $FILES $i:/tmp/ 10 done 11 root@test:~/shell_program# bash test.sh 12 usage: {test.sh Director|filesname} 13 root@test:~/shell_program# bash test.sh 1 2 3 14 test.sh: line 4: [: too many arguments 15 1 100% 0 0.0KB/s 00:00 16 2 100% 0 0.0KB/s 00:00 17 3 100% 0 0.0KB/s 00:00 18 1 100% 0 0.0KB/s 00:00 19 2 100% 0 0.0KB/s 00:00 20 3 100% 0 0.0KB/s 00:00 21 1 100% 0 0.0KB/s 00:00 22 2 100% 0 0.0KB/s 00:00 23 3 100% 0 0.0KB/s 00:00
while循环
1 #!/bin/bash 2 while read line 3 do 4 echo $line 5 done < /var/log/auth.log
case 循环
1 #!/bin/bash 2 3 case $1 in 4 apache) 5 echo -e "\033[32m Installing apache server\033[0m" 6 apt-get -y install apache2 7 # tar -xvf apache.tar.gz;cd httpd; ./configure &&make &&make install 8 ;; 9 10 mysql) 11 echo -e "\033[32m Installing mysql server\033[0m" 12 apt-get -y install mysql-server 13 ;; 14 15 php) 16 # apt-get install .... 17 ;; 18 19 *) 20 echo -e "\033[32m Usage {$0 apache|mysql|php}\033[0m" 21 ;; 22 esac
4. select 选择
1 root@test:~/shell_program# select OS in "Centos" "Ubuntu" "Redhat";do echo "Selected System is $OS";done; 2 1) Centos 3 2) Ubuntu 4 3) Redhat 5 #? 1 6 Selected System is Centos 7 #? 3 8 Selected System is Redhat 9 #? 2 10 Selected System is Ubuntu 11 #?
1 #!/bin/bash 2 select SW in "apache安装" "mysql安装" "php安装" 3 do 4 case $SW in 5 apache安装) 6 echo -e "\033[32m Installing apache server\033[0m" 7 apt-get -y install apache2 8 # tar -xvf apache.tar.gz;cd httpd; ./configure &&make &&make install 9 ;; 10 11 mysql安装) 12 echo -e "\033[32m Installing mysql server\033[0m" 13 apt-get -y install mysql-server 14 ;; 15 16 php安装) 17 echo -e "\033[32m Installing php server\033[0m" 18 # apt-get install .... 19 ;; 20 21 *) 22 echo -e "\033[32m Please input {1|2|3}\033[0m" 23 ;; 24 esac 25 done
5. shell之数组
定义:ARRAY=(test1 test2 test3)
引用: ${ARRAY[0]}
数组所有参数: ${ARRAY[@]}, 将显示所有内容,test1,test2,test3
数组参数个数: ${#ARRAY[@]}, 将显示3
替换数组内某个参数后返回新数组:${ARRAY[@]/test1/test4}
直接删除数组内某个参数:unset ARRAY[2]; 直接在原数删除test3
三、Linux之sed
1. 文本替换
1. 预修改,文件内容先不动
sed 's/oldString/newString/g' test.txt
2. 直接在文件里修改 sed -i 's/oldString/newString/g' test.txt
2. 每一行的行首、行尾添加
1. 在每一行的行首添加"testeString " ^代表行首 sed 's/^/&testString /g' test.log 2. 在每一行的行尾添加" testString" $代表行尾 sed 's/$/& testString /g' test.log 3. 在第2行的行首添加“testString ” 2s代表第2行 sed '2s/^/&testString /g' test.log
3. 在特定字符串前、后添加
1. 在特定字符串testString前添加 “######” sed '/testString/#######&' test.log 2. 在特定字符串testString前一行添加 “######” sed '/testString/i #######' test.log 3. 在特定字符串testString后添加 “######” sed '/testString/&#######' test.log 4. 在特定字符串testString后一行添加 “######” sed '/testString/a #######' test.log
4. 打印
1. 打印包含testString的行 sed -n '/testString/p' test.log 2. 打印第1行 sed -n '1p' test.log 3. 打印1-5行 sed -n '1,5p' test.log 4. 打印第1行和第5行 sed -n '1p;5p' test.log 5. 打印第1行和最后1行 sed -n '1p;$p' test.log
四、Linux之grep
注: grep -E= egrep
正则:
1. 打印以testString开始的行, ^代表开始 grep "^testString" test.log 2. 打印以testString结束的行, $代表结尾 grep "testString$" test.log 3. 打印包含数字0-5的行 grep "[0-5]" test.log 4. 打印包含字母a-f的行 grep "[a-f]" test.log 5. 打印以字母a-f开头的行 grep "^[a-f]" test.log
正则表达举例:
正则匹配ip root@test:~/shell_program# cat test.log 10.0.192.10 a.0.182.0 10.0.192.100 123.192.100.1234 10.0.199. 12123.192.100.1234 正确答案: root@test:~/shell_program# cat test.log | grep -E "^(([0-9]{1,3}\.){3}[0-9]{1,3})$" 10.0.192.10 10.0.192.100
解释:
1 root@test:~# cat test.log | grep -E "[0-9]" ##包含0-9 2 10.0.192.10 3 a.0.182.0 4 10.0.192.100 5 123.192.100.1234 6 10.0.199. 7 12123.192.100.1234 8 root@test:~# cat test.log | grep -E "[0-9]{1,3}" ##包含1-3个0-9,比如1 10 192 9 10.0.192.10 10 a.0.182.0 11 10.0.192.100 12 123.192.100.1234 13 10.0.199. 14 12123.192.100.1234 15 root@test:~# cat test.log | grep -E "[0-9]{1,3}\." ##包含1-3个0-9后,接着是一个. 注:正则里面.的表达: \. 16 10.0.192.10 17 a.0.182.0 18 10.0.192.100 19 123.192.100.1234 20 10.0.199. 21 12123.192.100.1234 22 root@test:~# cat test.log | grep -E "([0-9]{1,3}\.){3}" ##对于1. 或者10. 或者 192. 这样的匹配需要3次 23 10.0.192.10 24 10.0.192.100 25 123.192.100.1234 26 10.0.199. 27 12123.192.100.1234 28 root@test:~# cat test.log | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" ##在10.0.192之后,还需要有1-3个0-9 29 10.0.192.10 30 10.0.192.100 31 123.192.100.1234 32 12123.192.100.1234 33 root@test:~# cat test.log | grep -E "^(([0-9]{1,3}\.){3}[0-9]{1,3})$" ##以上一步过滤出的表达, 精确匹配,以此种模式开始,并结束。 34 10.0.192.10 35 10.0.192.100
五、Linux之awk
1. 指定分隔符为 “.” awk -F. '{print $2}' 2. awk 倒数第一列 awk '{print $(NF-1)}' 3. awk分割后,同时print附加其他信息 awk '{print "test" $2}' 4. 如果第2列数字大于14,就打印第1,2,最后1列 awk '$2>=14 {print $1 $2 $NF}'
六、Linux之find
举例: find /var/log/ -maxdepth 2 -type f -size +100M -exec cp {} /tmp \;
找到/var/log及其下一级目录下,大于100M的文件,拷贝到/tmp下
只查找当前目录 find . -maxdepth 1 最多查找到下一级目录 find . -maxdepth 2 查找文件 find . -type f 查找目录 find . -type d 30天之前的 find . -mtime +30 2天以内的 find . -mtime -2 大于200M的 find . -size +200M 找到*.log后删除 find . -type f -name *.log -exec rm {} \; find . -type f -name *.log |xargs rm {} \;
七、脚本中有错误行,跳出
set -eu
end