shell 是操作系统的最外层。shell 合并编程语言以控制进程和文件,以及启动和控制其它程序。shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。
shell提供了与操作系统通信的方式。此通信以交互的方式(来自键盘的输入立即操作)或作为一个 shell 脚本执行。shell 脚本是 shell 和操作系统命令的序列,它存储在文件中。
当登录到系统中时,系统定位要执行的 shell 的名称。在它执行之后,shell 显示一个命令提示符。普通用户的此提示符通常是一个 $(美元符)。当提示符下输入命令并按下 Enter 键时,shell 对命令进行求值,并尝试执行它。取决于命令说明,shell 将命令输出写到屏幕或重定向到输出。然后它返回命令提示符,并等待您输入另一个命令。
命令行是输入所在的行。它包含 shell 提示符。每行的基本格式如下:
$ 命令参数(一个或多个)
shell 视命令行的第一个字(直到第一个空白空格)为命令,所有后继字为自变量。
1. 字符串的截取
shell字符串的截取的问题:
一、Linux shell 截取字符变量的前8位,有方法如下:
1) expr substr “$a” 1 8
2) echo $a|awk ‘{print substr(,1,8)}’
3) echo $a|cut -c1-8
4) expr $a : ‘\(.\\).*’
5) echo $a|dd bs=1 count=8 2>/dev/null
二、按指定的字符串截取
1) 第一种方法:
${varible##*string} 从左向右截取最后一个string后的字符串
${varible#*string}从左向右截取第一个string后的字符串
${varible%%string*}从右向左截取最后一个string后的字符串
${varible%string*}从右向左截取第一个string后的字符串
“*”只是一个通配符可以不要
例子:
$ MYVAR=foodforthought.jpg
$ echo ${MYVAR##*fo}
rthought.jpg
$ echo ${MYVAR#*fo}
odforthought.jpg
2) 第二种方法:${varible:n1:n2}:截取变量varible从n1到n2之间的字符串。
可以根据特定字符偏移和长度,使用另一种形式的变量扩展,来选择特定子字符串。试着在 bash 中输入以下行:
$ EXCLAIM=cowabunga
$ echo ${EXCLAIM:0:3}
cow
$ echo ${EXCLAIM:3:7}
abunga
这种形式的字符串截断非常简便,只需用冒号分开来指定起始字符和子字符串长度。
三、按照指定要求分割:
比如获取后缀名
ls -al | cut -d “.” -f2
2. 大小写转换
echo $uppercase |tr [A-Z] [a-z]
echo $lowercase |tr [a-z] [A-Z]
练习一:写一个脚本:
1.创建目录/tmp/scripts
2.切换工作目录至此目录中 3.复制/etc/pam.d目录至当前目录,并重命名为test
4.将当前目录的test及其里面的文件和子目录的属主改为redhat
5.将test及其子目录中的文件的其它用户的权限改为没有任何权限
#!/bin/bash
mkdir -v /tmp/scripts
cd /tmp/scripts
cp -r /etc/pam.d ./test
chown -R redhat ./test
chmod -R o=--- ./test
练习二:写一个脚本
1.显示当前系统日期和时间,而后创建目录/tmp/lstest
2.切换工作目录至/tmp/lstest
3.创建目录a1d,b56e,6test
4.创建空文件xy,x2y,732
5.列出当前目录下以a,x或者6开头的文件或目录
6.列出当前目录下以字母开头,后跟一个任意数字,而后跟任意长度字符的文件或目录
#!/bin/bash
date
mkdir -pv /tmp/lstest
cd /tmp/lstest
mkdir a1d b56e 6test
touch xy x2y 732
ls [ax6]*
ls [[:alpha:]][[:digit:]]*
练习三:写一个脚本
添加10个用户user1到user10,但要求只有用户不存在的情况下才能添加
#!/bin/bash
for I in `seq 1 10`;do
cut -d: -f1 /etc/passwd |grep "user$I" 2>>/tmp/etc.err || useradd user$I
done
练习四:写一个脚本
通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线
如果在线,就显示“ip is up”
如果不在线,就显示“ip is down”
#!/bin/bash
for I in `seq 151 254`;do
ping -c1 -w1 192.168.0.$I &>/dev/null && echo "192.168.0.$I is up" || echo "192.168.0.$I is down"
done
练习五:打印九九乘法表
#!/bin/bash
for i in $(seq 9);#seq用于产生从某个数到另外一个数之间的所有整数
do
for j in $(seq $i);
do
echo -n "$i*$j=$(($i*$j)) ";
done;
echo "";
done
练习六:循环打印日期(可指定起始日期或默认日期),并返回天数
> 循环
>if判断
>date日期
#!/bin/bash
##判断变量,是否为空(如果没有或只有一个,进行默认赋值)
if [ "$1" == "" ]
then
start_date=`date -d "today last month" "+%Y%m01"`
end_date=`date -d "today" "+%Y%m%d"`
else
if [ "$2" == "" ]
then
start_date=`date -d "$1" "+%Y%m%d"`
end_date=`date -d "today" "+%Y%m%d"`
fi
fi
##判断两个变量是否有问题(可扩展,进行可用性识别)
if [ "$start_date" -gt "$end_date" ]
then
echo "ERROR! \nplease input a right date"
exit
fi
##通过循环,返回日期值(包含开始和结束日期,闭区间)
for i in `seq 0 100000`
do
t_date=`date -d "${start_date} +$(($i+1)) day" "+%Y%m%d"`
echo $t_date
cnt_days=$i
##如果循环到当天,就退出
if [ $t_date == $end_date ]
then
break
fi
done
echo "The days between two date is "+$cnt_days+" !"
练习七:写一个脚本 实现进度条功能
#!/bin/bash
#进度条
n=$((100/10))
N=$((100/20))
for i in `seq 500`
do
sleep 0.01
[ $(($i%$n)) -eq 0 ] && echo -ne "\b=" && continue
[ $(($i%$N)) -eq 0 ] && echo -ne "-"
done
echo ""
练习八:写一个脚本 传递两个整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
#!/bin/bash
echo "first number $1" (表示输出第一个数)
echo "second number $2" (表示输出第二个数)
echo " $(($1+$2))" (输出两数之和)
echo "$[$1-$2]" (输出两数之差)
echo "$[$1*$2]" (输出两数之积)
echo "$[$1/$2]" (输出两数之商)
:wq (表示保存并退出vi编辑器)
chmod +x test.sh (给test.sh执行的权限)
./test.sh 2 3 (传递两个参数并执行脚本
#! /bin/bash
##judge your computer's cpu.
##written by zhdya_20171011
cpu=`cat /proc/cpuinfo | grep vendor | awk '{print $3}'`
case $cpu in
GenuineIntel)
echo "This $cpu made from Inter company.";;
AuthenticAMD)
echo "This $cpu made from AMD company.";;
*)
echo "this $cpu made from uncommon company.";;