shell学习

Shell是用户与Linux操作系统沟通的桥梁

Linux的Shell种类众多,这里我们学习的是bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被

广泛使用,同时,Bash也是大多数Linux系统默认的Shell。

文件名后缀通常是.sh

#!/bin/bash

#这里是注释

在一般情况下,人们并不区分 Bourne Shell和Bourne Again Shell,所以,在这里,我们可以看到#!/bin/bash,它同样

也可以改为#!/bin/sh。


shell单步调试:bash -x test.sh

shell语法检查:bash -n test.sh


变量

变量不需要声明,初始化不需要指定类型

变量命名

1:不能使用程序中的关键字(保留字)

2:只能使用数字,字母和下划线,且不能以数字开头

3:建议命令要通俗易懂

显示变量值使用echo命令 ,加上$变量名,也可以使用${变量名}

例如:echo $JAVA_HOME  或者 echo ${JAVA_HOME}


变量分类


本地变量:

只对当前shell进程有效的,对子进程和其它shell进程无效。

定义:VAR_NAME=VALUE 不能有空格

变量引用:${VAR_NAME}

取消变量:unset VAR_NAME


环境变量:

自定义的环境变量对当前shell进程及其子shell进程有效,对其它的shell进程无效

定义:export VAR_NAME=VALUE

对所有shell进程都有效需要配置到配置文件中

vi /etc/profile

source /etc/profile


局部变量:

函数调用结束,变量就会消失 对shell脚本中某代码片段有效

定义:local VAR_NAME=VALUE


位置变量:

$1,$2,.....${10}....

/tmp/test.sh a b

$0:脚本自身路径全名

$1:脚本的第一个参数

$2:脚本的第二个参数


特殊变量:

$?:接收上一条命令的返回状态码 如果执行成功,返回的状态码是0,执行失败的状态码在1-255之间 echo $?

$#:参数个数,可用于在脚本中用$#获取传入参数个数

$*:或者$@:所有的参数 ,可用于在脚本中用$*或$@获取传入的所有参数

$$:获取当前shell脚本的进程号,可以在脚本中使用$$获取当前脚本进程号


单引号、双引号、反引号

''单引号不解析变量

""双引号会解析变量

``反引号是执行并引用一个命令的执行结果,类似于$(...)


for循环

通过使用一个变量去遍历给定列表中的每个元素,在每次变量赋值时执行一次循环体,直至赋值完成所有元素退出循环
格式1
for ((i=0;i<10;i++))
do
  ...
done
格式2
for i in 0 1 2 3 4 5 6 7 8 9
do
...
done
格式三
for i in {0..9}
do
  ...
done


条件测试

bash条件测试
     命令执行成功与否即为条件测试
          test EXPR
          [ EXPR ]:注意中括号和表达式之间的空格
     整型测试:
          -gt:大于:例如[ $num1 -gt $num2 ]
          -lt:小于
          -ge:大于等于
          -le:小于等于
          -eq:等于
          -nq:不等于
     字符串测试:
          >:大于[ "$str1" \> "$str2" ]
          <:小于
          =
          !=


算术运算

let varNamer=算术表达式

varName=$[算术表达式]

varName=$((算术表达式))

varName=`expr $num1 + $num2`


while/until循环

适用于循环次数未知,或不便用for直接生成较大的列表时
 格式:
while 测试条件
do
    循环体
done
 如果测试条件为“真”,则进入循环,退出条件为,测试条件为假。
until循环的格式和while循环的格式一致,但是和while循环的意思相反,如果测试条件为假,则进入循环,退出条件为,测试条件为真


if判断

单分支
 if 测试条件;then
    选择分支
 fi
双分支
 if 测试条件
  then
   选择分支1
   else
   选择分支2
   fi
多分支
     if 条件1; then
               分支1
          elif 条件2; then
               分支2
          elif 条件3; then
               分支3
          ...
          else
               分支n
          fi



例子:

if [ $1 -eq 1 ]
then
echo "one"
elif [ $1 -eq 2 ]
then
echo "two"
else
echo "none"
fi


case判断

有多个测试条件时,case语句会使得语法结构更清晰
格式: case 变量引用 in
               PATTERN1)
                         分支1
                         ;;
               PATTERN2)
                         分支2
                         ;;
               ...
               *)
                         分支n
                         ;;
               esac
PATTERN :类同于文件名通配机制,但支持使用|表示或者
a|b:a或者b
*:匹配任意长度的任意字符
?:匹配任意单个字符
[]:指定范围内的任意单个字符


例子:

#!/bin/bash

case $1 in
1)
echo "one"
;;
2)
echo "two"
;;
3)
echo "three"
;;
*)
echo "none"
;;
esac


自定义函数

function 函数名(){
  ....
}

引用自定义函数文件时,使用source  func.sh有利于代码的重用性


定义fun1.sh

#!/bin/bash

function test(){
echo "hello world"
}


定义fun2.sh直接调用test()函数

#!/bin/bash

source /usr/local/fun1.sh
test


date

显示当前时间

格式化输出

date "+%Y-%m-%d %H:%M:%S"

格式%s表示自1970-01-01 00:00:00以来的秒数

date +%s

指定时间输出 

date --date='2009-01-01 11:11:11'

指定时间输出 

date --date='3 days ago'

获取指定日期自1970-01-01 00:00:00以来的秒数

date --date='2009-01-01 11:11:11' +%s


read

read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变

量中。

格式

read VAR_NAME

read -p "Enter your name:" VAR_NAME  有提示信息Enter your name:

read如果后面不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中

read -t 5 -p "enter your name:" VAR_NAME   倒计时5秒钟

read  -s  -p "Enter your password: " pass    秘密的输入,看不到输入的内容


declare

用来限定变量的属性

-r 只读

#!/bin/bash

num=0
echo $num 输出0
declare -r num
num=1
echo $num 输出0


-i 整数:某些算术计算允许在被声明为整数的变量中完成,而不需要特别使用expr或let来完成。

#!/bin/bash

declare -i num
let num=1+1
echo $num


-a 数组


字符串操作


获取长度:${#VAR_NAME} 

name=zhangsan

echo ${#name} 输出8


字符串切片

name=zhangsan

${string:offset:length}

echo ${name:2:3} 输出ang


取尾部的指定个数的字符

name=zhangsan

 ${string: -length}:注意冒号后面有空格

echo ${name: -3} 输出san


取子串:基于模式

${variable#*word}  从左往右取第一个word后面的字符串

name=zhangsan

echo ${name#*a} 输出ngsan


${variable##*word} 从左往右截取第二个word后面的字符串

name=zhangsan

echo ${name##*a} 输出n


${variable%word*} 从右往左取第一个word后面的字符串

name=zhangsan

echo ${name%a*} 输出zhangs


${variable%%word*} 从右往左取第二个word后面的字符串

name=zhangsan

echo ${name%%a*} 输出zh


查找替换:

${variable/pattern/substr}替换第一次出现

${variable//pattern/substr}替换所有的出现

${variable/#pattern/substr}替换行首的pattern,如果行首没有此字符串,则不替换

${variable/%pattern/substr}替换行尾的pattern,如果行尾没有此字符串,则不替换

查找删除

${variable/pattern}删除第一次匹配的字串

${variable//pattern}删除所有匹配的字串

${variable/#pattern}删除行首匹配的字串

${variable/%pattern}删除行尾匹配的字串

大小写转换

小-->大:${variable^^}

大-->小:${variable,,}


变量赋值操作

${parameter:-word}

如果变量parameter的值为空或者不存在,返回结果为word,此时变量parameter的值依然为空

${parameter:=word}

如果变量parameter的值为空或者不存在,返回结果为word,此时将word赋值给变量parameter

${parameter:?word}

如果变量parameter的值为空或者不存在,则把word当作错误信息返回。

${parameter:+word}

如果变量parameter的值存在,返回结果为word。如果变量不存在,则返回为空。


数组

定义:declare -a:表示定义普通数组

特点

支持稀疏格式

仅支持一维数组

数组赋值方式

一次对一个元素赋值a[0]=$RANDOM

 一次对全部元素赋值a=(a b c d)

按索引进行赋值a=([0]=a [3]=b [1]=c)

命令替换 logs=($(ls /var/log/*.log)) 将/var/log/下所有的.log文件名作为数组元素存储在logs数组中

使用read命令read -a ARRAY_NAME

获取数组的长度

${#ARRAY[*]}

${#ARRAY[@]}

注意:${#ARRAY}表示获取数组中的第一个元素的长度,等于${#ARRAY[0]},等于$ARRAY

从数组中获取某一片段之内的元素

格式: ${ARRAY[@]:offset:number}

offset:偏移的元素个数

number:取出的元素的个数

${ARRAY[@]:offset}:取出偏移量后的所有元素

${ARRAY[@]}:取出数组中的所有元素

数组复制:(建议使用${ARRAY[@]})

$@:每个参数都是一个独立的串

$*:所有参数是一个串

 删除元素:

unset ARRAY[index]


脚本后台运行,执行

sleep.sh &  但是如果关闭终端就会退出。因为终端关闭时终端会发送hangup命令停止该终端的所有进程

可以使用:nohup sleep.sh & 这样即使关闭终端脚本仍然继续执行着,输出日志可查看当前路径的nohup.out


标准输入、输出、错误

标准输入、输出、错误都是命令行,使用文件描述符0、1、2引用

cat  >  catfile  <  ~/.bashrc

ls >file 或者 ls 1>file 这样把每次的输出都会覆盖进file,如果想追加在原内容后面可以使用ls >> file

lk 2>file(lk是一个错误命令)

使用重定向可以把信息转换到其他位置

ls folder 2> /dev/null  将错误信息扔进黑洞

ls folder 1>/dev/null 2>&1 将正确信息和错误信息全扔掉


crontab定时器

使用crontab -e 添加定时任务

* * * * * echo 'date' >> /usr/local/date.log


每分钟输出时间信息,里面指定的文件或脚本必须是全路径

* * * * * echo 'date' >> /usr/local/shell.sh


每分钟执行shell.sh脚本,必须是全路径

可以使用tail -f /usr/local/date.log监控输出结果

crontab定时任务可以执行的前提是必须启动cron服务:service crond start。查看状态:service crowd status


ps用来显示当前shell启动的进程相关信息

ps -e 显示系统中所有进程

ps -ef | grep bash

jps显示所有java进程,但是有时候查看不到,可以使用ps -ef|grep java查看


在编写批量执行脚本,需要ssh到远程服务器执行的脚本时,由于ssh到远程服务器时,不会主动加载/etc/profile只会

加载~/.bashrc或/tmp/bashrc,所以需要将source /etc/profile命令添加到bashrc脚本中,批量脚本才能正确加载到远

程服务器的环境变量,脚本才能正确执行。


vi小技巧

非编辑模式下:

查找字符串:/string   找到后按n找下一个

按:输入数字,跳到指定行

复制一行:光标移到该行任意位置,按两下yy,复制完毕。再按p粘贴。要复制两行先按2,光标移到第一行按yy。

跳到最后一行:大写g




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值