Dtpark's blog 磨刀不误砍柴工,读完硕士再打工

【Shell笔记】(一)Shell的基本概念及使用

2021-11-01
   

一、基本概念

1.1 shell

shell 是一个命令行解释器,它输出一个提示符,等待输人一个命令行,然后执行这个命令。

如果该命令行的第一个单词不是一个内置的 shell 命令,那么 shell 就会假设这是一个可执行文件的名字,它将加载并运行这个文件。

1.2 参数

参数跟在程序名后用空格分隔开的字符(串)。

参数中需要(空格)时,有两种方法:

  • " "' '扩起来组成字符串作为一个参数
  • 在空格前写转译字符\,将空格转译

""''的区别

  • "":若其包裹的内容中有变量,则变量被解析
  • '':若其包裹的内容中有变量,则变量不会被解析
$ foo=123	# 定义变量 foo 的值为 123

$ echo "$foo"	# 直接输出变量值                
123

$ echo '$foo'	# 不会转译输出
$foo

echo datedate echo会发生什么, 即参数为程序会输出什么?

1.3 环境变量($PATH)

当 shell 接到某条不是 shell 关键字的指令时,它会列出进行程序搜索的路径。

$ echo $PATH	# 输出由 : 所分割的一系列目录
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Shell 命令的加载流程,以echo为例:

当我们执行 echo 命令时,shell 了解到需要执行 echo 这个程序,随后它便会在 $PATH 中搜索由 : 所分割的一系列目录,基于名字搜索该程序。当找到该程序时便执行(假定该文件是 可执行程序)。

  • 确定指令代表的具体程序: which 指令名

    $ which echo  
    echo: shell built-in command
      
    $ which go  
    /usr/local/opt/go@1.14/bin/go
    

可以通过直接指定需要执行程序的路径来执行该程序,从而绕过$PATH

启动shell时要设置的变量为环境变量。

二、目录与文件操作(shell 中导航)

2.1 目录相关操作

  • 显示当前路径:pwd

    $ pwd
    /home/missing
    
  • 列出路径下文件:ls [参数] [路径],默认为当前路径

    $ ls
    bin
    boot
    dev
    etc
    home
    ...
    
    • 参数-l:使用长列表格式表示

      $ ls -l /home
      drwxr-xr-x 1 missing  users  4096 Jun 15  2019 missing
      
    • 参数-a:显示所有文件(包括隐藏文件)

    • 参数--help:显示手册(帮助文档)

  • 切换目录:cd [路径/参数]

    • 用(相对/绝对)路径切换目录(略)
    • 返回上次所在目录:cd -
  • 新建文件夹:mkdir 文件夹名称

2.2 文件相关操作

  • 移动/重命名:mv 源文件(可含路径) 目地文件(含路径)
  • 复制:cp 源文件(可含路径) 目地文件(含路径)
  • 新建文件:touch 文件名称

2.3 其它

  • 查看程序手册:man 程序名,如 man test
  • 清屏:clearctrl+l
  • 用合适的软件打开文件:xdgopen

三、程序间的操作(在程序间创建连接)

在 shell 中,程序有两个主要的“流”:输入流输出流

当程序尝试读取信息时,它们会从输入流中进行读取,当程序打印信息时,它们会将信息输出到输出流中。

通常,一个程序的输入输出流都是终端。即键盘作为输入,显示器作为输出。 但是,我们也可以重定向这些流。

  • 最简单的重定向是 < file> file。这两个命令可以将程序的输入输出流分别重定向到文件:

    $ echo hello > hello.txt
    $ cat hello.txt
    hello
    $ cat < hello.txt
    hello
    $ cat < hello.txt > hello2.txt
    $ cat hello2.txt
    hello
    
  • 向文件追加内容:>>

    $ echo new line >> hello.txt
    $ cat hello.txt
    hello
    new line
    
  • 管道(pipes):|,将左边程序的输出作为右边程序的输入

    $ ls -l / | tail -n1	# lail 为打印文件最后一行
    drwxr-xr-x 1 root  root  4096 Jun 20  2019 var
      
    $ curl --head --silent baidu.com
      
    HTTP/1.1 200 OK
    Date: Fri, 29 Oct 2021 06:55:29 GMT
    Server: Apache
    Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
    ETag: "51-47cf7e6ee8400"
    Accept-Ranges: bytes
    Content-Length: 81
    Cache-Control: max-age=86400
    Expires: Sat, 30 Oct 2021 06:55:29 GMT
    Connection: Keep-Alive
    Content-Type: text/html
      
    $ curl --head --silent baidu.com | grep -i content-length | cut --delimiter=' ' -f2
    81
    

四、root 用户相关

对于大多数的类 Unix 系统,有一类用户是非常特殊的,那就是:根用户(root user)。根用户几乎不受任何限制,他可以创建、读取、更新和删除系统中的任何文件。

注意:通常在并不会以根用户的身份直接登录系统,因为这样可能会因为某些错误操作而破坏系统。

当普通用户需要root 权限时,使用 sudo 命令。它的作用是可以以 su(super user 或 root 的简写)的身份执行一些操作。

有一件事情是您必须作为根用户才能做的,那就是向 sysfs 文件写入内容。系统被挂载在 /sys 下,sysfs 文件则暴露了一些内核(kernel)参数。 因此,您不需要借助任何专用的工具,就可以轻松地在运行期间配置系统内核。

  • 注意: Windows 和 macOS 没有/sys/sysfs文件

  • /sys下是Linux的各种内核参数
  • /sys/class 下有很多有趣的文件

|>、和 < 是通过 shell 执行的,而不是被各个程序单独执行。若使用上述符号操作当前用户无权修改的文件,会报错。

$ echo 3 > /sys/class/backlight/thinkpad_screen/brightness
An error occurred while redirecting file 'brightness'
open: Permission denied

$ echo 3 | sudo tee brightness	# 正确格式

echo 等程序并不知道 | 的存在,它们只知道从自己的输入输出流中进行读写。 对于上面这种情况, shell (权限为当前用户) 在设置 sudo echo 前尝试打开 brightness 文件并写入,但是系统拒绝了 shell 的操作因为此时 shell 不是根用户。

五、参考资料


Comments

Content