【Linux】shell基础&知识点(updating)

1.输出重定向

3种数据流:

stdin:标准输入,代码0,重定向符号<<<
stdout:标准输出,代码1,重定向符号>>>
stderr:标准错误输出,代码2,重定向符号2>2>>

>2>覆盖写入
>>2>>追加写入


创建一个py脚本分别输出标准输出和错误输出:

map@gzdt-map-poi-yingxiang-offline04 test$ cat logging_demo.py 
print(1)
print(1 / 0)

标准输出&错误输出分别重定向到两个不同文件:
python logging_demo.py >a.file 2>b.file,或者
python logging_demo.py 1>a.file 2>b.file,1可以省略。

标准输出&错误输出重定向到同一个文件:
python logging_demo.py >c.file 2>&1,或者
python logging_demo.py &> c.file

Q1:怎么理解2>&1?
A1:将文件描述符 2(标准错误)重定向到文件描述符 1(标准输出)。
Q2:为什么python logging_demo.py 2>&1 >c.file不可以?
A2:先2>&1会将标准错误输出重定向到标准输出(一般是终端),之后再重定向标准输出到c.file,这只会改变标准输出到c.file,标准错误输出仍然输出到原标准输出(终端)。

2.命令批量执行(; 、&&、 ||)

;:前后命令不相关的连续执行。例如cat a ; touch b,无论a文件存不存在前面一个命令能否正确执行,后一个命令都会执行,b文件被创建。
&&:前后命令相关的连续执行,只有当前面命令能正确执行($?=0)时,后面的命令才会执行。例如cd dir && pwd,dir存在才会打印dir的路径。
||:前后命令相关的连续执行,只有当前面命令不能正确执行($?≠0)时,后面命令才会执行。前面命令如果能正确执行则后面的命令不再执行。例如cd dir || mkdir dir,如果dir存在,直接进入,不存在则创建。

上面3种方式执行时都是按照从左往右的顺序,只有当左边的命令执行完成才会执行右边的命令。

3.脚本不同方式执行的区别(source、bash、sh、./)

bash、sh、以及相对路径或绝对路径的方式执行,相当于在当前进程中新开了一个子进程用来执行脚本,脚本执行完子进程销毁,子进程中定义的变量&环境不会回传给父进程。
source方式执行相当于在当前进程中执行脚本内容,脚本中的变量&环境操作会影响当前进程。

特别需要注意,管道操作并不会传递环境变量,管道中的每个子进程的环境变量都继承自父进程,例如下面在set_env.sh脚本中设置python环境变量并输出。

map@gzdt-map-poi-yingxiang-offline04 coordinate$ sh ./set_env.sh
Python 2.7.2

map@gzdt-map-poi-yingxiang-offline04 coordinate$ sh ./set_env.sh | python -V
Python 3.6.5
Python 2.7.2

从输出结果也可以看到:管道操作并非后面的进程在前面的进程执行完后启动,而是同时启动,只有当前面进程的标准输出是后面进程的标准输入时,前面进程才会一定先于后面进程执行完。

1)bash与sh的区别:可以简单理解为,bash在sh的基础上,增加了更多的拓展特性,适合编写更复杂的脚本,兼容sh。实际生产环境中很多sh仍然链接指向到bash。
2)./相对路径的方式执行时,具体是bash执行还是sh执行,取决于脚本首行的shebang是#!/bin/bash还是#!/bin/sh

4.理解环境变量

这块刚接触linux的时候可能会比较不容易理解,现在想从进程的角度来理解环境变量。

linux中的环境变量可以分为3个层级:系统级、用户级、会话级。系统级和用户级的修改都需要通过修改相关配置文件实现,修改后如果不重启需要source刷新生效。会话级的环境变量可通过export直接在shell中修改。

日常开发中经常会出现多用户共用linux开发机、多人使用相同用户账号共用linux开发机的情况,每次通过iterm或SecureCRT这样的终端软件连接linux服务器时,都相当于新开了一个会话,其实也就是新起了一个shell进程,这个进程的初始环境变量来源于系统级的环境变量文件和用户级的环境变量文件配置,因为进程间的资源隔离,所以无论是多用户账号登陆,还是单用户账号多人共享登陆,每个shell中的环境变量操作(除非修改用户或系统环境变量配置文件)互不影响,属于会话级别的操作,当断开连接的时候会话结束进程销毁,下次重新连接时新shell进程的环境变量又会根据配置文件初始化。

因此从进程资源的角度来说,只要不修改物理配置文件,是不会影响其它用户的。

补充关于在定时任务crontab中的环境变量,crontab守护进程在执行定时任务时会为每个定时任务新起一个进程,然后在这个新起的进程中执行配置的命令。所以不同的定时任务对环境变量的操作都是隔离的。例如在配置的命令中source env,其实是在新起的进程里source。

5.export

export也是一个环境变量相关的命令。linux中在当前shell中执行一个命令,大多时候都是新起一个子进程执行,这些子进程初始的环境变量继承自当前shell父进程。如果不使用export,当前设置的环境变量只会在当前shell有效,不会继承给子shell。

map@gzdt-map-poi-yingxiang-offline04 coordinate$ value=1
map@gzdt-map-poi-yingxiang-offline04 coordinate$ echo $value
1
map@gzdt-map-poi-yingxiang-offline04 coordinate$ bash
Package bash-completion was not found in the pkg-config search path.
Perhaps you should add the directory containing `bash-completion.pc'
to the PKG_CONFIG_PATH environment variable
No package 'bash-completion' found
bash: /yum: 没有那个文件或目录
manpath: 警告:已经设定了 $MANPATH,忽略 /etc/man_db.conf
manpath: 警告:已经设定了 $MANPATH,忽略 /etc/man_db.conf
map@gzdt-map-poi-yingxiang-offline04 coordinate$ echo $value

map@gzdt-map-poi-yingxiang-offline04 coordinate$
map@gzdt-map-poi-yingxiang-offline04 coordinate$ export value=1
map@gzdt-map-poi-yingxiang-offline04 coordinate$ echo $value
1
map@gzdt-map-poi-yingxiang-offline04 coordinate$ bash
Package bash-completion was not found in the pkg-config search path.
Perhaps you should add the directory containing `bash-completion.pc'
to the PKG_CONFIG_PATH environment variable
No package 'bash-completion' found
bash: /yum: 没有那个文件或目录
manpath: 警告:已经设定了 $MANPATH,忽略 /etc/man_db.conf
manpath: 警告:已经设定了 $MANPATH,忽略 /etc/man_db.conf
map@gzdt-map-poi-yingxiang-offline04 coordinate$ echo $value
1
map@gzdt-map-poi-yingxiang-offline04 coordinate$

所以也为什么能理解,在修改物理配置文件中的环境变量时,为什么都是export xxx=xxx,因为要让登陆时的shell父进程中的环境变量可以被所有子进程继承。

环境变量设置一般遵循export PATH1=PATH2:PATH3:$PATH1的格式,:用来分隔目录路径,表示在原变量值$PATH1的基础上,新增加PATH2PATH3。在使用时会从左往右查找,找到后就不再往后查找。

6.引号的使用

shell中的引号包括单引号''、双引号""、反引号``
单引号:强引用,引号内的任何内容都会被当作字面量处理,不会进行变量替换或者命令替换。
双引号:弱引用,引号内的变量可以被解释替换。
反引号:用于命令替换,反引号内的内容被当作shell命令执行,并将命令的执行结果用来替换原内容。和$()同样的作用,shell中推荐使用$()进行命令替换。

引号在嵌套使用时,遵循从左往右匹配原则,解释方式也只跟最外层引号相关,不受内层引号类型影响。比如shell中拼接一段用双引号包含路径的sql字符串,sql='..."${path}"...'错误,因为最外层单引号,所以内层都会被当字面量解释。可以sql='..."'${path}'"...',后面这种方式相当于3部分拼接而成:..."${path}"...

7.nohup &(后台执行)

还是从进程的角度来理解,每次ssh连接新建会话,都是新起了一个shell进程,这个进程里启动的所有进程,都是它的子进程。当ssh会话关闭 => shell进程关闭 ==> 子进程接收到SIGHUP信号 => 子进程结束。

nohup(no hang up,不挂断)作用就是忽略SIGHUP信号,使得主shell进程结束时子进程不用结束。所以仅使用nohup,就可以保证程序不会因为ssh会话关闭而中断,只是仅使用nohup时会占用当前终端。

nohup时,如果任务的输出没有重定向,会默认将输出写入到命令执行时路径下的nohup.out
文件,且为追加写入。

&作用是将程序放到后台执行,不占用当前终端,与当前会话终端解耦。当前会话关闭后,后台任务正常情况下也会继续执行。

map@gzdt-map-poi-yingxiang-offline04 dir1$ bash a.sh &
[1] 44406
map@gzdt-map-poi-yingxiang-offline04 dir1$ ps -aux | grep 44406
map      44406  0.0  0.0 105884   780 pts/374  S    15:48   0:00 bash a.sh
map      45006  0.0  0.0 107980   860 pts/374  S+   15:48   0:00 grep --color=auto 44406
map@gzdt-map-poi-yingxiang-offline04 dir1$ exit
登出
Connection to gzdt-map-poi-yingxiang-offline04.gzdt closed.

# 重新开启ssh会话后查看该进程
map@gzdt-map-poi-yingxiang-offline04 ~$ ps -aux | grep 44406
map      44406  0.0  0.0 105884   780 ?        S    15:48   0:00 bash a.sh
map      46951  0.0  0.0 107984   860 pts/375  S+   15:48   0:00 grep --color=auto 44406

可以看到任务在正常执行,且pts/374变为了?pts/374变为?表示该任务与启动任务时的会话终端脱离了关联。

pts/xxx(pseudo terminal slave):表示伪终端,远程ssh连接时就属于这种。
?:与任何终端都不关联。

所以一般使用nohup command &确保任务在后台可以正常执行完毕。

last.命令相关

https://blog.csdn.net/atwdy/article/details/137874868

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值