expr

sjf是什么意思(黄金sjf是什么意思)

4.3、将命令加入PATH

接下来,我们把上面的命令,做成一个脚本。然后将这个脚本,放到PATH目录中。不过先等等,我们要先给命令起个名字。

首先需要创建一个文件。在Linux上,创建文件使用touch命令。

# touch jdsjf

命令执行后,什么都没发生,它只是创建了一个空文件。接下来,我们向其中添加一些内容。

# echo "echo 'Hello World'" > jdsjf

注意符号>,它的意思是,将前面的输出,重定向到后面的文件中。执行完上面的命令,jdsjf 中的内容,就变成了echo 'Hello World。

接下来,我们尝试着去执行刚才生成的命令。

# ./jdsjf

-bash: ./jdsjf : Permission denied

我们通过相对路径的方式,来执行刚刚生成的命令。结果,终端显示我们并没有这个命令的执行权限。

其实,Linux在权限控制这一方面,非常的详细。一个文件,有可读、可写、可执行三种属性。如果想要一个文件能够执行,需要给它添加执行权限,这个过程是由命令chmod完成的。

# chmod u+x jdsjf

# ./jdsjf

Hello World

我们将在后面的章节,来详细介绍权限方面的知识。如上所示,命令已经能正常输出,接下来,我们把命令移动到PATH中的一个目录。

# mv jdsjf /usr/local/bin/

# jdsjf

Hello World

不需要加任何的相对路径,现在,只需要输入jdsjf,就可以正常输出一串数字。我们成功地让一个没有任何意义的字符串,表达了它的想法。虽然我们依然是它的主宰。

你可以想一下下面这三个问题:

1、我可以自定义一个目录,比如/root/mybin,把它加入到PATH么?

2、我可以省略上面的touch命令,直接使用重定向生成文件么?

3、除了放到PATH和相对路径,还有没有其他的命令执行方式?

5. Linux漫游方式

想要了解linux的基本使用方法,就要了解一个基本的事实--linux系统中,一切皆文件。

不管是命令,还是文档,甚至设备,目录,套接字,在linux上对它们的操作都是一致对待的。许多开发驱动程序的小伙伴,会发现使用的一些函数,和读写文件的没什么两样。今天我们所说的基本操作,针对的就是普通文件和目录,本小节将详细解释相关命令。

5.1、当前路径

到现在为止,我们还不知道自己在系统的什么地方。在浏览器上,我们能够通过导航栏上的url,了解到自己在互联网上的具体坐标。相似的功能,是由pwd命令提供的,它能够输出当前的工作目录。

pwd命令是非常非常常用的命令,尤其是在一些命令提示符设置不太友好的机器上。另外,它也经常用在shell脚本中,用来判断当前的运行目录是否符合需求。

有很多线上事故,都是由于没有确认当前目录所引起的。比如rm -rf *这种危险的命令。在执行一些高危命令时,随时确认当前目录,是个好的习惯。

# pwd

/root

我们使用root用户默认登陆后,就停留在/root目录中。Linux中的目录层次,是通过/进行划分的。

5.2、文件系统用户标准

Linux的文件系统,从一开始就有一个规范标准。它还有一个专有缩写名词,叫做FHS (Filesystem Hierarchy Standard)。FHS经过多年的演进,目录结构也越来越清晰。除了一些标准的要求,还有一些使用者之间的约定。

接下来,我们大体看一下linux上的默认目录,对其有一个基本的感觉。

第1层第二层介绍/bin目录/usr/bin的软链接/sbin目录/usr/sbin的软链接/lib目录/usr/lib的软链接/usr/bin存放一些常用的命令/usr/sbin存放一些管理员常用的命令/usr/lib用来存放动态库和一些模块文件/sys内核中的数据结构的可视化接口/proc内存映像/run内存映像/boot存放引导程序,内核相关文件/dev存放一些设备文件,比如光盘/etc用于存储一些全局的、应用的配置文件/var与/var/run一样,存放的是系统运行时需要的文件,比如mysql的pid等/tmp非常特殊的临时文件夹,断电丢失/home/**用户目录,比如我的目录是/home/xjjdog/rootroot用户的home目录

  • home 平常,我们打交道最多的目录,就集中在自己的用户目录,我们可以在里面做任何操作,比如我们现在root用户的/root目录。一些自己的资料,比如视频、音频、下载的文件,或者做测试用的一些数据资料,就可以自行在这些目录下规划。root用户比较特殊,普通用户的私人目录都是在/home下的。
  • /etc etc目录是经常要打交道的目录,存放了一些全局的系统配置文件和应用配置文件。比如你安装了php,或者nginx,它们的配置文件就躺在/etc目录下的某个文件夹里。
  • /var var目录存放一些运行中的数据,有必须的,也有非必须的。一些黑客入侵之后,会在这里面的某些文件中留下痕迹,他们会着重进行清理。var目录还是一些应用程序的默认数据存放之地,比如mysql的数据文件。
  • /tmp 目录是一个特殊的临时目录,文件在断电以后就消失了。但这个目录,所有的用户,都有写入权限,通常用来做文件交换用。
  • /proc和/sys目录,是两个神奇的目录。它们两个是一种伪文件系统,可以通过修改其中一些文件的状态和内容,来控制程序的行为。刚开始的时候,只有proc目录,由于里面内容有多又乱,后面又规划出sys目录,用来控制内核的一些行为。如果你在调优一些系统参数,和这些文件打交道的时间比较多。
  • 还有几个空的目录,我们没有列在上面的表格上。比如/srv目录,通常会把一些web服务的资料,比如nginx的,放在这里面。但是,这并不是强制要求的,所以我见过的/srv目录,通常会一直是空的。同样的,/opt目录也是这样一个存在,你就当它不存在就行。这都属于使用者规划的范畴,自定义性非常强。
  • 在使用Linux系统的时候,也可以创建自己的目录。比如,我就喜欢自己创建一个叫做/data的目录,用来存放一些数据库相关的内容。举个例子,/data/mysql存放mariadb的数据,而/data/es/存放elasticsearch的索引内容。
  • linux上的文件类型有很多,它们大部分都分门别类地存放在相应的目录中,比如/dev目录下,就是一些设备文件;/bin文件下,是一些可以执行命令。通常都好记的很。

    5.3、查看文件列表

    所以,上面的表格内容,我是怎么看到的呢,靠记忆么?ls命令,能够列出相关目录的文件信息。可以被评为linux下最勤劳的命令标兵。

    现在的终端,都能够输出彩色的信息,非常的直观。oh-my-zsh和oh-my-bash等项目,可以让你的终端更加的漂亮。把它加入到你的研究清单里吧。

    # ls /

    # 注意:ls可以接受路径参数,你不用先跳转,就可以输出相关信息

    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

    # ls -l /

    # 带上 -l参数,可以查看一些更加详细的信息。

    total 20

    lrwxrwxrwx.   1 root root    7 Nov  3 20:24 bin -> usr/bin

    dr-xr-xr-x.   5 root root 4096 Nov  3 20:34 boot

    drwxr-xr-x.  19 root root 3080 Nov  3 21:19 dev

    drwxr-xr-x.  74 root root 8192 Nov  3 20:34 etc

    drwxr-xr-x.   2 root root    6 Apr 11  2018 home

    lrwxrwxrwx.   1 root root    7 Nov  3 20:24 lib -> usr/lib

    lrwxrwxrwx.   1 root root    9 Nov  3 20:24 lib64 -> usr/lib64

    drwxr-xr-x.   2 root root    6 Apr 11  2018 media

    drwxr-xr-x.   2 root root    6 Apr 11  2018 mnt

    drwxr-xr-x.   2 root root    6 Apr 11  2018 opt

    dr-xr-xr-x. 108 root root    0 Nov  3 21:19 proc

    dr-xr-x---.   2 root root  135 Nov  4 07:53 root

    drwxr-xr-x.  24 root root  740 Nov  3 21:20 run

    lrwxrwxrwx.   1 root root    8 Nov  3 20:24 sbin -> usr/sbin

    drwxr-xr-x.   2 root root    6 Apr 11  2018 srv

    dr-xr-xr-x.  13 root root    0 Nov  3 21:19 sys

    drwxrwxrwt.   9 root root 4096 Nov  4 03:40 tmp

    drwxr-xr-x.  13 root root  155 Nov  3 20:24 usr

    drwxr-xr-x.  19 root root  267 Nov  3 20:34 var

    ls最常用的,就是加参数l或者参数a。

    5.3.1、详细信息

    加上参数l,能够看到文件的一些权限信息已经更新日期等。但我们还看到了一些更有意思的东西。比如:

    lib -> usr/lib

    上面表示的,是软链接信息。

    就如同我们上面表格所展示的一样,lib目录,是/usr/lib的快捷方式,它们之中的内容,没有什么两样。

    关于ls -l展示的更加详细的内容,可以参照我下面的这张图。我们将在了解后面小节的内容后,再次对这张图进行回顾。

    5.3.2 隐藏文件

    直接在你的/root目录里,执行ls -al,你会看到更多东西。这些额外的隐藏文件,都是以.开头,以配置文件居多。这就是参数a的作用。

    # ls -al

    total 28

    dr-xr-x---.  2 root root  135 Nov  4 07:53 .

    dr-xr-xr-x. 17 root root  224 Nov  3 20:28 ..

    -rw-------.  1 root root 1273 Nov  3 20:28 anaconda-ks.cfg

    -rw-------.  1 root root  246 Nov  4 11:41 .bash_history

    -rw-r--r--.  1 root root   18 Dec 28  2013 .bash_logout

    -rw-r--r--.  1 root root  176 Dec 28  2013 .bash_profile

    -rw-r--r--.  1 root root  176 Dec 28  2013 .bashrc

    -rw-r--r--.  1 root root  100 Dec 28  2013 .cshrc

    -rw-r--r--.  1 root root  129 Dec 28  2013 .tcshrc

    细心的同学,应该会注意到两个特殊的目录。.和..。前者表示的是当前目录,而后者表示的是上层目录。

    使用cd命令,将在这些目录中,自由穿梭。

    小技巧:如果你对英文日期阅读困难,可以使用ls -al --full-time查看可读的日期。

    5.4、切换目录

    执行cd命令,可以将工作目录切换到目标文件夹。为了展示cd命令的效果。请在root用户下,执行下面的命令,这将创建一个7层的目录。

    cd

    mkdir -p a1/b2/c3/d4/e5/f6/{g7,g8,g9,g10}

    我们使用cd命令,切换到最后一层。然后,我们使用..切换到上层目录。

    # cd a1/b2/c3/d4/e5/f6/g7

    # pwd

    /root/a1/b2/c3/d4/e5/f6/g7

     

    # cd ..

    # pwd

    /root/a1/b2/c3/d4/e5/f6

    所以,切换到上面n层目录,只需使用多层级的../即可。有几个特殊的变量,需要说明一下。

  • ../ 指的是上层目录
  • ../../ 指的是上两层目录
  • ./ 指的是当前目录
  • ~ 指的是当前的用户目录,这是一个缩写符号
  • - 使用它,可以在最近两次的目录中来回切换
  • 我们来使用命令把上面这些特殊变量验证一下。

    # 跳转到用户根目录

    # cd ~

    # pwd

    /root

     

    # 进入到第三层目录

    # cd a1/b2/c3/

    # pwd

    /root/a1/b2/c3

     

    # 跳回到前三层目录

    # cd ../../..

    # pwd

    /root

     

    # 跳到上次访问的目录

    # cd -

    /root/a1/b2/c3

    # pwd

    /root/a1/b2/c3

     

    # 进入当前目录:等于什么都没干

    # cd ./

    # pwd

    /root/a1/b2/c3

    以上就是cd命令的常用用法。现在,我们返回头来看一下mkdir。顾名思义,就是创建目录的意思,但一般在工作中,都会加上-p参数,这样就可以一次性创建多层目录。注意mkdir后面的大括号{},可以一次性地指定多个目录进行创建,这通常能节省很多时间。

    5.5、文件操作

    使用命令行操作文件,是非常方便的。

  • touch 新建文件
  • cp 复制文件
  • mv 移动文件
  • rm 删除文件
  • 这四个风骚的命令,主宰着文件资料的去向。我们依然使用上面创建的目录,进行接下来的操作。

    # 创建三个文件

    # touch long-long-long.txt

    # touch 996.txt

    # touch icu.txt

    # ls

    996.txt  a1  anaconda-ks.cfg  icu.txt  long-long-long.txt

     

    # 复制一个文件

    # cp 996.txt 007.txt

    # mv long-long-long.txt short.txt

    # ls

    007.txt  996.txt  a1  anaconda-ks.cfg  icu.txt  short.txt

     

    # 移动996.txt到a1目录,icu.txt到a1/b2目录

    # 删除short.txt

    # mv 996.txt a1/

    # mv icu.txt a1/b2/

    # rm short.txt

    rm: remove regular empty file ‘short.txt’? y

     

    # 递归删除a1目录

    # rm -rvf a1/

    removed directory: ‘a1/b2/c3/d4/e5/f6/g7’

    removed directory: ‘a1/b2/c3/d4/e5/f6/g8’

    removed directory: ‘a1/b2/c3/d4/e5/f6/g9’

    removed directory: ‘a1/b2/c3/d4/e5/f6/g10’

    removed directory: ‘a1/b2/c3/d4/e5/f6’

    removed directory: ‘a1/b2/c3/d4/e5’

    removed directory: ‘a1/b2/c3/d4’

    removed directory: ‘a1/b2/c3’

    removed ‘a1/b2/icu.txt’

    removed directory: ‘a1/b2’

    removed ‘a1/996.txt’

    removed directory: ‘a1/’

     

    # ls

    007.txt   anaconda-ks.cfg

    经过一番操作以后,只剩下了007了。除了上面基本的操作,接下来我要介绍一些更加重要的功能。

    可以看到在使用rm删除文件的时候,进行了一次提示。这是为了避免误删除一些东西,但有时候,你需要不显示这种提示,就可以加-f参数。f参数对于cp、mv等命令来说,同样适用,它是force的意思

    rm -f file

    cp -f file1 file2

    mv -f file1 file2

    另外,还有一个参数-r,这是递归的意思。我们的目录和文件,通常有多个层次,递归可以把操作全部作用于上面,比如上面的递归删除a1目录。

    # 警告:以下命令会造成严重后果

    rm -rf /

    上面的这个命令,你一定经常看到。这不是笑话,已经有很多用户因此丢失了数据,这就是传说中的删根,最终你将一无所有。那参数v又是干什么用的呢?加上它之后,可以看到命令详细的执行过程。在平常的操作中,我一般都加上。

    6.开始操作文件

    你可能已经了解到,ll -l命令的第一列,能够显示linux的文件类型。请对此有一个大体的印象,因为后面的很多命令,会用到这些知识。

  • - 表示普通文件
  • d 表示目录文件
  • l 表示链接文件,比如快捷方式
  • s 套接字文件
  • c 字符设备文件,比如/dev/中的很多文件
  • b 表示块设备文件,比如一些磁盘
  • p 管道文件
  • Linux上的文件可以没有后缀,而且可以创建一些违背直觉的文件。比如后缀是png,但它却是一个压缩文件。大学时,就有聪明的同学这样看小电影,效果很好。

    查看文件的具体类型,可以使用file命令,它很聪明,能够识别很多文件格式。

    # file /etc

    /etc: directory

    # file /etc/group

    /etc/group: ASCII text

    # file /dev/log

    /dev/log: socket

    # file /dev/log

    /dev/log: socket

    # file /bin

    /bin: symbolic link to `usr/bin'

    本部分的操作,面向的就是 ASCII text类型的,普通文本文件。接下来,我们要创建一些文件。然后写入一些内容到文件里,以便进行后续的操作。

    6.1、创建一个文件6.1.1、数字序列

    使用重定向符,能够直接生成文件。下面,我要生成10到20的数字,每一个数字单独一行,写入一个叫做spring的文件。巧的很,seq命令可以完成这个过程。

    seq 10 20 >> spring

    我们在前面提到过>的意思,是将前面命令的输出,重定向到其他地方。在这里,我们用了两个>,它依然是重定向的意思,但表示的是,在原来文件的基础上,追加内容。

    也就是编程语言里的w+和a+的意思。

    6.1.2、查看内容

    为了查看文件的生成效果,可以使用cat命令检测。cat命令将会把文件的内容,输出打印到终端上。如果加上参数n,甚至可以打印行号。效果如下:

    # cat spring

    # cat -n spring

    除了查看文件内容,cat命令通常用在更多的地方。只有和其他命令联合起来,它才会觉得生活有意义。

    # 合并a文件和b文件到c文件

    cat a  b>> c

     

    # 把a文件的内容作为输入,使用管道处理。我们在后面介绍

    cat a | cmd

     

    # 写入内容到指定文件。在shell脚本中非常常用。我们在后面会多次用到这种写法

    cat > index.html <<EOF

    <html>

        <head><title></title></head>

        <body></body>

    </html>

    EOF

     

    由于我们的文件不大,cat命令没有什么危害。但假如文件有几个GB,使用cat就危险的多,这只叫做猫的小命令,会在终端上疯狂地进行输出,你可以通过多次按ctrl+c来终止它。

    6.2、平和地查看文件

    既然cat命令不适合操作大文件,那一定有替换的方案。less和more就是。由于less的加载速度比more快一些,所以现在一般都使用less。它最主要的用途,是用来分页浏览文件内容,并提供一些快速查找的方式。less是一个交互式的命令,你需要使用一些快捷键来控制它。

    这次我们使用seq生成一千万行记录,足足有76MB大小,然后用less打开它。

    # seq 10000000 > spring

    # du -h spring

    76M spring

    # less spring

    关于less,一般操作如下:

  • 空格 向下滚屏翻页
  • b 向上滚屏翻页
  • / 进入查找模式,比如/1111将查找1111字样
  • q 退出less
  • g 到开头
  • G 去结尾
  • j 向下滚动
  • k 向上滚动,这两个按键和vim的作用非常像
  • 6.3、文件头尾

    head可以显示文件头,tail可以显示文件尾。它们都可以通过参数-n,来指定相应的行数。

    # head -n 3 spring

    # tail -n 3 spring

    9999998

    9999999

    10000000

    对于部分程序员来说,tail -f或许是最常用的命令之一。它可以在控制终端,实时监控文件的变化,来看一些滚动日志。比如查看nginx或者tomcat日志等等。通常情况下,日志滚动的过快,依然会造成一些困扰,需要配合grep命令达到过滤效果。

    # 滚动查看系统日志

    tail -f /var/log/messages

     

    # 滚动查看包含info字样的日志信息

    tail -f /var/log/messages | grep info

    对于tail命令来说,还有一个大写的参数F。这个参数,能够监控到重新创建的文件。比如像一些log4j等日志是按天滚动的,tail -f无法监控到这种变化。

    6.4、查找文件

    考虑下面这个场景。我们需要找一个叫做decorator.py的文件,这个文件是个幽灵,可能存在于系统的任何地方。find命令,能够胜任这次捉鬼行动。

    我们使用find命令,从根目录找起,由于系统的文件过多,下面的命令可能会花费一段时间。

    # find / -name decorator.py  -type f

    /usr/lib/python2.7/site-packages/decorator.py

    使用time命令,可以看到具体的执行时间。执行还是挺快的么!秒出!

    # time find / -name decorator.py  -type f

    /usr/lib/python2.7/site-packages/decorator.py

     

    real    0m0.228s

    user    0m0.098s

    sys 0m0.111s

    find命令会查出一个路径的集合。通常是查询出来之后,进行额外的处理操作,一般配合xargs命令使用,至于find的exec参数?忘了它吧,不好用!

    # 删除当前目录中的所有class文件

    find . | grep .class$ | xargs rm -rvf

     

    # 找到/root下一天前访问的文件,type后面的类型参见文章开头

    find /root  -atime 1 -type f

     

    # 查找10分钟内更新过的文件

    find /root  -cmin  -10

     

    # 找到归属于root用户的文件

    find /root -user root

     

    # 找到大于1MB的文件,进行清理

    find /root -size  +1024k  -type f | xargs rm -f

    find的参数非常非常多,记不住怎么办?除了常用的,其实都可以通过man命令查看。man的操作也和vi非常的类似,输入/EXAMPLES,会看到很多样例。不过我觉得还是上面列出的这些命令更加的适用。

    6.4.1、数据来源

    在上图中,你会看到mtime,ctime,atime类似的字样,它们的数据来自于何处呢?接下来我们顺理成章地看一下stat命令。

    # stat spring

      File: ‘spring’

      Size: 78888897   Blocks: 154080     IO Block: 4096   regular file

    Device: fd00h/64768d   Inode: 8409203     Links: 1

    Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

    Context: unconfined_u:object_r:admin_home_t:s0

    Access: 2019-11-04 18:01:46.698635718 -0500

    Modify: 2019-11-04 17:59:38.823458157 -0500

    Change: 2019-11-04 17:59:38.823458157 -0500

     Birth: -

    这不就是文件属性么?从文件大小,到文件类型,甚至到最后修改、访问时间,都可以从这里获取。Linux文件系统以块为单位存储信息,为了找到某一个文件所在存储空间的位置,会用i节点(inode) 对每个文件进行索引,你可以认为它是一个文件指针。

  • 文件的字节数
  • 文件拥有者user
  • 文件所属组group
  • 文件的读、写、执行权限
  • 文件的时间戳ctime指inode上一次变动的时间mtime指文件内容上一次变动的时间atime指文件上一次打开的时间。
  • 链接数,即有多少文件名指向这个inode
  • 文件数据block的位置
  • 关于inode是一个比较大的话题,也是比较重要的知识点,有兴趣的可以自行搜索。我们只需要知道这些信息是从这里来的就可以了。

    6.4.2、小练习

    如果我只想获取Modify这个数值,可以组合使用一下上面写到的命令。首先获取最后三行,然后获取首行。效果如下:

    # stat spring | tail -n 3 | head -n 1

    Modify: 2019-11-04 17:59:38.823458157 -0500

    下面几个命令,效果是与上面等价的,输出结果也是一模一样。正所谓条条大路通罗马,接下来,我们首先介绍一下出现频率较高的grep。另外,我们在上面的这些命令中,多次使用了|,这是Linux中非常重要的管道概念,下面也会着重介绍。

    stat spring | head -n 7 | tail -n 1

    stat spring | grep Modify

    stat spring | sed -n '7p'

    stat spring | awk 'NR==7'6.5、字符串匹配

    grep用来对内容进行过滤,带上--color参数,可以在支持的终端可以打印彩色,参数n则用来输出具体的行数,用来快速定位。这是一个必须要熟练使用的命令。

    比如:查看nginx日志中的POST请求。

    grep -rn --color POST access.log

    推荐每次都使用这样的参数。

    如果我想要看某个异常前后相关的内容,就可以使用ABC参数。它们是几个单词的缩写,经常被使用。

  • A after 内容后n行
  • B before 内容前n行
  • C 内容前后n行
  • 就像是这样:

    # 查看Exception关键字的前2行和后10行

    grep -rn --color Exception -A10 -B2   error.log

     

    #查找/usr/下所有import关键字,已经它们所在的文件和行数

    grep -rn --color import /usr/6.6、管道

    在上面的命令中,我们多次用到了|,这貌似可以完成一些神奇的事情。|是pipe的意思,它可以把多个命令联系起来。通常,命令有下面的关联方式:

  • ; 顺序执行,如mkdir a;rmdir a
  • && 条件执行,如mkdir a && rmdir a
  • || 条件执行,如mkdir a || rmdir a,后面的命令将不执行
  • | 管道,前面命令的输出,将作为后面命令的输入
  • 前三种的命令关联,是非常简单有逻辑的,非常的好理解。而管道,却有自己的特点。

    接触过编程语言的都知道stdin、stdout、stderr的概念。让我们重新组织一下针对于管道的定义:前面命令的输出(stdin),将作为后面命令的输入(stdout)。

    我们拿一行命令来说明。

    seq 20 100 | head -n 50 | tail -n 1

    上面命令,将输出69。69是个神奇的数字,它是怎么办到的呢?我们来一张小图,一切就豁然开朗了。

    关于输入输出和错误,linux使用一个数字进行缩写,这在一些脚本中,甚至在一些安装文件中,会经常用到。

  • 0 表示stdin标准输入
  • 1 表示stdout标准输出
  • 2 表示stderr标准错误
  • 通过类似2>&1的语法,可以把错误信息定向到标准输出。我们用命令来证明一下。

    # 错误信息无法输出到文件

    # cat aaaaaaaaa > b

    cat: aaaaaaaaa: No such file or directory

    # cat b

     

    # 错误信息被重定向了

    # cat aaaaaaaaa > b 2>&1

    # cat b

    cat: aaaaaaaaa: No such file or directory

    温馨提示:本文内容由互联网用户自发贡献,该文观点仅代表作者本人,如有侵权,请联系删除!