shell内部变量
一、内部变量杂记
1、随便记
[root@master4 ~]# echo $HOSTNAME
master4.com
[root@master4 ~]#
[root@master4 ~]# echo $HOSTTYPE
x86_64
[root@master4 ~]#
[root@master4 ~]# uname -m
x86_64
[root@master4 ~]#
记录上一个位置变量:
[root@master4 day1]# echo $OLDPWD
/root
[root@master4 day1]#
[root@master4 day1]# echo $OLDPWD
/root
[root@master4 day1]# cd
[root@master4 ~]# echo $OLDPWD
/server/scripts/day1
[root@master4 ~]# cd $OLDPWD
[root@master4 day1]#
产生随机数:
[root@master4 day1]# echo $RANDOM
27093
[root@master4 day1]#
历史文件记录:
cat /etc/profile
HISTSIZE=10
HISTFILESIZE=10
二、内部命令
1、杂记
[root@master4 ~]# which cd
/usr/bin/cd
[root@master4 ~]# type -a cd
cd is a shell builtin
cd is /usr/bin/cd
[root@master4 ~]#
man的格式查询命令帮助:
[root@master4 ~]# help -m history
2、常见bash内置命令
2.1 echo
-n,不换行
[root@master4 day1]# echo -n oldboy
oldboy[root@master4 day1]#
-e
[root@master4 day1]# echo -e "oldboy\toldbody"
oldboy oldbody
[root@master4 day1]#
[root@master4 day1]# echo -e "oldboy\noldbody"
oldboy
oldbody
追加内容到文件结尾:
[root@master4 day2]# echo '####' >> a.log
2.2 printf
[root@master4 ~]# printf "Restarting MySQl...\n"
Restarting MySQl...
[root@master4 ~]#
2.3 read
接收一个用户参数
[root@master4 day2]# cat read.sh
read -p "please input a number:" var
echo $var
[root@master4 day2]#
[root@master4 day2]# sh read.sh
please input a number:100
100
2.4 history
2.5 ulimit
查看文件描述符
[root@master4 day2]# ulimit -n
1024
[root@master4 day2]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 1879
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1879
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@master4 day2]#
2.6 shifit 位置变量降级
[root@master4 ~]# set -- "I am" handsome oldboy.
[root@master4 ~]# echo $#
3
[root@master4 ~]#
[root@master4 ~]# echo $#
3
[root@master4 ~]# echo $1
I am
[root@master4 ~]# echo $2
handsome
[root@master4 ~]# echo $3
oldboy.
参数减1
[root@master4 ~]# shift
[root@master4 ~]# echo $1
handsome
[root@master4 ~]# echo $2
oldboy.
[root@master4 ~]# echo $3
2.7 time
计算执行命令的时间:
[root@master4 ~]# time du -sh /etc
23M /etc
real 0m0.384s
user 0m0.003s
sys 0m0.048s
3、变量子串的常用操作
3.1 ${#string}
返回$string的长度
[root@master4 ~]# echo ${#LANG}
11
[root@master4 ~]#
[root@master4 ~]# OLDBOY="I am oldboy"
[root@master4 ~]# echo $OLDBOY
I am oldboy
返回长度:
[root@master4 ~]# echo ${#OLDBOY}
11
3.2 ${string:position}
在$string中,从位置$position之后开始提取子串
字符之后开始接续,不包含字符在内
[root@master4 ~]# echo $LANG
en_US.UTF-8
[root@master4 ~]# echo ${LANG:6}
UTF-8
[root@master4 ~]#
[root@master4 ~]# echo ${OLDBOY:2}
am oldboy
3.3 ${string:postition:length}
从第二个开始取,取两个
[root@master4 ~]# echo ${OLDBOY:2:2}
am
[root@master4 ~]#
3.4 ${string#substring}
从变量$string开头开始删除最短匹配$substring子串
[root@master4 ~]# echo $OLDBOY
I am oldboy
[root@master4 ~]# echo ${OLDBOY#I am}
oldboy
[root@master4 ~]#
[root@master4 ~]# echo ${OLDBOY#I}
am oldboy
[root@master4 ~]#
开头删除,最短匹配
[root@master4 ~]# OLDBOY="I am oldboy I am"
[root@master4 ~]# OLDBOY="I am oldboy I am"
[root@master4 ~]# echo ${OLDBOY#I am}
oldboy I am
[root@master4 ~]#
3.5 ${string##substring}
[root@master4 ~]# echo ${OLDBOY##I am}
oldboy I am
[root@master4 ~]#
3.6 ${string%substring}
从后面开始删除:
[root@master4 ~]# echo ${OLDBOY}
I am oldboy I am
[root@master4 ~]# echo ${OLDBOY%I am}
I am oldboy
[root@master4 ~]#
3.7 ${string%%substring}
[root@master4 ~]# echo ${OLDBOY%%I am}
I am oldboy
[root@master4 ~]#
3.8 ${string/substring/replace}
[root@master4 ~]# OLDBOY="I am oldboy"
从左开始替换:
[root@master4 ~]# echo ${OLDBOY/oldboy/etiantian}
I am etiantian
[root@master4 ~]#
3.9 ${string/%substring/replace}
从结尾开始替换:
[root@master4 ~]# OLDBOY="oldboy I am oldboy oldboy"
[root@master4 ~]#
[root@master4 ~]# echo ${OLDBOY/%oldboy/etiantian}
oldboy I am oldboy etiantian
[root@master4 ~]#
3.10 ${string/#substring/replace}
[root@master4 ~]# OLDBOY="oldboy I am oldboy oldboy"
前缀匹配:
[root@master4 ~]# echo ${OLDBOY/#oldboy/etiantian}
etiantian I am oldboy oldboy
4、最长匹配和最短匹配
[root@master4 ~]# OLDBOY="I am oldboy I am oldboy"
5、实例
5.1 变量结尾删除实践
${string%substring}
把下面所有系统中文件的文件名中的findished内容去掉
[root@master4 day2]# cd testdir/
[root@master4 testdir]# touch stu_102999_1_finished.jpg stu_102999_2_finished.jpg stu_102999_3_finished.jpg stu_102999_4_finished.jpg stu_102999_5_finished.jpg
[root@master4 testdir]# ls -l
total 0
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_1_finished.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_2_finished.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_3_finished.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_4_finished.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_5_finished.jpg
改单个文件:
[root@master4 testdir]# file="stu_102999_1_finished.jpg"
[root@master4 testdir]# mv $file ${file%finished*}.jpg
[root@master4 testdir]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_1_.jpg
批量:
[root@master4 testdir]# for file in `ls *.jpg`;do mv $file ${file%finished*}.jpg;done
[root@master4 testdir]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_1_.jpg.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_2_.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_3_.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_4_.jpg
-rw-r--r-- 1 root root 0 Nov 18 06:11 stu_102999_5_.jpg
[root@master4 testdir]#
[root@master4 testdir]# vim chang_file_name.sh
for file in `ls *.jpg`;
do
mv $file ${file%finished*}.jpg
done
[root@master4 testdir]# echo ${file%.html}.HTML
a.HTML
[root@master4 testdir]# echo ${file%.html} | tr "[a-z]" "[A-Z]"
A
5.2 变量结尾替换
创建测试文件:
[root@master4 testdir]# touch {a..g}.html
[root@master4 testdir]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 18 06:27 a.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 b.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 c.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 d.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 e.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 f.html
-rw-r--r-- 1 root root 0 Nov 18 06:27 g.html
针对单个文件改名:
[root@master4 testdir]# echo ${file/%html/HTML}
A.html
批量修改:
[root@master4 testdir]# for file in `ls *.html`;do mv $file ${file/%html/HTML};done
[root@master4 testdir]# ll
total 4
-rw-r--r-- 1 root root 0 Nov 18 07:07 a.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 b.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 c.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 d.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 e.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 f.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 g.HTML
把文件名变成大写
[root@master4 testdir]# for file in `ls *.HTML`;do mv $file `echo ${file%.html} | tr "[a-z]" "[A-Z]"`;done
[root@master4 testdir]# ll
total 4
-rw-r--r-- 1 root root 0 Nov 18 07:07 A.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 B.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 C.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 D.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 E.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 F.HTML
-rw-r--r-- 1 root root 0 Nov 18 07:07 G.HTML
5.3 小结
小结:
结尾删除的办法:
[root@master4 testdir]# echo ${file%.html}.HTML
a.HTML
sed方法:
[root@master4 testdir]# echo $file | sed 's/html/HTML/g'
a.HTML
[root@master4 testdir]#
变量替换方法:
[root@master4 testdir]# echo ${file/%html/HTML}
a.HTML
5.4 awk改名
[root@master4 testdir]# ls
stu_102999_1_finished.jpg stu_102999_3_finished.jpg stu_102999_5_finished.jpg
stu_102999_2_finished.jpg stu_102999_4_finished.jpg
[root@master4 testdir]# ls *.jpg | awk -F "finished" '{print $0,$1""$2}'
stu_102999_1_finished.jpg stu_102999_1_.jpg
stu_102999_2_finished.jpg stu_102999_2_.jpg
stu_102999_3_finished.jpg stu_102999_3_.jpg
stu_102999_4_finished.jpg stu_102999_4_.jpg
stu_102999_5_finished.jpg stu_102999_5_.jpg
[root@master4 testdir]# ls *.jpg | awk -F "finished" '{print "mv "$0,$1""$2}'
mv stu_102999_1_finished.jpg stu_102999_1_.jpg
mv stu_102999_2_finished.jpg stu_102999_2_.jpg
mv stu_102999_3_finished.jpg stu_102999_3_.jpg
mv stu_102999_4_finished.jpg stu_102999_4_.jpg
mv stu_102999_5_finished.jpg stu_102999_5_.jpg
把命令交给bash处理:
[root@master4 testdir]# ls *.jpg | awk -F "finished" '{print "mv "$0,$1""$2}'| bash
[root@master4 testdir]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 18 10:56 stu_102999_1_.jpg
-rw-r--r-- 1 root root 0 Nov 18 10:56 stu_102999_2_.jpg
-rw-r--r-- 1 root root 0 Nov 18 10:56 stu_102999_3_.jpg
-rw-r--r-- 1 root root 0 Nov 18 10:56 stu_102999_4_.jpg
-rw-r--r-- 1 root root 0 Nov 18 10:56 stu_102999_5_.jpg
5.5 rename重命名
[root@master4 testdir]# rename "finished" "" *.jpg
[root@master4 testdir]# ls
stu_102999_1_.jpg stu_102999_2_.jpg stu_102999_3_.jpg stu_102999_4_.jpg stu_102999_5_.jpg
[root@master4 testdir]#
[root@master4 testdir]# rename "jpg" "png" *.jpg
[root@master4 testdir]# ls
stu_102999_1_.png stu_102999_2_.png stu_102999_3_.png stu_102999_4_.png stu_102999_5_.png
三、深入变量替换##
1、${value:-word}
测试变量是否存在且值非null,如果是返回里面的值,否则返回word
[root@master4 testdir]# result=${test:-word}
[root@master4 testdir]# echo $test
[root@master4 testdir]# echo $result
word
[root@master4 testdir]#
例子:
删除gz文件
[root@master4 testdir]# ll
total 0
-rw-r--r-- 1 root root 0 Nov 18 15:01 1.tar.gz
-rw-r--r-- 1 root root 0 Nov 18 15:01 2.tar.gz
如果路径不存在
[root@master4 testdir]# cat find.sh
#path=/server/scripts/day2/
find ${path:-/tmp} -type f -name "*.tar.gz" -exec rm -f {} \;
[root@master4 testdir]# sh -x find.sh
+ find /tmp -type f -name '*.tar.gz' -exec rm -f '{}' ';'
2、${value:=word}
取消变量:
[root@master4 testdir]# unset result
[root@master4 testdir]# result=${test:=word}
[root@master4 testdir]# echo $test
word
[root@master4 testdir]# echo $result
word
即便test有赋值,result的值还是word
[root@master4 testdir]# test=1
[root@master4 testdir]# echo $test
1
[root@master4 testdir]# echo $result
word
[root@master4 testdir]#
3、${value:?"word"}
[root@master4 testdir]# echo ${value:?"not define"}
-bash: value: not define
[root@master4 testdir]#
[root@master4 testdir]# echo ${value:?"value is null"}
-bash: value: value is null
4、${value:+word}
如果变量名存在且非null,则返回word。否则返回null。
用途:测试变量是否存在。
[root@master4 testdir]# echo ${value:+word}
[root@master4 testdir]# echo $value
[root@master4 testdir]# value=1
[root@master4 testdir]# echo ${value:+word}
word
[root@master4 testdir]#
5、企业生产应用:防止处理的路径变量无值,从根目录开始删除文件
[root@master4 testdir]# cat find.sh
#path=/server/scripts/day2/
find ${path:-/tmp} -type f -name "*.tar.gz" -exec rm -f {} \;
[root@master4 testdir]# sh -x find.sh
+ find /tmp -type f -name '*.tar.gz' -exec rm -f '{}' ';'
[root@master4 testdir]#
四、变量的数值计算
1、(())
1.1 加减乘除
[root@master4 testdir]# ((a=1+2**3-4%3))
[root@master4 testdir]# echo $a
8
[root@master4 testdir]#
[root@master4 testdir]# b=$((a=1+2**3-4%3))
[root@master4 testdir]# echo $b
8
[root@master4 testdir]#
只出结果:
[root@master4 testdir]# echo $((a=1+2**3-4%3))
8
1.2 +=
[root@master4 testdir]# a=$((1+2**3-4%3))
[root@master4 testdir]# echo $((a+=1))
9
[root@master4 testdir]#
1.3 a++
表达式
[root@master4 testdir]# echo $((a++))
9
实际已经增加了。先输出自身值,再运算
[root@master4 testdir]# echo $a
10
先运算再输出值:
[root@master4 testdir]# echo $((--a))
9
1.4 比较表达式
[root@master4 testdir]# echo $((3>2))
1
[root@master4 testdir]# echo $((3<2))
0
[root@master4 testdir]#
1+到100的值:
[root@master4 testdir]# echo $((100*(100+1)/2))
5050
[root@master4 testdir]#
1.5 变量计算
[root@master4 testdir]# myvar=99
[root@master4 testdir]# echo $(($myvar+1))
100
[root@master4 testdir]# echo $(( $myvar+1 ))
100
[root@master4 testdir]# echo $(( $myvar + 1 ))
100
[root@master4 testdir]#
1.6 运算
[root@master4 testdir]# echo $((100/6))
16
[root@master4 testdir]# echo $((100+6))
106
[root@master4 testdir]# echo $((100*6))
600
[root@master4 testdir]# echo $((100-6))
94
[root@master4 testdir]# echo $((100**6))
1000000000000
[root@master4 testdir]# echo $((100%6))
4
[root@master4 testdir]#
1.7 脚本练习
[root@master4 testdir]# vim test.sh
#!/bin/bash
a=6
b=2
echo "a-b =$(( $a - $b ))"
echo "a+b =$(( $a + $b ))"
echo "a*b =$(( $a * $b ))"
echo "a/b =$(( $a / $b ))"
echo "a**b =$(( $a ** $b ))"
echo "a%b =$(( $a % $b ))"
[root@master4 testdir]# sh test.sh
a-b = 4
a+b = 8
a*b = 12
a/b = 3
a**b = 36
a%b = 0
传参数实现运算:
[root@master4 testdir]# cat 01.sh
#!/bin/bash
a=$1
b=$2
echo "a-b = $(( $a - $b ))"
echo "a+b = $(( $a + $b ))"
echo "a*b = $(( $a * $b ))"
echo "a/b = $(( $a / $b ))"
echo "a**b = $(( $a ** $b ))"
echo "a%b = $(( $a % $b ))"
1.8 传参实现计算器
思路:$1就是下面计算表达式内容,即 4*5
方法一:
[root@master4 testdir]# cat d.sh
echo $(($1))
[root@master4 testdir]# sh 02.sh 4*5
20
方法二:
[root@master4 testdir]# cat 03.sh
echo $(($1$2$3))
[root@master4 testdir]# sh 03.sh 4 + 4
8
[root@master4 testdir]# sh 03.sh 1+3 +4 +2
10
[root@master4 testdir]#
乘法需要转义:
[root@master4 testdir]# sh 03.sh 4 \* 4
16
[root@master4 testdir]#
2、let
[root@master4 testdir]# i=2
[root@master4 testdir]# i=i+8
[root@master4 testdir]# echo $i
i+8
[root@master4 testdir]#
let运算:
[root@master4 testdir]# i=2
[root@master4 testdir]# let i=i+8
[root@master4 testdir]# echo $i
10
[root@
3、expr
3.1 expr用户整数计算
[root@master4 testdir]# expr 2 + 2
4
[root@master4 testdir]# expr 2 \* 3
6
[root@master4 testdir]#
3.2 例子
[root@master4 testdir]# i=0
[root@master4 testdir]# i=`expr $i + 1`
[root@master4 testdir]# echo $i
1
[root@master4 testdir]#
[root@master4 testdir]# expr $[2+3]
5
[root@master4 testdir]# expr $[2*3]
6
[root@master4 testdir]#
计算字符长度:
[root@master4 testdir]# expr length "oldboy"
6
提取子串:
[root@master4 testdir]# expr substr "oldboy" 4 3
boy
[root@master4 testdir]#
[root@master4 testdir]# OLDBOY="I am oldboy"
[root@master4 testdir]# echo ${#OLDBOY}
11
[root@master4 testdir]# echo ${OLDBOY:2:2}
am
[root@master4 testdir]#
4、变量的处理计算变量长度与其他不同方法的耗时对比:
[root@master4 testdir]# chars=`seq -s " " 100`
4.1
[root@master4 testdir]# echo ${#chars}
291
4.2
[root@master4 testdir]# echo $(expr length "$chars")
291
[root@master4 testdir]# expr length "$chars"
291
[root@master4 testdir]#
4.3
[root@master4 testdir]# echo ${chars} | wc -m
292
[root@master4 testdir]# echo ${chars} | wc -L
291
[root@master4 testdir]#
4.4 测试速度
[root@master4 day2]# time for i in $(seq 50000);do count=${#chars};done
real 0m2.170s
user 0m2.112s
sys 0m0.006s
[root@master4 day2]#
[root@master4 day2]# time for i in $(seq 50000);do count=`expr length "$chars"`;done
real 2m16.893s
user 0m34.889s
sys 1m34.553s
[root@master4 day2]# time for i in $(seq 50000);do count=`echo ${chars}|wc -L`;done
real 5m1.325s
user 1m1.350s
sys 3m41.831s