linux基础知识-19
Tofloor
poster avatar
老陌
deepin
2018-07-20 22:46
Author
参见老陌博客: https://www.cnblogs.com/myccloves/p/9341320.html


一、shell脚本初邂逅
把多条命令写到文件中,之后交给解释器一条一条的执行,这个解释器是/bin/bash,这个文件就是脚本。

下面老陌就编写一个脚本,用来显示当前时间和当前登录到系统的用户。 文件名用post.sh,其实文件名无所谓,自已喜好。

  1. #!/bin/bash
  2. date
  3. who
Copy the Code

其中#!/bin/bash是我们选择的解释器,告诉我们用bash来解释下面的代码。date显示日期,who显示谁登录了系统。可以看出脚本就是一条条命令堆在一起。

脚本的第一行必须指定用哪个解释器, 看来不只是/bin/bash一个解释器。
给脚本一个可执行权限,这个老陌会加权限。
执行脚本时需要指定脚本所在的路径,或把脚本加入到系统路径PATH中。你也可以把脚本复制到/bin目录中,因为/bin在PATH里了。
对于上面的脚本添加可执行权限,运行:

  1. chmod u+x ./post.sh
  2. ./post.sh
Copy the Code


原来就是这样简单。对于老陌这样的小白,计算机瘫痪经常事,所以练就了重装系统的强大本领。老陌想能不能把需要的软件写个脚本一次性安装呢?老陌准备下一次安装系统时就试一试。

二、返回值
linux系统中每个进程都有寿命。 每个进程通过另一个进程的请求而启动。发出请求的进程称为父进程,新启动的进程称为子进程。

子进程也可能再产生子进程,当子进程任务完成后退出,退出时会返回信息给父进程,叫做返回值或退出状态。



父进程可以收集子进程的返回值。(我倒!腐败无处不在啊)

返回值以整数的形式出现,范围是0-255。程序可以在退出时随意选择返回值。linux中规定返回0表示成功,以外的数表示程序运行失败。返回值保存在 $? 的特殊变量中。

  1. linux@myccloves:~$ ./post.sh
  2. Thu Jul 19 20:45:14 CST 2018
  3. linux    tty1         2018-07-19 14:35 (:0)
  4. linux    pts/2        2018-07-19 20:32 (172.16.18.113)
  5. linux@myccloves:~$ echo $?
  6. 0
  7. linux@myccloves:~$ cat /etc/shadow
  8. cat: /etc/shadow: Permission denied
  9. linux@myccloves:~$ echo $?
  10. 1
Copy the Code

我们运行自己写的脚本,由于返回值保存到 $? 中,所以我们打印一下看看:echo $? ,通过观察老陌写的脚本返回0,表示成功运行。再用cat查看一下密码文件,提示权限拒绝,看来运行打脸了,人家不让看。用echo $? 打印返回值,结果不是0,表示失败。

总结一下:

  • 每个命令是一个进程,退出命令向父进程返回一个整数值
  • 返回的整数值交给变量$?


提示:echo $? 这也是一条命令,也有返回值。所以打印命令是否成功你只能用一次echo $?, 第二次就不是原先那条命令的返回值了。

三、有条件的运行多个命令
之前我们学习过用;分隔命令,之后一条一条执行。但是有些时候下一条命令根据上一条命令的结果才决定执行与不执行,需要用 &&和|| 把两个命令有条件地连接在一起。

(一) &&
描述这样一个场景,老陌领着小白们去砸场子,如果砸第一家成功,再砸第二家。(第一条命令运行成功,再运行第二条)

  1. linux@myccloves:~$ mkdir /tmp/砸第一家 && echo "走,去砸第二家"
  2. 走,去砸第二家
Copy the Code

我们发现第一条命令:mkdir /tmp/砸第一家,运行成功后,会运行 echo "走,去砸第二家"。 也就是说用&&连接的两条命令,第一条命令运行成功之后才会运行第二条,如果不成功呢?

  1. linux@myccloves:~$ mkdir /砸第一家 && echo "走,去砸第二家"
  2. mkdir: cannot create directory ‘/砸第一家’: Permission denied
Copy the Code

这次我们发现没打过第一家,运行失败,所以不会执行第二条命令。

(二) ||
||也是用于连接两条命令,如果第一条命令运行失败,再运行条二条,否则不运行第二条。

  1. linux@myccloves:~$ mkdir /tmp/砸第一家 || echo "大哥,没打过啊,上医院吧"
Copy the Code

通过观察,没有输出,表示运行成功。也就是第一条成功了,就不执行第二条了。

  1. linux@myccloves:~$ mkdir /砸第一家 || echo "大哥,没打过啊,上医院吧"
  2. mkdir: cannot create directory ‘/砸第一家’: Permission denied
  3. 大哥,没打过啊,上医院吧
Copy the Code

通过观察,输出了“大哥,没打过啊,上医院吧”,第一条命令失败,所以执行第二条命令。

总结一下:

  • 多条命令用;隔开,依次执行
  • 多条命令用&&,||隔开,根据前面的执行是否成功,再判断是否执行第二条命令。


四、bash变量
我们可以自己定义变量和引用变量。

(一)shell变量有两种类型:
  • 局部变量
  • 全局变量

局部变量只能在创建它的shell中使用,全局变量也叫环境变量,可以在创建它的shell和子shell中使用,也就是在子shell中可以访问父shell中定义的变量。

(二)定义与访问局部变量:
  1. linux@myccloves:~$ name=老陌
Copy the Code

变量名=变量的值 ,通过这种方式定义变量 ,这里要注意等号两边不能有空格。如果想要访问这个变量,则用:$+变量名 , 如:

  1. linux@myccloves:~$ echo $name
  2. 老陌
Copy the Code

老陌发现:
  1. linux@myccloves:~$ echo "欢迎" $name "$name" '$name'
  2. 欢迎 老陌 老陌 $name
Copy the Code

在命令里面,$name读取这个变量的值,放到双引号中,依然读取变量的值,但放到单引号中就原样输出了。

(三)变量的命名规则
  • 由[a-zA-Z0-9_]组成的任意名字,但不能以数字开头
  • 变量名区分大小写

比如下面的名字因为大小写不同,则shell就不认识了。

  1. linux@myccloves:~$ name=老陌
  2. linux@myccloves:~$ echo 欢迎$name同学。
  3. 欢迎老陌同学。
  4. linux@myccloves:~$ echo 欢迎$Name同学。
  5. 欢迎同学。
Copy the Code

那些没有被定义的变量shell解析的时候当成空值。就当空气吧,看看输出时啥也没有。

(四)变量赋值要注意的问题:
  1. linux@myccloves:~$ name=What is your name?
  2. bash: is: command not found
  3. linux@myccloves:~$ name="What is your name?"
  4. linux@myccloves:~$ echo $name
  5. What is your name?
Copy the Code

当有多个单词时,之间会有空格,这样必须用双引号或单引号括起来,当成一个整体对待。我们发现,如果没有引号,提示错误了。

(五)访问变量的另一种方法:
老陌想要拼接一些字符串,我们一起分析一下:

  1. linux@myccloves:~$ word=he
  2. linux@myccloves:~$ echo $word
  3. he
  4. linux@myccloves:~$ echo $word llo
  5. he llo
  6. linux@myccloves:~$ echo $wordllo

  7. linux@myccloves:~$
Copy the Code

首先定义变量word,值为he,之后测试成功的输出he,之后打印变量和后面跟上的部分字符,输出he llo。但老陌发现多了一个空格,这不是老陌要的,老陌要一个完整的单词,所以$wordllo,但结果是空值……
因为shell把wordllo当成变量名了,而不是用户想的先输出$word,再输出llo

这种情况我们用另一种方法访问变量:

  1. linux@myccloves:~$ echo ${word}llo
  2. hello
Copy the Code

这种通过${变量名}的方式访问就不会出错了。原来访问变量有两种方法。

  • $变量名
  • ${变量名}


五、SHELL中定义的变量
只读变量


这里面我们熟悉返回值等,但老陌不明白的!,还有-,SHELLOPTS以后再说,不明白的原因是不理解其意义。

预赋值变量


这几个变量不难理解,而且老陌发现,这些SHELL全是大写的。

六、环境变量
环境变量就是上面说的全局变量,可以被子shell继承的变量。

创建环境变量的方法:
  • 先定义变量
  • 提升变量为环境变量

以下面的例子说明:

  1. linux@myccloves:~$ name=老陌
  2. linux@myccloves:~$ export name
  3. linux@myccloves:~$ age="very old"
  4. linux@myccloves:~$ bash
  5. linux@myccloves:~$ echo $name $age
  6. 老陌
  7. linux@myccloves:~$ exit
  8. exit
  9. linux@myccloves:~$ echo $name $age
  10. 老陌 very old
Copy the Code

首先定义变量name,之后提升为全局变量, 再定义变量局部变量age。之后启用子shell,在子shell中访问name与age变量,发现name被继承下来,但age是局部变量则不可以访问。

当退出之后,再次访问这两个变量,都成功输出。说明退出子shell又回到了父shell,所以局部变量可用了。

我们可以把上面的两步合成一步。
  1. export name=老陌
Copy the Code

七、列出变量
set命令和env命令可以查看更多的变量。其中set列出了shell变量和与shell有关的环境变量,而env只列出环境变量。

老陌运行了一下,发现了大量的变量,之前接触过的都在里面了。

常用的环境变量

昨天老陌还在论坛求助,fc命令默认的编辑器怎么变成了nano,后来有朋友留言说设置EDITOR这个环境变量就可以,今天终于学到了。

实例:配置环境变量PATH

帖子太长,超10000字符了,不让提交,请参见老陌博客继续阅读:

https://www.cnblogs.com/myccloves/p/9341320.html

Reply Favorite View the author
All Replies
avatar
kingskill
deepin
2018-07-21 23:08
#1
顶一下~~~~
Reply View the author
avatar
whoam1
deepin
2018-07-21 23:45
#2
....
Reply View the author
avatar
135******79
deepin
2018-07-22 01:16
#3
我只想说一句,老陌你把的头像太丑了,每次看到都感觉是个光蛋头。
Reply View the author
avatar
老陌
deepin
2018-07-22 02:40
#4
https://bbs.deepin.org/post/166393
我只想说一句,老陌你把的头像太丑了,每次看到都感觉是个光蛋头。

啊,半斤八两,你的头像很也酷。哈哈。
Reply View the author