shell 命令 第一篇

269 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、shell介绍

1585616889678.png

  1. shell是用户与操作系统交互工具,桥梁
  2. 它本身是一个应用程序,可以使用echo $$来查看它的pid
  3. shell贝壳的意思,像一个贝壳一样将操作系统包裹起来,供用户交互使用

在开发过程中,需求:统计一个日志中错误日志的条数:

  1. c,python,java,开发效率很低,需要2小时
  2. shell,几个命令就可以搞定了

运维上的需求,打包,编译,预处理,批量的、重复性的操作,我们可以快速的使用shell脚本进行完成。

shell开发人员是必须掌握的技能!

主流的shell工具:

  1. sh,直接执行sh命令,可以进入到sh的shell终端,也可以与操作系统进行交互

  2. csh

  3. bash 《== 最重要的,使用两种方式查看当前用户终端的默认shell:

    1. echo $SHELL
    2. vi /etc/passwd
  4. 小技巧:当我们紧急处理一个任务的时候,可以使用ctrl+z将当前的vi放到后台,再使用fg进行唤醒(避免反复退出vim)

  5. whoami, 查看当前登陆用户

  6. echo $$,可以查看当前pid

  7. 同时编辑两个vim文件的技巧

    1. 打开1.txt
    2. 输入 : tabe 2.txt
    3. 使用gt在两个文件中快速切换

二、内建命令-外部命令

命令:

cd, ==> 内建命令(buildin)

chmod ==》 外部命令

1585618617459.png

如何判断一个命令的类型:

  1. type 加上命令
  2. which 加上命令, 如果没有找到这个命令的位置,则说明他是内建命令

区别:

  1. 内建命令是不需要启动子进程的,而是在当前的进程下去调用一个普通的函数,产生的效果直接作用在当前终端(cd , source, . ), 回想一下source ~/.bashrc

    小技巧:将常用目录设置成变量,定义在.bashrc中,cd $c39,可以快速切换

  2. 外部命令:bash会先fork一个子进程,内部调用exec,执行程序,执行完毕后退会到bash中

三、执行脚本方法

shell

shell命令:cd 、ls

shell脚本(shell script):把shell命令按照一定的逻辑进行编程,完成既定步骤比较多的任务。

#!/bin/bash     #注意,这不是注释echo "hello world"cd ..
ls
touch c39.txt
  1. 一个shell脚本必须指定解析器,明确下面的命令使用哪个解析器:bash, sh

  2. #! ==> 开头是固定的

  3. shell使用#号作为注释

  4. shell没有主函数,也不需要编译,它是解释性语言,而不是编译性语言(c,c++)

  5. shell脚本的执行顺序就是从上到下

  6. 如果一个命令在解析器之上,是不会被解析的,但是不会报错

  7. 常见执行方式:

    1. chmod +x hello.sh , 使用 ./hello.sh执行
    2. 明确指定解析器,/bin/bash hello.sh , 也可以,而且不需要hello.sh有执行权限
    3. (cd ..;ls),使用括号的方式,也可以启动子进程执行,而不是影响当前进程
  8. 执行脚本的逻辑:

    1. bash在执行shell脚本时,启动一个子进程,进行exec处理,退出

四、基本语法

1. 变量相关:

#!/bin/bash#定义变量不需要指定类型,int float#定义变量时,等号两边不要有空格,否则会报错
name="Lily"#使用$进行遍历的引用
echo $name
echo name
​
​
#如果在变量解析的时候,涉及到边界划分问题,可以使用${}方式,来进行划分
#helloa
a="hello"
aa="world"
echo $a
echo ${a}a

结果:

1585622418307.png

2.单引号-双引号-反引号

  1. 单引号:所见即所得,不会解析里面的变量
  2. 双引号:所见非所得,里面可以包含变量,会先解析变量,在赋值
  3. 反引号:会事先对命令进行解析,得到的结构再进行赋值

案例:

#!/bin/bash
​
name=lily
​
person="$name is a good girl"
person1='$name is a good girl'echo "person: $person , person1: $person1"touch a.txt b.txt
v1="a.txt b.txt"ls $v1
echo "-----------"
ls "$v1"   #<<=== 经验老道都这样写!
​
​
d0=date  
d1=`date`  #《== tab键上面的
d2=$(date)  #与``效果相同echo "d0: $d0"
echo "d1: $d1"
echo "d2: $d2"
​
curPath=$(cd `dirname $0`;pwd)
#curPath=$(cd dirname $0;pwd) #此时会报错,too many arguments
echo "curPath: $curPath"

结果:

1585623140764.png

此时,程序将 "a.txt\ b.txt"当成一个文件去查找了,所以报错

注意点:所有使用变量的地方,尽量使用双引号将变量包裹起来 "var",而不用直接使用var", 而不用直接使用 var,尤其是在if,for里面,如果变量不加双引号,会经常出bug

3. 变量分类

shell内变量:

  1. 分为全局变量,局部变量local修饰的,不能在进程间传递

环境变量,最出名的环境变量:PATH

  1. 加上了export之后,就会变成环境变量
  2. 环境变量可以在当前进程已及子进程之间都可以使用
  3. 子进程的环境变量无法传递给父进程, 只能单向传递
#!/bin/bash
​
​
export school=浙江大学
​
echo "address" $address  #事先在bash终端中设置了  export addrss="Beijing"
echo 111111 : $name#全局的内变量
name=Lily
echo 222222 : $name
​
​
function testfunc()
{
    #局部内变量,只能在自己的作用域中使用
    local age=20
    echo 333333 : $age
}
​
testfunc
​
echo 444444 : age :$age , name : $name
​
/bin/bash 4.1.子进程.sh
​

4.1.子进程.sh:

#!/bin/bashecho "school :" $school
echo "name :" $name

结果:

address 黑龙江
111111 :
222222 : Lily
333333 : 20
444444 : age : , name : Lily
school : 浙江大学
name :

1585625598155.png

可以使用env来查看环境变量(export修饰的)

可以使用set命令来查看所有变量(包括环境变量和普通变量)

可以使用unset命令来删除变量的值(置空)

1585626280207.png

4.通配符

    • ==> 最常用的,代表0或多个任意字符
  1. ?==> 匹配任意1个字符
  2. [] ==》方框中的任意数字出现1次
touch {1..9}.txt
touch {a..h}.sh
mv 1.txt 111.txt
mv c.sh cccc.sh
​
ls *.txt
ls ?.txt
ls [123ght].txt

5. 转义字符

  1. 特殊字符变成普通字符

    echo $SHELL

  2. 把普通字符变成特殊字符

    \r\n ==> 换行回车

1585627012884.png

  1. 一行文字过多时,可以使用\进行换行

1585635391003.png