Shell

一、Shell入门简介

1.1 什么是shell

1.2

1.3 第一个伟大的shell脚本

#创建HelloWorld.sh文件
[lln@hadoop102 shell]$ touch HelloWorld.sh
#编辑HelloWorld.sh文件
[lln@hadoop102 shell]$ vim HelloWorld.sh
#查看HelloWorld.sh文件
[root@hadoop102 shell]# cat HelloWorld.sh
#!/bin/bash
# This is ower first shell
# by author lln 2022.8.25
echo "hello world"
#查看文件目录
[lln@hadoop102 shell]$ ll
总用量 4
-rw-rw-r--. 1 lln lln 84 825 09:46 HelloWorld.sh
#运行HelloWorld.sh脚本
[lln@hadoop102 shell]$ ./HelloWorld.sh
-bash: ./HelloWorld.sh: 权限不够
#赋予执行权限
[root@hadoop102 shell]# chmod +x HelloWorld.sh
#再次运行HelloWorld.sh脚本
[root@hadoop102 shell]# ./HelloWorld.sh
hello world
[root@hadoop102 shell]# 

 

1.4 shell脚本执行方式

 

在新进程中运行shell脚本
 

  • 将shell脚本作为程序运行

Shell 脚本也是一种解释执行的程序,可以在终端直接调用(需要使用 chmod 命令给 Shell 脚本加上执行权限),如下所示:

在这里插入图片描述

#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

通过这种方式运行脚本,脚本文件第一行的#!/bin/bash一定要写对,好让系统查找到正确的解释器。

chmod +x表示给 a.sh 增加执行权限。

./表示当前目录,整条命令的意思是执行当前目录下的 a.sh 脚本。如果不写./,Linux 会到系统路径(由 PATH环境变量指定)下查找 a.sh,而系统路径下显然不存在这个脚本,所以会执行失败。

 

  • 将shell脚本作为参数传递给Bash解释器

直接运行 Bash 解释器,将脚本文件的名字作为参数传递给 Bash。

通过这种方式运行脚本,不需要在脚本文件的第一行指定解释器信息,写了也没用。

更加简洁的写法是运行 bash 命令。bash 是一个外部命令,Shell 会在 /bin 目录中找到对应的应用程序,也即 /bin/bash,这点我们已在《Shell命令的本质到底是什么》一节中提到。

在这里插入图片描述
这两种写法在本质上是一样的:第一种写法给出了绝对路径,会直接运行 Bash 解释器;第二种写法通过 bash 命令找到 Bash 解释器所在的目录,然后再运行,只不过多了一个查找的过程而已。

 

检测是否开启了新进程

Linux 中的每一个进程都有一个唯一的 ID,称为 PID,使用$$变量就可以获取当前进程的 PID。

在这里插入图片描述
进程的 PID 都不一样,当然就是两个进程了。

 

在当前进程中运行shell脚本

source 是 Shell 内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。你也可以理解为,source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。

source 命令的用法为:

source filename

也可以简写为:

. filename

两种写法的效果相同。对于第二种写法,注意点号.文件名中间有一个空格

在这里插入图片描述
使用 source 命令不用给脚本增加执行权限,并且写不写./都行。

进程的 PID 都是一样的,当然是同一个进程了。

 

现有一a.sh脚本

#!/bin/bash
echo "step 1 sleeping"
sleep 200
echo "step 2 sleeping"
sleep 200
  • ./a.shsh ./a.shbash ./a.sh ,此三种执行脚本的方式都是重新启动一个shell,在子shell中执行此脚本,脚本中设置的变量在脚本执行完毕后不会保存。(但是若 script.sh 脚本不是以 #!/bin/bash 开头,那么也不会在子进程中执行。) ./a.sh将a.sh当成一个文件执行,此时需要x运行权限,同时有两个进程进行:a.sh和sleep。如果在执行到第一个sleep时终止脚本,a.sh和sleep一起终止,并且第二个sleep不会执行,因为整个a.sh运行已经终止。
  • source ./a.sh   和 . ./a.sh   的执行方式是等价的,即这两种执行方式都是在当前shell进程中执行此脚本,而不是重新启动一个shell在子shell进程中执行此脚本,并且脚本中设置的变量在脚本执行完毕后会保存下来。
  • source是Shell(准确地说是Bash)的内置命令,在Bourne Shell中的等价命令是一个点.,即点命令。用source命令执行脚本文件时,是在当前Shell进程中执行,而不是像./sh方式一样在新的Shell进程中执行,因此早先设置的变量在脚本里是可以读取到的。不需要执行权限,有读取权限(r权限)即可。如果在执行第1个sleep时按ctrl+c终止,那么第2个sleep接着运行,直到脚本所有命令执行完。
  • source一般不用来执行业务脚本,最常见用途是在某些初始化脚本修改之后使其立即生效,即source /etc/profile这样。

 

二、shell变量

2.1 shell变量介绍

Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量。
Shell变量名在定义时,首个字符必须为字母(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线_,不能使用-,也不能使用标点符号等。
等号两侧不能有空格。

2.2 shell系统变量

# 系统变量,主要是用于对参数判断和命令返回值判断时使用,系统变量详解如下:

$0 		当前脚本的名称;
$n 		当前脚本的第n个参数,n=1,2,9;
$* 		当前脚本的所有参数(不包括程序本身);
$# 		当前脚本的参数个数(不包括程序本身);
$? 		令或程序执行完后的状态,返回0表示执行成功;
$$ 		程序本身的PID号。


2.3 shell环境变量

环境变量,主要是在程序运行时需要设置,环境变量详解如下:

PATH  		命令所示路径,以冒号为分割;
HOME  		打印用户家目录;
SHELL 		显示当前Shell类型;
USER  		打印当前用户名;
ID    		打印当前用户id信息;
PWD   		显示当前所在路径;
TERM  		打印当前终端类型;
HOSTNAME    显示当前主机名;
PS1         定义主机命令提示符的;
HISTSIZE    历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
RANDOM      随机生成一个 032767 的整数;
HOSTNAME    主机名

2.4 shell用户变量

# 用户变量又称为局部变量,主要用在Shell脚本内部或者临时局部使用,系统变量详解如下:
a=rivers 				       自定义变量AHttpd_sort=httpd-2.4.6-97.tar  自定义变量N_SOFT;
BACK_DIR=/data/backup/         自定义变量BACK_DIR;
IPaddress=10.0.0.1			   自定义变量IP1;

2.5 变量的定义

在这里插入图片描述

在这里插入图片描述

2.6 Shell变量的作用域

Shell 变量的作用域可以分为三种:

  • 有的变量只能在函数内部使用,这叫做局部变量(local variable);
  • 有的变量可以在当前 Shell 进程中使用,这叫做全局变量(global variable);
  • 而有的变量还可以在子进程中使用,这叫做环境变量(environment variable)。

2.7 局部变量

Shell 也支持自定义函数,但是 Shell 函数和 C++、Java、C# 等其他编程语言函数的一个不同点就是:在 Shell 函数中定义的变量默认也是全局变量,它和在函数外部定义变量拥有一样的效果。

#!/bin/bash

#定义函数
function func(){
    a=99
}

#调用函数
func

#输出函数内部的变量
echo $a

输出结果:
99

a 是在函数内部定义的,但是在函数外部也可以得到它的值,证明它的作用域是全局的,而不是仅限于函数内部。

要想变量的作用域仅限于函数内部,可以在定义时加上 local 命令,此时该变量就成了局部变量。

#!/bin/bash

#定义函数
function func(){
    local a=99
}

#调用函数
func

#输出函数内部的变量
echo $a

输出结果为空,表明变量 a 在函数外部无效,是一个局部变量。

Shell 变量的这个特性和 JavaScript 中的变量是类似的。在 JavaScript 函数内部定义的变量,默认也是全局变量,只有加上var关键字,它才会变成局部变量。

 

2.8 全局变量

所谓全局变量,就是指变量在当前的整个 Shell 进程中都有效。
每个 Shell 进程都有自己的作用域,彼此之间互不影响。
在 Shell 中定义的变量,默认就是全局变量。

想要实际演示全局变量在不同 Shell 进程中的互不相关性,可在图形界面下同时打开两个 Shell,或使用两个终端远程连接到服务器(SSH)。

首先打开一个 Shell 窗口,定义一个变量 a 并赋值为 99,然后打印,这时在同一个 Shell 窗口中是可正确打印变量 a 的值的。然后再打开一个新的 Shell 窗口,同样打印变量 a 的值,但结果却为空,如下图所示。
在这里插入图片描述

这说明全局变量 a 仅仅在定义它的第一个 Shell 进程中有效,对新的 Shell 进程没有影响。

需要强调的是,全局变量的作用范围是当前的 Shell 进程,而不是当前的 Shell 脚本文件,它们是不同的概念。打开一个 Shell 窗口就创建了一个 Shell 进程,打开多个 Shell 窗口就创建了多个 Shell 进程,每个 Shell 进程都是独立的,拥有不同的进程 ID。在一个 Shell 进程中可以使用 source 命令执行多个 Shell 脚本文件,此时全局变量在这些脚本文件中都有效。

例如:
a.sh

#!/bin/bash
echo $a
b=200

b.sh

#!/bin/bash
echo $b

在这里插入图片描述

这三条命令都是在一个进程中执行的,从输出结果可以发现,在 Shell 窗口中以命令行的形式定义的变量 a,在 a.sh 中有效;在 a.sh 中定义的变量 b,在 b.sh 中也有效,变量 b 的作用范围已经超越了 a.sh。

注意,必须在当前进程中运行 Shell 脚本,不能在新进程中运行 Shell 脚本。

2.9 环境变量

全局变量只在当前 Shell 进程中有效,对其它 Shell 进程和子进程都无效。如果使用export命令将全局变量导出,那么它就在所有的子进程中也有效了,这称为“环境变量”。

环境变量被创建时所处的 Shell 进程称为父进程,如果在父进程中再创建一个新的进程来执行 Shell 命令,那么这个新的进程被称作 Shell 子进程。当 Shell 子进程产生时,它会继承父进程的环境变量为自己所用,所以说环境变量可从父进程传给子进程。不难理解,环境变量还可以传递给孙进程。

注意,两个没有父子关系的 Shell 进程是不能传递环境变量的,并且环境变量只能向下传递而不能向上传递,即“传子不传父”。

创建 Shell 子进程最简单的方式是运行 bash 命令

请添加图片描述

通过exit命令可以一层一层地退出 Shell。

演示环境变量的使用:

[redhat@localhost ~]$ a=100      #定义一个全局变量
[redhat@localhost ~]$ echo $a    #在当前Shell中输出a,成功
100
[redhat@localhost ~]$ bash	     #进入Shell子进程
[redhat@localhost ~]$ echo $a	 #在子进程中输出a,失败

[redhat@localhost ~]$ exit	     #退出Shell子进程,返回上一级Shell
exit
[redhat@localhost ~]$ export a   #将a导出为环境变量
[redhat@localhost ~]$ bash	     #重新进入Shell子进程
[redhat@localhost ~]$ echo $a	 #在子进程中再次输出a,成功
100
[redhat@localhost ~]$ exit	     #退出Shell子进程
exit
[redhat@localhost ~]$ exit	     #退出父进程,结束整个Shell会话

可以发现,默认情况下,a 在 Shell 子进程中是无效的;使用 export 将 a 导出为环境变量后,在子进程中就可以使用了。

export a这种形式是在定义变量 a 以后再将它导出为环境变量,如果想在定义的同时导出为环境变量,可以写作export a=22。

我们一直强调的是环境变量在 Shell 子进程中有效,并没有说它在所有的 Shell 进程中都有效;如果你通过终端创建了一个新的 Shell 窗口,那它就不是当前 Shell 的子进程,环境变量对这个新的 Shell 进程仍然是无效的。第一个窗口中的环境变量 a 在第二个窗口中就无效。

在这里插入图片描述

环境变量也是临时的

通过 export 导出的环境变量只对当前 Shell 进程以及所有的子进程有效,如果最顶层的父进程被关闭了,那么环境变量也就随之消失了,其它的进程也就无法使用了,所以说环境变量也是临时的。

如果我想让一个变量在所有 Shell 进程中都有效,不管它们之间是否存在父子关系,该怎么办呢?

只有将变量写入 Shell 配置文件中才能达到这个目的!Shell 进程每次启动时都会执行配置文件中的代码做一些初始化工作,如果将变量放在配置文件中,那么每次启动进程都会定义这个变量。

2.10 命令替换

Shell 命令替换是指将命令的输出结果赋值给某个变量。比如,在某个目录中输入 ls 命令可查看当前目录中所有的文件,但如何将输出内容存入某个变量中呢?这就需要使用命令替换了,这也是 Shell 编程中使用非常频繁的功能。

Shell 中有两种方式可以完成命令替换,一种是反引号,一种是$(),使用方法如下:

variable=`commands`
variable=$(commands)

其中,variable 是变量名,commands 是要执行的命令。commands 可以只有一个命令,也可以有多个命令,多个命令之间以分号;分隔。

例如,date 命令用来获得当前的系统时间,使用命令替换可以将它的结果赋值给一个变量。

#!/bin/bash
begin_time=`date`    #开始时间,使用``替换
sleep 20s            #休眠20秒
finish_time=$(date)  #结束时间,使用$()替换
echo "Begin time: $begin_time"
echo "Finish time: $finish_time"

运行脚本,20 秒后可以看到输出结果:

Begin time: 20220826日 星期五 09:59:58 CST
Finish time: 20220826日 星期五 10:00:18 CST

使用 data 命令的%s格式控制符可以得到当前的 UNIX 时间戳,这样就可以直接计算脚本的运行时间了。UNIX 时间戳是指从 1970 年 1 月 1 日 00:00:00 到目前为止的秒数。

#!/bin/bash
begin_time=`date +%s`    #开始时间,使用``替换
sleep 20s                #休眠20秒
finish_time=$(date +%s)  #结束时间,使用$()替换
run_time=$((finish_time - begin_time))  #时间差
echo "begin time: $begin_time"
echo "finish time: $finish_time"
echo "run time: ${run_time}s"

运行脚本,20 秒后可以看到输出结果:

begin time: 1555639864
finish time: 1555639884
run time: 20s

第 5 行代码中的(( ))是 Shell 数学计算命令。和 C++、C#、Java 等编程语言不同,在 Shell 中进行数据计算不那么方便,必须使用专门的数学计算命令,(( ))就是其中之一。

注意,如果被替换的命令的输出内容包括多行(也即有换行符),或者含有多个连续的空白符,那么在输出变量时应该将变量用双引号包围,否则系统会使用默认的空白符来填充,这会导致换行无效,以及连续的空白符被压缩成一个。

#!/bin/bash
LSL=`ls -l`
echo $LSL  #不使用双引号包围
echo "--------------------------"  #输出分隔符
echo "$LSL"  #使用引号包围

运行结果:

total 8 drwxr-xr-x. 2 root root 21 71 2016 abc -rw-rw-r--. 1 mozhiyan mozhiyan 147 1031 10:29 demo.sh -rw-rw-r--. 1 mozhiyan mozhiyan 35 1031 10:20 demo.sh~
--------------------------
total 8
drwxr-xr-x. 2 root     root      21 71 2016 abc
-rw-rw-r--. 1 mozhiyan mozhiyan 147 1031 10:29 demo.sh
-rw-rw-r--. 1 mozhiyan mozhiyan  35 1031 10:20 demo.sh

所以,为了防止出现格式混乱的情况,我建议在输出变量时加上双引号。

 

再谈反引号和 $ ()

原则上讲,上面提到的两种变量替换的形式是等价的,可以随意使用;但是,反引号毕竟看起来像单引号,有时候会对查看代码造成困扰,而使用 $ () 就相对清晰,能有效避免这种混乱。而且有些情况必须使用 $ (), $ () 支持嵌套,反引号不行。

下面的例子演示了使用计算 ls 命令列出的第一个文件的行数,这里使用了两层嵌套。

[c.biancheng.net]$ Fir_File_Lines=$(wc -l $(ls | sed -n '1p'))
[c.biancheng.net]$ echo "$Fir_File_Lines"
36 anaconda-ks.cfg

要注意的是,$ () 仅在 Bash Shell 中有效,而反引号可在多种 Shell 中使用。所以这两种命令替换的方式各有特点,究竟选用哪种方式全看个人需求。

2.11 位置参数

运行Shell脚本文件时我们可以给它传递一些参数,这些参数在脚本文件内部可以使用$n的形式来接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。

同样,在调用函数时也可以传递参数。Shell 函数参数的传递和其它编程语言不同,没有所谓的形参和实参,在定义函数时也不用指明参数的名字和数目。换句话说,定义 Shell 函数时不能带参数,但是在调用函数时却可以传递参数,这些传递进来的参数,在函数内部就也使用$n的形式接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。

这种通过$n的形式来接收的参数,在 Shell 中称为位置参数。

在讲解变量的命名时,我们提到:变量的名字必须以字母或者下划线开头,不能以数字开头;但是位置参数却偏偏是数字,这和变量的命名规则是相悖的,所以我们将它们视为“特殊变量”。

  • 给脚本文件传递位置参数

test003.sh

#!/bin/bash
echo "Language: $1"
echo "Url: $2"

运行 test.sh,并附带参数:

在这里插入图片描述

  • 给函数传递位置参数
#!/bin/bash
#定义函数
function func(){
    echo "Language: $1"
    echo "URL: $2"
}
#调用函数
func C++ http://c.biancheng.net/cplus/

运行:

[mozhiyan@localhost demo]$ . ./test.sh
Language: C++
URL: http://c.biancheng.net/cplus/

注意事项
如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如 10 、 {10}、 10{23}。{ }的作用是为了帮助解释器识别参数的边界,这跟使用变量时加{ }是一样的效果。

2.12 特殊变量

Shell特殊变量及其含义

在这里插入图片描述

  • 给脚本文件传递参数
#!/bin/bash
echo "Process ID: $$"
echo "File Name: $0"
echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "All parameters 1: $@"
echo "All parameters 2: $*"
echo "Total: $#"

运行,并附带参数:

[mozhiyan@localhost demo]$ . ./test.sh Shell Linux
Process ID: 5943
File Name: bash
First Parameter : Shell
Second Parameter : Linux
All parameters 1: Shell Linux
All parameters 2: Shell Linux
Total: 2
  • 给函数传递参数
#!/bin/bash
#定义函数
function func(){
    echo "Language: $1"
    echo "URL: $2"
    echo "First Parameter : $1"
    echo "Second Parameter : $2"
    echo "All parameters 1: $@"
    echo "All parameters 2: $*"
    echo "Total: $#"
}
#调用函数
func Java http://c.biancheng.net/java/

运行结果:

Language: Java
URL: http://c.biancheng.net/java/
First Parameter : Java
Second Parameter : http://c.biancheng.net/java/
All parameters 1: Java http://c.biancheng.net/java/
All parameters 2: Java http://c.biancheng.net/java/
Total: 2

三、shell流程控制语句

3.1 if条件语句

3.1.1 if分支

在这里插入代码片

3.1.2 if常见判断运算符

3.1.3 判断crond进程是否在运行

 

echo 命令

echo是一个Shell内建命令,用来在终端输出字符串,并在最后加默认加上换行符。

【实例】

#!/bin/bash
name="Shell教程"
url="http://c.biancheng.net/shell/"
echo "读者,你好!"  #直接输出字符串
echo $url  #输出变量
echo "${name}的网址是:${url}"  #双引号包围的字符串中可以解析变量
echo '${name}的网址是:${url}'  #单引号包围的字符串中不能解析变量

运行结果:

读者,你好!
http://c.biancheng.net/shell/
Shell教程的网址是:http://c.biancheng.net/shell/
${name}的网址是:${url}

不换行

echo命令输出结束后默认会换行,如果不希望换行,可以加上-n参数,如下所示:

#!/bin/bash
name="Tom"
age=20
height=175
weight=62
echo -n "${name} is ${age} years old, "
echo -n "${height}cm in height "
echo "and ${weight}kg in weight."
echo "Thank you!"

运行结果:

Tom is 20 years old, 175cm in height and 62kg in weight.
Thank you!

输出转义字符

默认情况下,echo 不会解析以反斜杠\开头的转义字符。比如,\n表示换行,echo 默认会将它作为普通字符对待。

[root@localhost ~]# echo "hello \nworld"
hello \nworld

可以添加-e参数来让 echo 命令解析转义字符。

[root@localhost ~]# echo -e "hello \nworld"
hello
world

\c转义字符
有了-e参数,我们也可以使用转义字符-c来强制echo命令不换行了。

#!/bin/bash
name="Tom"
age=20
height=175
weight=62
echo -e "${name} is ${age} years old, \c"
echo -e "${height}cm in height \c"
echo "and ${weight}kg in weight."
echo "Thank you!"

运行结果:

Tom is 20 years old, 175cm in height and 62kg in weight.
Thank you!

 

read命令

read是Shell的内置命令,用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。

read命令的用法为:

read [-options] [variables]

options表示选项,如下表所示;variables表示用来存储数据的变量,可以有一个或多个,如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二个变量,如果输入数据个数过多,则最后所有的值都给第一个变量。如果太少输入不会结束。

optionsvariables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量REPLY中。

在这里插入图片描述

【实例1】使用read命令给多个变量赋值

#!/bin/bash
read -p "Enter some information > " name url age
echo "网站名字:$name"
echo "网址:$url"
echo "年龄:$age"

运行结果:

Enter some information > C语言中文网 http://c.biancheng.net 7
网站名字:C语言中文网
网址:http://c.biancheng.net
年龄:7

注意,必须在一行内输入所有的值,不能换行,否则只能给第一个变量赋值,后续变量都会赋值失败。

本例还使用了-p选项,该选项会用一段文本来提示用户输入。

【实例2】只读取一个字符

#!/bin/bash
read -n 1 -p "Enter a char > " char
printf "\n"  #换行
echo $char

运行结果:

Enter a char > 1
1

-n 1表示只读取一个字符。运行脚本后,只要用户输入一个字符,立即读取结束,不用等待用户按下回车键。

printf "\n"语句用来达到换行的效果,否则 echo 的输出结果会和用户输入的内容位于同一行,不容易区分。

【实例3】在指定时间内输入密码

#!/bin/bash
if
    read -t 20 -sp "Enter password in 20 seconds(once) > " pass1 && printf "\n" &&  #第一次输入密码
    read -t 20 -sp "Enter password in 20 seconds(again)> " pass2 && printf "\n" &&  #第二次输入密码
    [ $pass1 == $pass2 ]  #判断两次输入的密码是否相等
then
    echo "Valid password"
else
    echo "Invalid password"
fi

这段代码中,我们使用&&组合了多个命令,这些命令会依次执行,并且从整体上作为if语句的判断条件,只要其中一个命令执行失败(退出状态为非 0 值),整个判断条件就失败了,后续的命令也就没有必要执行了。

如果两次输入密码相同,运行结果为:

Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Valid password

如果两次输入密码不同,运行结果为:

Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)>
Invalid password

如果第一次输入超时,运行结果为:

Enter password in 20 seconds(once) > Invalid password

如果第二次输入超时,运行结果为:

Enter password in 20 seconds(once) >
Enter password in 20 seconds(again)> Invalid password

【实例4】读文件

每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。

读取文件的关键是如何将文本中的数据传送给read命令。

最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令

alias

alias用来给命令创建一个别名。

若直接输入alias且不带任何参数,则会列出当前进程中使用了哪些别名。

例如llls -l的效果一样。

[redhat@localhost shell]$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias vi='vim'
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
alias xzegrep='xzegrep --color=auto'
alias xzfgrep='xzfgrep --color=auto'
alias xzgrep='xzgrep --color=auto'
alias zegrep='zegrep --color=auto'
alias zfgrep='zfgrep --color=auto'
alias zgrep='zgrep --color=auto'

为了让我们使用方便,Shell 会给某些命令默认创建别名。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

不学了,学锤子,学sql去了。。。。。。。。。。。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值