shell 皮毛学习

shell 皮毛学习

序?

先写一个皮毛学习,估计连皮毛学习都不算🤭。后面有时间在补充深入学习🐊(到处留小尾巴)。

额,为啥要学习呢,实际上是因为学习nginx的时候涉及到使用shell脚本实现日志切割。所以想先了解下shell(反正行走江湖,技多不压身。了解一下)。学习资料就时shell脚本学习指南.pdf本来想上传一个免费的上去,不过发现存在重复资源。有需要的可以留言或者私信我留下邮箱。当然网上也有免费资源可以下,只是需要找啦。当然这一篇是不可能有太多东西的,所以基本营养不多,都是基本的,路过的大神多多指点


前言

Shell脚本的三大特性:

  • 简单性:高级解释型语言,可以简洁的表达复杂的操作。

  • 可移植性:使用POSIX定义的功能,使得脚本无需修改就可在不同系统上执行。

  • 易开发:耗时短。即短时间内就可以完成一个功能强大又好用的脚本。

# 授权
chmod +x 

第一个shell脚本

#!/bin/bash -
who | wc -l

Tip: #! /bin/bash - 中的-表示没有shell选项;基于安全考虑,可避免某种程度的欺骗式攻击。#!前后不能有空格等其他字符,否则,执行脚本失败"-bash: ./finduser: bin/sh: bad interpreter: No such file or directory"

几个初级陷阱:

  • 当今的系统,对#! 这行的长度限制从63到1021字符都有,尽量不要让这行长度超过64位字符
  • 脚本是否可移植取决于是否又完整的路径名称
  • 选项之后不要防止任何空白,因为空包会跟着选项一起传递给引用的程序
  • 需要知道解析器的完整路径名称。这可以用来规避可移植问题

shell的基本元素

1、命令与参数

  • 内建命令:Shell本身所执行的命令,为了其必要性和效率,例:cd、 read 、test、echo、 printf等。
  • shell函数:功能健全的一系列程序代码,以Shell语言写成,它们可以像命令那样引用
  • 外部命令:由Shell的副本(新的进程)所执行的命令

一些常见的命令

who:当前系统上登录用户
echo:标准输出
printf:与echo相比,需要在结尾使用\n换行.
基本的I/O重定向:标准输入/输出(<)、标准错误输出(>)----默认三者在终端
tr:translate的简写,主要用于压缩重复字符,删除文件中的控制字符以及进行字符转换操作。
   -s:压缩字符
   -d:删除字符
   -t:字符替换,可以省略
   格式:echo "abcddel" | tr -d "d"  ====> adcel
|:建立管道,program1|program2   //前一个的标准输出为后一个的标准输入
#:注释grep:查找可配合+正则表达式 🐊
# cut:切分文件,具体参考🐊
# awk:一个强大的文本分析工具。🐊

2、变量

不需要声明类型,直接创建即可。

变量的初始值都为空(null)且变量赋值是没有长度限制的,这里要注意shell中变量赋值的时候不要存在空格

# 错误
a = jimmy
# 正确
a=jimmy
  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。
#!/bin/bash
_name=jimmy
echo $_name
echo ${_name}
echo _${name}_
echo _$_name_
##### 下面为输出结果
> ./variablePrc 
jimmy
jimmy
_jimmy_
_

# 这里最后一种形式不是我们想要的结果,只是错误示例展示

POSIX Shell中其他的内置变量:显示时都是$…

?:前一个命令的退出状态
$:Shell进程的进程编号(process ID)
0:Shell程序的名称
!:最近一个后台命令的进程编号.
IFS:内部的字段分隔器.例如单词分隔,一般为空格、制表符或换行.
HOME:根目录
LANG:当前locale的默认名称
PATH:命令的查找路径
PPID:父进程的进程编号
PWD:当前工作目录

POSIX Shell的结束状态:

0:在重定向或单词展开期间
1-125:命令不成功地退出
126:命令找到了,但文件无法执行
127:命令找不到
128:未定义
可以使用exit命令传递一个退出值给它的调用者,退出脚本。

3、echo和printf

echo命令涉及内容比较多,以后会单独进行学习🐊。这里只是简单的说明下

> echo jimmy
jimmy
> echo 'jimmy'
jimmy
> echo "jimmy"
jimmy
> echo "jimmy!"
# 双引号不能打印感叹号 关于这部分后面我们在进行实验学习
-bash: !": event not found

echo 遇到转义序列时,会打印相应的字符。有效的转移序列如下:

序列说明
\a警示字符,通常是ASCII的BEL字符
\b退格
\c输出是忽略最后的换行字符,这个参数之后的任何字符都会被忽略
\f清除屏幕
\n换行
\r回车
\t水平制表符
\v垂直制表符
\反斜杠字符
\0ddd将字符表示成1到3的八进制数值

由于echo有版本上的差异,有UNIX版本间可移植性问题。因此使用printf命令来处理。

printf命令模仿了Cprintf()。几乎复制了该函数的功能

# 这里可以发现 printf不会像echo一样进行
> printf 'jimmy'
jimmy >

printf的完整语法:

printf format-string [ars…]

format-string: 用来描述输出的排列方式,最好为此字符串加上引号

ars:是与格式声明像对应的参数列表

printf只是格式化输出,不会改变任何结果,所以在格式化浮点数的输出时,浮点数结果是不变的,仅仅只是改变了显示的结果。注意看示例里面的浮点数展示

# printfPrc1
#!/bin/bash
printf "%-5s %-10s %-4s\n" No Name Mark     # 三个%分别对应后面的三个参数
printf "%-5s %-10s %-4.2f\n" 1 Sarath 80.34 # 减号“-”表示左对齐
printf "%-5s %-10s %-4.2f\n" 2 James 90.998 # 5s表示第一个参数占用5个字符
printf "%-5s %-10s %-4.2f\n" 3 Jeff 77.564

> ./printfPrc1
No    Name       Mark
1     Sarath     80.34
2     James      91.00
3     Jeff       77.56

printf中还可以加入分行符、制表符等符号。

# printfPrc2
#!/bin/bash
printf "%-s\t %-s\t %s\n" No Name Mark
printf "%-s\t %-s\t %4.2f\n" 1 Sarath 80.34
printf "%-s\t %-s\t %4.2f\n" 2 James 90.998
printf "%-s\t %-s\t %4.2f\n" 3 Jeff 77.564

> ./printfPrc2
No	 Name	 Mark
1	 Sarath	 80.34
2	 James	 91.00
3	 Jeff	 77.56

更多详细的以后在进行逐一学习🐊

4、I/O重定向、管道

  • <改变(标准)输入 a < file

    表示a的输入修改为file

  • >该表(标准)输出 a > file

    表示a的输出到file

  • >> 附加到文件 a >> file 将a的输出附加到 file的结尾处

  • | 建立管道 command1 | command2 将 C1的标准输出修改为 C2的标准输入

    管道命令是可以将俩个程序联通,如果使用< >等需要写如临时文件,然后在执行,这样效率就打打降低了

几个命令是可以结合使用的(下面的例子我没有自己试验,是PDF里面的)

# tr 命令可以查下是啥意思
> tr -d '\r' < dos-file.txt
> tr -d '\r' < dos-file.txt > UNIX-file.txt
> tr -d '\r' < dos-file.txt | sort > UNIX-file.txt
  • 特殊文件(用的比较少,需要的时候在来学习)

    • /dev/null

      if grep pattern myfile > /dev/null

      then

      ​ … 找到模式时

      else

      ​ … 未找到模式时

      fi

    • /dev/tty

5、环境变量

$PATH表示环境变量,具体环境变量是干啥的我就不说了😂

> echo $PATH
bin:/usr/local/git/bin:/usr/local/git/bin:/home/ybyy/bin

这里可以windows不同,linux的环境变量分隔符未:

当然我们也可以修改环境变量

PATH = $PATH:$HOME/mybin

Shell脚本的循环、条件、计算、判断

1、替换运算符

${var:-jimmy}:若var存在且非null,则返回其值;否则,返回jimmy.
用途:若变量未定义,返回默认值.
${var:=jimmy}:若var存在且非null,则返回其值;否则,设置其为jimmy,并返回值.
用途:若变量未定义,设置默认值.
${var:?msg}:若var存在且非null,则返回其值;否则,显示var:msg,并退出当前命令或脚本.
用途:为了捕捉由于变量未定义所导致的错误.
${var:+jimmy}:若var存在且非null,则返回jimmy;否则,返回null.
用途:为测试变量的存在.
例如:若count已定义,则${count:+1}返回1.

2、模式匹配运算符:

${path#/*/}
${path%.*}
${#var}:返回var值里的字符串长度.

#匹配的是前面(左),
%匹配的是后面(右).
//,匹配任何位于两个斜杠之间的元素;.,匹配点号之后接着的任何元素.

3、位置参数:

Shell脚本中的命令行参数;同时也表示Shell函数中的函数参数。其名称由单个整数命名,且当这个整数大于9时,需{}

echo arg1 is $1    
echo arg10 is ${10}    //表示命令行的第10个参数

$#:统计参数总数.
∗ 、 *、 @:将所有命令行参数视为单个字符串.
∗ " : 带 双 引 号 , 将 所 有 命 令 行 参 数 视 为 一 个 字 符 串 . " *":带双引号,将所有命令行参数视为一个字符串. " "."@”:带双引号,保留真正的参数值,即显示正确的参数.【正确显示命令行参数】
shift:截去来自列表的位置参数,由左开始.默认shift等同于shift 1,即将第一个参数移除
例: shift 10:截去第10个参数,若总数不足10个,则该语句不起作用

4、判断语句

# if -- then -- elif -- else --fi
# 写判断条件时,语法格式必须((...)),若以否定状态表达,则在条件前加入!即可.

i=168
if ((i<10))
then echo "<10"
elif ((i<200))
then echo "<200"
else 
echo "fail"
fi

# case  每个条件用)结尾,且;;表示结束,类似java中的break,*表示默认匹配模式,类似java中的default。
case $1 in     
    10)
    echo "10"        
    ;;    
    2)
    echo "2"    
    ;;        
    *)
    echo "other"    
    ;;
esac

5、循环

# 简单的循环语句:
for i in "$@"
	do echo i is $i
done

for var in item1 item2 ... itemN; do command1; command2… done;

for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

# while 循环
while condition
do
    command
done

# until循环
until condition
do
    command
done

6、Shell中自增的几种格式

((count++))
let count+=1
let count++
# $((...)):Shell中的算术运算。
# ((...)) 推荐--新写法
count=$((count+1)) 
# ``反引号,而非单引号,原始形式
count=`expr $((count+1))` 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值