shell 基础

目录

shell是什么?

shell ps -ef | grep xxx

shell 环境变量配置

shell 环境变量

shell  /dev/null

shell  2>/dev/null、>/dev/null 2>&1、2>&1>/dev/null

shell  ` `

shell  |

shell  $1、$#、$@、$0、$1、$2

shell xargs

未梳理部分

 


shell是什么?

参考文章https://baike.baidu.com/item/GNOME/5105879?fr=aladdin

当谈到命令时,我们实际上指的是shell。shell是一个接收由键盘输入的命令,并将其传递给操作系统来执行的程序。几乎所有的Linux发行版都提供shell程序,该程序来自于称之为bash的GNU项目。

bash是Bourne Again Shell的首字母缩写,Bourne Again Shell基于这样一个事实,即bash是sh的增强版本,而sh是最初的UNIX shell程序,由Steve Bourne编写。

 

什么是终端?

当使用图形用户界面时,需要另一种叫做终端仿真器(terminal emulator)的程序与shell进行交互。如果我们仔细查看桌面菜单,那么很可能会找到一个款终端仿真器。

在KDE环境下使用的是konsole,而在GNOME环境下使用的是gonme-terminal,但在桌面菜单上很可能将它们简单地统称为终端

在Linux系统中,还有许多其他的终端仿真器可以使用,但是它们基本上都做同样的事情:让用户访问shell

 

GNOME(全称:The GNU Network Object Model Environment 是一套纯粹自由的计算机软件,运行在操作系统上,提供图形桌面环境

GNOME 包含了 Panel (用来启动此程式和显示目前的状态)、桌面 (应用程式和资料放置的地方)及一系列的标准桌面工具和应用程式,并且能让各个应用程式都能正常地运作。

GNOME是Linux操作系统上最常用的图形桌面环境之一。

shell ps -ef | grep xxx

参考文章《ps -ef |grep 输出的具体含义》https://blog.csdn.net/g56467467464/article/details/82993965

命令拆解:
ps:将某个进程显示出来

-A  显示所有程序。 
-e  此参数的效果和指定"A"参数相同。
-f  显示UID,PPIP,C与STIME栏位。 

grep命令是查找

中间的|是管道命令 是指ps命令与grep同时执行
这条命令的意思是显示有关Apachejetspeed有关的进程
UID PID PPID C STIME TTY TIME CMD

各相关信息的意义:

UID: 程序被该 UID 所拥有
PID :就是这个程序的 ID 
PPID :则是其上级父程序的ID
C: CPU 使用的资源百分比
STIME :系统启动时间
TTY: 登入者的终端机位置
TIME: 使用掉的 CPU 时间
CMD :所下达的指令为何

shell 环境变量配置

参考文章 https://www.cnblogs.com/ultimateWorld/p/9028303.html 和 IT黑马

 

 

1.linux中/etc/profile 和 ~/.bash_profile 的区别

在 linux中设置环境变量一般使用bash_profile进行配置

其中/etc/bash_profile 表示系统整体设置 ,生效后系统内所有用户可用

而 ~/.bash_profile 只表示当前用户的个人设置,生效后只该用户可用。

 

来自 <https://www.cnblogs.com/ultimateWorld/p/9028303.html>

 

2.bash_profile 配置

1、打开Terminal(终端)

2、输入:vi ~/.bash_profile

3、设置PATH:export PATH=/mongodb/bin:$PATH

4、输入::wq    //保存并退出vi

5、修改立即生效:source ~/.bash_profile

6、查看环境变量的值:echo $PATH

7、如果bash_profile存在的情况下,可以通过open  ~/.bash_profile的命令打开,编辑好后再执行5的方式

 

注意:1、~/.bash_profile中有个点

2、如果是新增环境变量或者是修改环境变量的值,都需要source一下才能立即生效。如果是删除一个环境变量,必须输入exit以logout当前shell,然后再重新打开一个新的shell并login才能生效

 

来自 <https://www.cnblogs.com/chrissong/p/10740404.html>

3.Linux中设置环境变量小结【必看】

 

  在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现“command not found”的提示内容。如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。

【是的,我就是这样。】

shell 环境变量

参考文章 https://blog.csdn.net/csf111/article/details/7296443

1、总结背景
    在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现“command not found”的提示内容。
如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。这涉及到环境变量PATH的设置问题,而PATH的设置也是在linux下定制环境变量的一个组成部分。本案例基于RedHat AS4讲解环境变量定制的问题。

2、变量简介
    Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

3、定制环境变量
    环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell。对于Linux来说一般是bash,但也可以重新设定或切换到其它的Shell(使用chsh命令)。
根据发行版本的情况,bash有两个基本的系统级配置文件:/etc/bashrc和/etc/profile。这些配置文件包含两组不同的变量:shell变量和环境变量。前者只是在特定的shell中固定(如bash),后者在不同shell中固定。很明显,shell变量是局部的,而环境变量是全局的。环境变量是通过Shell命令来设置的,设置好的环境变量又可以被所有当前用户所运行的程序所使用。对于bash这个Shell程序来说,可以通过变量名来访问相应的环境变量,通过export来设置环境变量。

【注】:Linux的环境变量名称一般使用大写字母

4、环境变量设置实例
1).使用命令echo显示环境变量
本例使用echo显示常见的变量HOME
$ echo $HOME
/home/kevin

2).设置一个新的环境变量
$ export MYNAME=”my name is kevin”
$ echo $ MYNAME
my name is Kevin

3).修改已存在的环境变量
接上个示例
$ MYNAME=”change name to jack”
$ echo $MYNAME
change name to jack

4).使用env命令显示所有的环境变量
$ env
HOSTNAME=localhost.localdomain
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
SSH_CLIENT=192.168.136.151 1740 22
QTDIR=/usr/lib/qt-3.1
SSH_TTY=/dev/pts/0
……

5).使用set命令显示所有本地定义的Shell变量
$ set
BASH=/bin/bash
BASH_ENV=/root/.bashrc
…

6).使用unset命令来清除环境变量
$ export TEMP_KEVIN=”kevin” #增加一个环境变量TEMP_KEVIN
$ env | grep TEMP_KEVIN #查看环境变量TEMP_KEVIN是否生效(存在即生效)
TEMP_KEVIN=kevin #证明环境变量TEMP_KEVIN已经存在
$ unset TEMP_KEVIN #删除环境变量TEMP_KEVIN
$ env | grep TEMP_KEVIN #查看环境变量TEMP_KEVIN是否被删除,没有输出显示,证明TEMP_KEVIN被清除了。
7).使用readonly命令设置只读变量

注:如果使用了readonly命令的话,变量就不可以被修改或清除了。
$ export TEMP_KEVIN ="kevin" #增加一个环境变量TEMP_KEVIN
$ readonly TEMP_KEVIN #将环境变量TEMP_KEVIN设为只读
$ env | grep TEMP_KEVIN #查看环境变量TEMP_KEVIN是否生效
TEMP_KEVIN=kevin #证明环境变量TEMP_KEVIN已经存在

$ unset TEMP_KEVIN #会提示此变量只读不能被删除
-bash: unset: TEMP_KEVIN: cannot unset: readonly variable
$ TEMP_KEVIN ="tom" #修改变量值为tom会提示此变量只读不能被修改
-bash: TEMP_KEVIN: readonly variable

8).通过修改环境变量定义文件来修改环境变量。

需要注意的是,一般情况下,仅修改普通用户环境变量配置文件,避免修改根用户的环境定义文件,因为那样可能会造成潜在的危险。

$ cd ~ #到用户根目录下
$ ls -a #查看所有文件,包含隐藏的文件
$ vi .bash_profile #修改用户环境变量文件

例如:编辑你的PATH声明,其格式为:
PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>
   你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效。如果想立刻生效,则可执行下面的语句:$source .bash_profile
需要注意的是,最好不要把当前路径”./”放到PATH里,这样可能会受到意想不到的攻击。完成后,可以通过$ echo $PATH查看当前的搜索路径。这样定制后,就可以避免频繁的启动位于shell搜索的路径之外的程序了。
所以很多人会export PATH=$PATH:/opt/arm-linux-gcc-3.4.2/bin 等同于将补在了上一个PATH的后面了,像JAVA的字符串拼接。

5、学习总结
1).Linux的变量种类
    按变量的生存周期来划分,Linux变量可分为两类:
i. 永久的:需要修改配置文件,变量永久生效。
ii. 临时的:使用export命令行声明即可,变量在关闭shell时失效。

2).设置变量的三种方法
方案一
也有这种配置环境变量的办法。(估计只对当前用户有效吧。)
vi ~/.bash_profile
--配置maven的环境变量
export M2_HOME=/usr/local/maven
export PATH=$PATH:$M2_HOME/bin
来自 <https://www.cnblogs.com/smartloli/p/9371904.html> 
方案二
i. 在/etc/profile文件中添加变量【全局用户配置文件,如果修改了此文件中的设置,修改的设置将会影响系统中的所有用户】
    用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。

例如:编辑/etc/profile文件,添加CLASSPATH变量

# vi /etc/profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

注:修改文件后要想马上生效还要运行# source /etc/profile不然只能在下次重进此用户时生效。

ii. 在用户目录下的~/.bash_profile文件中增加变量【用户个人配置文件,如果修改了此文件中的设置,修改的设置只会影响单个用户。】
            用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。
例如:编辑guok用户目录(/home/guok)下的.bash_profile
$ vi /home/guok/.bash.profile

添加内容:
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。
iii. 直接运行export命令定义变量【只对当前shell(BASH)有效(临时的)】
            在shell的命令行下直接使用[export变量名=变量值]定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。
iiii. 在/etc/bashrc文件中增加变量【全局环境变量配置文件,此文件中定义了所有用户的环境变量】
iiiii.在~/bashrc文件中增加变量【个人环境变量配置文件,此文件中定义了用户的环境变量】
6、综述
1)、直接用export命令:#export PATH=$PATH:/opt/arm-linux-gcc-3.4.2/bin
2)、新建一个sh文件,把要添加的代码放到里面,保存之后输入#source ***.sh
3)、修改/etc/profile文件:#vi /etc/profile 注意这种方法不安全,因为它对所有用户都是有效的
4)、修改/etc/.bashrc文件:#vi /etc/profile
        注意:后两种方法需要重新注销系统才有效;查看是否设置成功,可以用命令#echo $PATH查看我的路径是否加入到系统里面去了;多个路径用冒号隔开;软件越装越多,建议都放在文件末尾;
注意:Fedora10  当中用gedit /root/.bashrc   在结尾加上bin地址就可以了。

来自 <https://blog.csdn.net/csf111/article/details/7296443###> 

shell  /dev/null

/dev/null表示空设备.

sh xxx.sh > /dev/null 就是把日志记录到空设备里,就是不记录日志,Null 是一特殊指标值(或是一种物件参照 reference)表示这个指标并不指向任何的物件。

是一个特殊的文件,写入到它的内容都会被丢弃,如果尝试从该文件读取内容,那么什么也读不到,但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。


2>/dev/null

shell  2>/dev/null、>/dev/null 2>&1、2>&1>/dev/null

参考文章  https://blog.csdn.net/longgeaisisi/article/details/90519690 

一、区别:

2>/dev/null

意思就是把错误输出到“黑洞”

>/dev/null 2>&1

默认情况是1,也就是等同于1>/dev/null 2>&1。意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”

2>&1 >/dev/null

意思就是把错误输出2重定向到标准出书1,也就是屏幕,标准输出进了“黑洞”,也就是标准输出进了黑洞,错误输出打印到屏幕

二、解释:

1、文件描述符

Linux系统预留可三个文件描述符:0、1和2,他们的意义如下所示:

0——标准输入(stdin)

1——标准输出(stdout)

2——标准错误(stderr)

标准输出——stdout

假设:在当前目录下,有且只有一个文件名称为ljl.txt的文件,这时我们运行这个命令【ls ljl.txt】,就会获得一个标准输出stdout的输出结果:ljl.txt

错误输出——stderr

按照上面的假设,我们运行另一条命令【ls gss.txt】,这样我们就会获得一个标准错误stderr的输出结果“ls:无法访问gss.txt:没有那个文件或目录”。

2、重定向

重定向的符号有两个:>或>>,两者的区别是:前者会先清空文件,然后再写入内容,后者会将重定向的内容追加到现有文件的尾部。举个例子:

(1)重定向标准输出stdout

如上图所示,对比没有添加重定向的操作,这条命令在使用之后并没有将123.txt打印到屏幕。在紧接的cat操作后,可以发现本来应该被输出的内容被记录到stdout.txt中。

(2)重定向标准错误stderr

如上图所示,文件描述符2,标准错误的重定向也是同样的原理被记录在了文件stderr.txt这个文件里面了。

(3)可以将stderr单独定向到一个文件,stdout重定向到另一个文件

cmd 2> stderr.txt 1>stdout.txt

(4)也可以将stderr和stdout重定向到同一个文件

cmd > output.txt 2>&1

或采用下面的方法,可以少写几个字,能达到同样的效果

cmd &> output.txt

cmd >& output.txt #两个表达式效果一样的

3、Linux特殊文件

/dev/null是一个特殊的设备文件,这个文件接收到任何数据都会被丢弃。因此,null这个设备通常也被称为位桶(bit bucket)或黑洞。

所以,2>/dev/null的意思就是将标准错误stderr删掉。

附:linux中单进程的文件数据结构图

上图是linux中单进程的文件数据结构图,最左边是我们熟悉的fd标志,也就是文件描述符,一个进程内所有的文件描述符按照顺序排列构成一张文件描述符表(即图中的进程表项),其中包括fd0,fd1,fd2。(注意:这里并没有说标准输入,标准输出,错误输出,原因后面讲)

那么,问题来了,假如我们想fd1写入数据时,最终数据会到哪儿呢?事实上fd1作为文件描述符,它本身并不是文件的真正的“入口”,文件真正的“入口”在文件描述符表(即图中的进程表项)的第二列:记录了每个文件描述符所对应文件位置的文件指针。换言之,如果我们更换fd1所对应的文件指针,就改变了fd1指向文件的”真正位置”。

fd0,fd1,fd2指向的文件默认情况下分别是/dev/stdin、/dev/stdout和/dev/stderr,这才是真正的标准输入,标准输出,错误输出,如果将数据写入到/dev/stdout中,就会在屏幕上显示数据,fd0,fd1,fd2只是标志而已,真正起作用的是他们对应的文件指针!

所以重定向命令’>’所做的工作就是就是改变了fd所对应的文件指针!

参考来自:https://blog.csdn.net/gramdog/article/details/80374119,https://blog.csdn.net/zhongqi2513/article/details/78613768,https://blog.csdn.net/a1439458305/article/details/79586567



来自 <https://blog.csdn.net/longgeaisisi/article/details/90519690>

 

shell  ` `

符号:` `
名称:反引号,上分隔符
位置:反引号(`)这个字符一般在键盘的左上角,数字1的左边,不要将其同单引号(’)混淆
作用:反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分
'单引号':当我需要显示的内容为纯文本时,使用单引号
“双引号”:当我需要显示的内容中有引用时,要用双引号。
总结使用技巧,正常打印信息时,一律用双引号
具体信息可以参考下图:

shell  |

linux下命令执行结果作为其他命令输入参数

1. 通过ps命令获取对应程序的pid,比如要获取redis-server这个进程的pid
ps -ef | grep redis-server

root      60415      1 93 Feb17 ?        8-04:12:36 redis-server *:6379
root      61823  59236  0 01:26 pts/1    00:00:00 grep --color=auto redis-server

但是我们要获取具体的60415这个值,可以通过下面命令来获取命令
ps -ef | grep redis-server | grep -v grep | awk '{print $2}'
简单介绍awk,就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。


2.把获取的pid作为其他命令的输入

这里执行一个名字为test的C程序,需要把pid作为输入参数。

方法1:

./test `ps -ef | grep redis-server | grep -v grep | awk '{print $2}'`

方法2:

ps -ef | grep redis-server | grep -v grep | awk '{print $2}'  | xargs ./test

shell  $1、$#、$@、$0、$1、$2

变量说明: 
$$ ——Shell本身的PID(ProcessID) 
$! ——Shell最后运行的后台Process的PID 
$? ——最后运行的命令的结束代码(返回值) 
$- ——使用Set命令设定的Flag一览 
$* ——所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
$@ ——所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 
$# ——添加到Shell的参数个数 
$0 ——Shell本身的文件名 
$1~$n ——添加到Shell的各参数值。$1是第1参数、$2是第2参数…。

shell脚本中经常用到转义字符$,下面是$的常见用法:
$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

$1在shell中称为“位置参数”,表示传入的第1个参数(第1个入参)。
常见搭配 test -z $1 是一个判断表达式,用于判断$1的值是否为空字符串。若为空,则结果为true;否则为false。

@与*的区别:
• 相同点:都是引用所有参数
• 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数(分别存储在1 2 3)则"*" 等价于 “1 2 3"(传递了一个参数);而“@" 等价于 "1" "2"  "$3"(传递了三个参数)

给脚本传参,默认是空格为分隔符的。

shell xargs

xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理。通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从文件的输出中读取数据。

xargs的默认命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。

未梳理部分

  • 本地变量只在当前进程有效,如 su 用户。(包含了切换进程的操作了)再echo这变量 值就不一样了
  • env 变量名 输出环境变量
  •  #!/bin/env bash  (不推荐 #!/bin/bash )

export -p  查看环境

查看进程之间的关系。auxf(管道??) grep 来过滤,条件为“bash”。如图:第三行的子进程是第四行

chmod u+x (其中u代表用户(文件的所有者),g代表用户组,o代表其他,a代表所有)

chmod +x 文件名;   赋予执行权限

expr 需要有空格的

 

打印用户的ID。这句先判断用户id是否属于 u,是则为0,打印admin

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值