1

【Linux】《The Command Line Handbook》 读书笔记(上半部分)

前言

这篇博客介绍的命令确实比较多,并且受到平台字数影响,拆分为上下两个部分。

与其说是读书笔记,实际上更像是学学英语顺带学学Linux命令。这本书是通过每天挤一点时间边看边学边敲完成的,每天日常翻翻所以顺序和原始博客网站不太一样。

个人起初看这个“书”的时候PDF还是免费开放的,不过现在博主已经转为收费了,但是在线版本依然免费对外公开。

此外英文博主还出过很多小而美的初级教程,英文用词和语法都比较简单,非常适合像我一样词汇量薄弱的人看看。

这个教程对于一些简单的Linux入门是用是非常足够,话不多说我们直接开始。

英文博客网址

网址:https://thevalleyofcode.com/linux/#54-traceroute

image.png

在最近的更新当中,作者改名并且把书名改为了《The Command Line Handbook》,在线网址如下:flaviocopes.com

image.png

介绍

Linux是操作系统,和MacOs和Windows没什么区别。Linux“核心”(称为内核)于 1991 年在芬兰诞生,从其不起眼的开始经历了很长的路要走。它继续成为 GNU 操作系统的内核,创建了双核 GNU/Linux。

相比Windows和MacOs系统不同的是,Linux是永久免费的。如果你使用Mac,你需要知道macOS是一个UNIX操作系统,它与GNU/Linux系统有很多相共同的思想,Shell命令也甚至部分软件可以直接兼容,因为GNU/Linux是基于UNIX开源的。

而如果使用Windows,则提供了Windows Subsystem for Linux 来实现运行Linux的相关内容。但是个人并不推荐是用WSL来学习Linux命令。(更推荐虚拟机)

绝大多数下使用Linux是在VPS (Virtual Private Server) 等环境当中,Linux提供了shell来执行脚本或者文本来执行一系列操作。同时shell 允许以比 GUI(图形用户界面)更优化的方式执行操作。命令行工具可以提供许多不同的配置选项,并且使用过程中并不会特别复杂。

最后注意,博主用的是Mac电脑编写的笔记,部分命令在CenterOs系统和Ubuntu不一定适用,请以个人实验效果为准。

man

第一个命令是查询命令的命令,man帮助我们理解所有其他命令。不知道如何使用命令时我们可以键入 man <command> 来获取手册:

LS(1)                                               User Commands                                              LS(1)

NAME
       ls - list directory contents

SYNOPSIS
       ls [OPTION]... [FILE]...

DESCRIPTION
       List  information about the FILEs (the current directory by default).  Sort entries alphabetically if none of
       -cftuvSUX nor --sort is specified.

       Mandatory arguments to long options are mandatory for short options too.

       -a, --all
              do not ignore entries starting with .

       -A, --almost-all
              do not list implied . and ..

       --author
              with -l, print the author of each file

       -b, --escape
              print C-style escapes for nongraphic characters

       --block-size=SIZE
              scale sizes by SIZE before printing them; e.g., '--block-size=M' prints sizes in  units  of  1,048,576
              bytes; see SIZE format below

       -B, --ignore-backups
              do not list implied entries ending with ~

man命令是学习Linux必不可少的工具,但是有时候为了快速学习一个命令,并不是把参数列举就是好的,更多时候我们会想要看到实际案例快速上手。

为了快速学习命令推荐使用 tldrhttps://tldr.sh/) 的网站。我们可以安装的命令 tldr 快速上手,然后像这样运行它:tldr <command>

它给你一个非常快速的命令概述,并提供一些常见使用场景的方便示例:

ubuntu@VM-8-8-ubuntu:~$ sudo tldr ls
Cache is out of date. You should run "tldr --update"

  ls

  List directory contents.
  More information: https://www.gnu.org/software/coreutils/ls.

  - List files one per line:
    ls -1

  - List all files, including hidden files:
    ls -a

  - List all files, with trailing / added to directory names:
    ls -F

  - Long format list (permissions, ownership, size, and modification date) of all files:
    ls -la

  - Long format list with size displayed using human-readable units (KiB, MiB, GiB):
    ls -lh

  - Long format list sorted by size (descending):
    ls -lS

  - Long format list of all files, sorted by modification date (oldest first):
    ls -ltr

  - Only list directories:
    ls -d */

注意tldr这个命令需要NodeJs的环境,建议先安装NodeJs,这里了跳过NodeJs的安装过程

[zxd@localhost ~]$ tldr
Usage: tldr command [options]

Simplified and community-driven man pages

Options:
  -v, --version            Display version
  -l, --list               List all commands for the chosen platform in the cache
  -a, --list-all           List all commands in the cache
  -1, --single-column      List single command per line (use with options -l or -a)
  -r, --random             Show a random command
  -e, --random-example     Show a random example
  -f, --render [file]      Render a specific markdown [file]
  -m, --markdown           Output in markdown format
  -o, --os [type]          Override the operating system [linux, osx, sunos, windows]
  --linux                  Override the operating system with Linux
  --osx                    Override the operating system with OSX
  --sunos                  Override the operating system with SunOS
  --windows                Override the operating system with Windows
  -t, --theme [theme]      Color theme (simple, base16, ocean)
  -s, --search [keywords]  Search pages using keywords
  -u, --update             Update the local cache
  -c, --clear-cache        Clear the local cache
  -h, --help               Show this help message

  Examples:

    $ tldr tar
    $ tldr du --os=linux
    $ tldr --search "create symbolic link to file"
    $ tldr --list
    $ tldr --list-all
    $ tldr --random
    $ tldr --random-example

  To control the cache:

    $ tldr --update
    $ tldr --clear-cache

  To render a local file (for testing):

    $ tldr --render /path/to/file.md

如果你觉得搞NodeJs环境和版本十分麻烦,还有个类似的替代品cheat,它的使用非常简单,把官方文档介绍的脚本执行之后即可使用。

官方安装教程:cheat/INSTALLING.md at master · cheat/cheat (github.com)")

当然tldr的github项目中也介绍了其他替代品:

Similar projects

  • Command Line Interface Pages allows you to write standardized help pages for CLI, directories and configs.
  • Cheat allows you to create and view interactive cheatsheets on the command-line. It was designed to help remind *nix system administrators of options for commands that they use frequently, but not frequently enough to remember.
  • cheat.sh Aggregates cheat sheets from multiple sources (including tldr-pages) into 1 unified interface.
  • devhints Rico's cheatsheets are not just focused on the command-line and include a plethora of other cheatsheets related to programming.
  • eg provides detailed examples with explanations on the command-line. Examples come from the repository, but eg supports displaying custom examples and commands alongside the defaults.
  • kb is a minimalist command-line knowledge base manager. kb can be used to organize your notes and cheatsheets in a minimalist and clean way. It also supports non-text files.
  • navi is an interactive cheatsheet tool, which allows you to browse through specific examples or complete commands on the fly.
  • bropages (deprecated) are a highly readable supplement to man pages. It shows concise, common-case examples for Unix commands. The examples are submitted by the user base, and can be voted up or down; the best entries are what people see first when they look up a command.
  • Command Line Interface Pages allows you to write standardized help pages for CLI, directories and configs.
  • Cheat allows you to create and view interactive cheatsheets on the command-line. It was designed to help remind *nix system administrators of options for commands that they use frequently, but not frequently enough to remember.
  • cheat.sh Aggregates cheat sheets from multiple sources (including tldr-pages) into 1 unified interface.
  • devhints Rico's cheatsheets are not just focused on the command-line and include a plethora of other cheatsheets related to programming.
  • eg provides detailed examples with explanations on the command-line. Examples come from the repository, but eg supports displaying custom examples and commands alongside the defaults.
  • kb is a minimalist command-line knowledge base manager. kb can be used to organize your notes and cheatsheets in a minimalist and clean way. It also supports non-text files.
  • navi is an interactive cheatsheet tool, which allows you to browse through specific examples or complete commands on the fly.
  • bropages (deprecated) are a highly readable supplement to man pages. It shows concise, common-case examples for Unix commands. The examples are submitted by the user base, and can be voted up or down; the best entries are what people see first when they look up a command.

printenv

这个命令可以发打印当前的环境变量参数,如果需要打印指定环境变量的值就需要指定对应的key,注意linux系统对于大小写敏感,变量名要区分大小写 。

ubuntu@VM-8-8-ubuntu:~$ printenv 
SHELL=/bin/bash
HISTSIZE=1000
HISTTIMEFORMAT=%F %T 
PWD=/home/ubuntu
LOGNAME=ubuntu
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/home/ubuntu
LANG=en_US.UTF-8

printenv命令的快速指南,用于打印环境变量的值

在任何一个shell中,都有大量的环境变量,它们或者由系统设置,或者由你自己的shell脚本和配置设置。

你可以使用printenv命令将它们全部打印到终端。你可以附加一个变量名作为参数,只显示该变量值,其输出结果将是这样的:

[zxd@localhost ~]$ printenv JAVA_HOME
/opt/jdk8
[zxd@localhost ~]$ printenv PATH
/opt/maven-3.8.6/bin:/opt/jdk8/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/zxd/.local/bin:/home/zxd/bin

ls

ls是 list 的缩写,作用是打印某个文件夹下面的所有文件。

ls -al

ls -al 可以使用竖状的展示当前文件夹的所有内容。

xander@xander:~$ ls -al
total 76
drwxr-x--- 6 xander xander 4096 Mar 11 02:20 .
drwxr-xr-x 3 root   root   4096 Jan  8 03:12 ..
-rw------- 1 xander xander 1550 Feb 27 23:50 .bash_history
-rw-r--r-- 1 xander xander  220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 xander xander 3771 Jan  6  2022 .bashrc
drwx------ 2 xander xander 4096 Jan  8 03:12 .cache
drwx------ 3 xander xander 4096 Mar 11 02:20 .config
-rwxrwxr-x 1 xander xander  174 Feb  3 13:37 demo2.sh
-rwxrwxr-x 1 xander xander  223 Feb  3 13:17 demo-arges.sh
-rw-rw-r-- 1 xander xander   30 Feb 24 23:25 error.txt
-rwxrwxr-x 1 xander xander  277 Feb  3 13:22 func-args.sh
-rw------- 1 xander xander   20 Mar 11 01:50 .lesshst
-rw-rw-r-- 1 xander xander   18 Feb 24 23:24 log.txt
-rw-r--r-- 1 xander xander  807 Jan  6  2022 .profile
drwx------ 2 xander xander 4096 Jan  8 03:14 .ssh
-rw-r--r-- 1 xander xander    0 Jan  8 03:26 .sudo_as_admin_successful
drwxrwxr-x 2 xander xander 4096 Mar 11 00:33 tesgt
-rw------- 1 xander xander 5795 Feb  3 13:37 .viminfo
-rw------- 1 xander xander  104 Mar 11 00:31 .Xauthority

从左到右的含义:

  • the file permissions (and if your system supports ACLs, you get an ACL flag as well)
  • the number of links to that file
  • the owner of the file
  • the group of the file
  • the file size in bytes
  • the file modified datetime
  • the file name

mkdir

使用mkdir用于创建一个新的文件夹:

mkdir test

mkdir 后面接多个参数,可以创建多个文件夹。

mkdir test1 test2 test3

还有一个特殊的路径指示器,它是 .,表示当前的文件夹。

你也可以使用绝对路径,从根文件夹/开始:

cd /etc

这个命令可以在Linux、macOS、WSL以及任何有UNIX环境的地方使用。

rmdir

和mkdir命令刚好相反,这个命令用于删除一个目录。

[zxd@localhost ~]$ mkdir test
[zxd@localhost ~]$ rmdir test

删除多个文件夹则在命令后面跟进多个文件夹名称即可。

[zxd@localhost ~]$ mkdir test test1 test2
[zxd@localhost ~]$ rmdir test test1 test2

注意默认情况下删除一个内部带文件的文件夹会报错:

[zxd@localhost ~]$ mkdir test
[zxd@localhost ~]$ touch test/test.txt
[zxd@localhost ~]$ rmdir test
rmdir: failed to remove ‘test’: Directory not empty

要删除带有其他文件的文件夹,我们将使用更通用的 rm命令,该命令使用-rf选项删除文件和文件夹:

rm -rf test
请谨慎使用此命令!
[zxd@localhost ~]$ mkdir test 
mkdir: cannot create directory ‘test’: File exists
[zxd@localhost ~]$ touch test/test.txt
[zxd@localhost ~]$ rm -r test

从命令行删除文件时,没有bin记录,恢复丢失的文件可能很困难。

mv

mv的通常用途是用于把一个文件挪到另一个位置:

[zxd@localhost ~]$ mkdir test
[zxd@localhost ~]$ cd test
[zxd@localhost test]$ mkdir bemoved
[zxd@localhost test]$ touch a.txt aaa
[zxd@localhost test]$ cat a.txt 
[zxd@localhost test]$ mv a.txt bemoved/
[zxd@localhost test]$ ls bemoved/
a.txt

mv还可以用于重命名:

[zxd@localhost test]$ mv bemoved/a.txt bemoved/b.txt
[zxd@localhost test]$ ls bemoved/
b.txt

如果想要把多个文件夹的内容移动到指定的文件夹,在mv参数当中以最后一个参数为目标,具体的案例如下:

[zxd@localhost test]$ mkdir apple pear
[zxd@localhost test]$ mkdir fruits
[zxd@localhost test]$ mv apple pear fruits/
[zxd@localhost test]$ ls fruits/
apple  pear

mv还有一个隐藏作用是“重命名”:

ubuntu@VM-8-8-ubuntu:~$ ls
''$'\033''[200~recipes.txt~'   compress   dif              error.txt   list2.txt.gz   newrecipes.txt   otherfile.txt   testdata.txt      test.txt
 archive.tar                   current    echoresult.txt   list2.txt   list.txt.gz    otherfile2.txt   testdata2.txt   testdata.txt.gz
 
ubuntu@VM-8-8-ubuntu:~$ mv dif difff


ubuntu@VM-8-8-ubuntu:~$ ls
''$'\033''[200~recipes.txt~'   compress   difff            error.txt   list2.txt.gz   newrecipes.txt   otherfile.txt   testdata.txt      test.txt
 archive.tar                   current    echoresult.txt   list2.txt   list.txt.gz    otherfile2.txt   testdata2.txt   testdata.txt.gz
ubuntu@VM-8-8-ubuntu:~$ 

touch

touch命令通常用于构建一个新文件:

touch apple

注意如果该文件已经存在,它将以写模式打开该文件并更新文件的时间戳

ubuntu@VM-8-8-ubuntu:~$ ls -l
-rw-rw-r-- 1 ubuntu ubuntu   0 Mar 14 13:18 list2.txt

ubuntu@VM-8-8-ubuntu:~$ touch list2.txt 
ubuntu@VM-8-8-ubuntu:~$ ls -l
-rw-rw-r-- 1 ubuntu ubuntu   0 Mar 15 13:24 list2.txt

那么如果touch一个有数据的文件呢?实际上也是更新时间戳。

ubuntu@VM-8-8-ubuntu:~$ ls -l
total 24

-rw-rw-r-- 1 ubuntu ubuntu 226 Mar 14 13:22 list.txt

ubuntu@VM-8-8-ubuntu:~$ touch list.txt 

ubuntu@VM-8-8-ubuntu:~$ ls -l
total 24
-rw-rw-r-- 1 ubuntu ubuntu 226 Mar 15 13:25 list.txt

find

find 命令主要用于 Linux 的文件查找,可以借助此命令寻找符合特定搜索模式的文件或文件夹。它的搜索是递归的。

比如下面的案例,查找当前目录所有的txt文件:

-rw-rw-r-- 1 ubuntu ubuntu  16 Mar 14 13:13 testdata.txt
ubuntu@VM-8-8-ubuntu:~$ find . -name '*.txt'
./testdata2.txt
./otherfile2.txt
./testdata.txt
./list2.txt
./otherfile.txt
./error.txt
./list.txt
./.config/cheat/cheatsheets/community/.github/LICENSE.txt
提示:在特殊字符(如 *)周围需要使用“引号”,避免shell对其进行其他解释。

下面的案例是查找当前系统所有路径带有src的文件夹,但是会发现这里会出现“无权访问”的提示:

ubuntu@VM-8-8-ubuntu:~$ find / -type d -name src
find: ‘/tmp/systemd-private-b1f69592ff0a423584359e16f90b4c29-ModemManager.service-yvVX9P’: Permission denied
find: ‘/tmp/systemd-private-b1f69592ff0a423584359e16f90b4c29-ntp.service-VRK7Gs’: Permission denied
find: ‘/tmp/tat_agent’: Permission denied
find: ‘/tmp/systemd-private-b1f69592ff0a423584359e16f90b4c29-systemd-resolved.service-3IzTT4’: Permission denied
find: ‘/tmp/8a6be2f9e39171ef24ae0f7757c5d095’: Permission denied
find: ‘/tmp/systemd-private-b1f69592ff0a423584359e16f90b4c29-systemd-logind.service-92E7Xj’: Permission denied
find: ‘/tmp/snap-private-tmp’: Permission denied
find: ‘/var/cache/pollinate’: Permission denied

这些恼人的报错可以通过重定向stderr/dev/null过滤掉:

ubuntu@VM-8-8-ubuntu:~$ find / -type d -name src 2> /dev/null
/usr/src
/usr/src/linux-headers-5.15.0-48/tools/usb/usbip/src
/usr/src/linux-headers-5.15.0-48/drivers/gpu/drm/amd/display/dmub/src
/usr/include/nodejs/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/agent-base/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/agent-base/dist/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/tiny-relative-date/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/node-gyp/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/cli-table3/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/debug/src
/usr/local/n/versions/node/16.15.1/lib/node_modules/npm/node_modules/has/src
/usr/local/n/versions/node/19.5.0/lib/node_modules/npm/node_modules/agent-base/src
/usr/local/n/versions/node/19.5.0/lib/node_modules/npm/node_modules/agent-base/dist/src
...

通过上面的命令可以看到所有包含src文件夹的路径被展示出来。

-type d 表示搜索文件夹。

-type f:表示仅仅搜索文件夹,

-type l 表示只搜索符号连接。

此外还需要注意,-name是区分大小写的。使用-iname来执行不区分大小写的搜索。上面介绍的都是搜索单个文件夹,搜索多个文件路径可以使用下面的方式:

find folder1 folder2 -name filename.txt

再比如在多个文件夹下面搜索需要的文件:

sudo find /usr  ~/  ’*.txt‘

如果是匹配多个文件名称,则可以使用 -or 拼接搜索条件:

find . -type d -name node_modules -or -name otherfile.txt
./otherfile.txt

当然也可以添加排除的文件路径,搜索的时候跳过他们:

find . -type d -name '*.md' -not -path 'node_modules/*'

还可以搜索其中有超过100个字符(字节)的文件:

find . -type f -size +100c

查找文件大小大于100KB但是小于1M的文件:

find . -type f -size +100k -size -1M

查找修改时间超过3天的文件

[zxd@localhost ~]$ find . -type f -mtime +3 -not -path './.*/*'
./.bash_logout
./.bash_profile
./.bashrc
./zookeeper-3.4.14.tar.gz.1
./.profile
./hello.c
./a.out
./.lesshst
./c.txt
./test.json
./sss.json
./zookeeper-3.4.14.tar_3.gz
./test.sh
./jdk-8u331-linux-x64.tar.gz
./apache-maven-3.8.6-bin.zip
./seata-server-1.6.1.tar.gz
./.mysql_history
./kafka_2.13-2.8.2.tgz
./.viminfo
./sys_dump.sql
./.node_repl_history
./.npmrc
./a.txt
./b.txt
./ss.json
./nohup.out
./test.txt

搜索过去24小时内编辑的文件

[zxd@localhost ~]$ find . -type f -mtime -1
./test/bemoved/a.txt
./test/aaa
./test/test.txt
./test/test_copy.txt
./test/bemoved_copy/a.txt

你可以通过添加-delete选项来删除所有与搜索匹配的文件,这将删除过去24小时内编辑的所有文件:

find . -type f -mtime -1 -delete

可以对每个搜索结果执行一个命令。在这个例子中,我们运行cat来打印文件内容:

下面的命令不要轻易尝试
find . -type f -exec cat {} \;

请注意,结尾处的" .{}在执行时被填上了文件名。

cd

cd 命令用于移动到指定的文件夹当中,可以指定文件夹相对路径或者绝对路径,比如:

mkdir fruits
cd fruits

在类Unix系统当中,..通常表示上一级目录,可以通过 cd .. 回到当前目录的上一级。

cd .. #back to the home folder
/ :是Linux的最顶级目录,通常称为根目录。

. 表示当前目录,当我们进入到当前路径对应的文件夹,隐藏含义是 cd ./文件夹

日常工作学习使用过程中多数是通过cd /etc 的方式,从顶层路径往下找到对应想要跳转的路径。

ln

ln命令是Linux文件系统命令的一部分。这个命令通常用于创建链接。链接类似指向其他文件的指针,一个文件指向另一个文件,它和Windows的快捷方式类似。

链接分为两种,软链接硬链接。先介绍硬链接,硬链接很少使用。它们有一些限制:你不能链接到目录,也不能链接到外部文件系统(磁盘)。

硬链接使用下面的方式构建:

ln <original> <link>

比如想要给名为recipes.txt的文件构建硬链接,使用下面的命令:

ln recipes.txt newrecipes.txt

从表面上看,你创建的新硬链接与普通文件没有区别。但是在任何时候只要改动硬链接文件其中一个,那么两个文件的内容都会被同时更改。

如果你删除了原始文件,链接仍将包含原始文件内容,因为有一个硬链接之前指向它,但是这个硬链接文件并不会被删除

下面介绍软链接,我们可以使用ln-s选项创建软链接,我们再次引用硬链接的例子,使用软链接只需要改动参数即可:

ln -s recipes.txt newrecipes.txt

构建软链接之后,如果此时用ls -la 查看 recipes.txt 文件和 newrecipes.txt,会发现软链接的文件有一个特殊的l标志,而且文件名在最后有一个@(原作者是Mac系统),如果你启用了颜色,它的颜色是不同的:

lrwxrwxrwx 1 ubuntu ubuntu   11 Mar 25 11:16  newrecipes.txt -> recipes.txt

如果删除了原始文件,Name软链接将被破坏,如果我们试图访问它,shell会告诉我们 "No such file or directory"

ubuntu@VM-8-8-ubuntu:~$ cat newrecipes.txt 
ubuntu@VM-8-8-ubuntu:~$ cat recipes.txt 
ubuntu@VM-8-8-ubuntu:~$ rm recipes.txt 
ubuntu@VM-8-8-ubuntu:~$ cat newrecipes.txt 

cat: newrecipes.txt: No such file or directory

cp

复制命令。

[zxd@localhost test]$ touch test.txt
[zxd@localhost test]$ cp test.txt test_copy.txt

[zxd@localhost test]$ ll
total 0
-rw-rw-r-- 1 zxd zxd  0 Mar 24 19:20 aaa
drwxrwxr-x 2 zxd zxd 19 Mar 24 21:10 bemoved
drwxrwxr-x 4 zxd zxd 31 Mar 24 21:16 fruits
-rw-rw-r-- 1 zxd zxd  0 Mar 24 21:17 test_copy.txt
-rw-rw-r-- 1 zxd zxd  0 Mar 24 21:17 test.txt

如果要拷贝文件夹需要添加-r参数,它会递归整个文件夹所有文件和目录一同拷贝到新地址

[zxd@localhost test]$ ls
aaa  bemoved  fruits  test_copy.txt  test.txt
[zxd@localhost test]$ ll bemoved/
total 0
-rw-rw-r-- 1 zxd zxd 0 Mar 24 19:20 a.txt

[zxd@localhost test]$ copy -r bemoved bemoved_copy

-bash: copy: command not found
[zxd@localhost test]$ cp -r bemoved bemoved_copy
[zxd@localhost test]$ ls
aaa  bemoved  bemoved_copy  fruits  test_copy.txt  test.txt

文件夹的内部文件也会一同拷贝:

[zxd@localhost test]$ ls bemoved_copy/
a.txt
[zxd@localhost test]$ ls bemoved
a.txt

拷贝如果没 -r 参数会报错:

[zxd@localhost test]$ cp  bemoved bemoved_copy2
cp: omitting directory ‘bemoved’

gzip

你可以使用gzip命令,用名为LZ77gzip压缩协议来压缩文件。最简单的用法如下:

gzip filename
ubuntu@VM-8-8-ubuntu:~$ gzip list.txt
ubuntu@VM-8-8-ubuntu:~$ ll
-rw-rw-r-- 1 ubuntu ubuntu  114 Mar 15 13:25 list.txt.gz

最简单的用法会把当前的文件删除,并且生成一个原始文件名+.gz的后缀名称。如果想要避免原文件被删除,可以通过重定向的方式,或者配合-c的选项重定向输出到 filename.gz

gzip -c filename > filename.gz

当然也可以用-k的选项,效果和上面的命令等效:

ubuntu@VM-8-8-ubuntu:~$ gzip -k list2.txt 
ubuntu@VM-8-8-ubuntu:~$ ll
-rw-rw-r-- 1 ubuntu ubuntu    0 Mar 15 13:24  list2.txt
-rw-rw-r-- 1 ubuntu ubuntu   30 Mar 15 13:24  list2.txt.gz

注意gzip内置了压缩等级的概念,从 压缩等级1(最快但是压缩比最小)压缩等级9(最慢但是压缩比最大),默认情况下使用gzip压缩等级为 6。

我们可以通过-(数字1-9)的方式的方式自定义压缩等级:

ubuntu@VM-8-8-ubuntu:~/compress$ touch aaa.txt
ubuntu@VM-8-8-ubuntu:~/compress$ vim aaa.txt 
ubuntu@VM-8-8-ubuntu:~/compress$ cat aaa.txt 
12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`

ubuntu@VM-8-8-ubuntu:~/compress$ gzip -1k aaa.txt 
ubuntu@VM-8-8-ubuntu:~/compress$ ll
total 16
drwxrwxr-x 2 ubuntu ubuntu 4096 Mar 25 11:26 ./
drwxr-x--- 8 ubuntu ubuntu 4096 Mar 25 11:26 ../
-rw-rw-r-- 1 ubuntu ubuntu  145 Mar 25 11:26 aaa.txt
-rw-rw-r-- 1 ubuntu ubuntu   44 Mar 25 11:26 aaa.txt.gz

压缩多个文件只需要在命令末尾指定多个文件,中间用空格分隔即可:

gzip filename1 filename2

你可以使用-r选项,递归地压缩一个目录中的所有文件:

注意并不是把整个文件夹打成一个压缩包
gzip -r a_folder

-v选项可以打印出压缩百分比信息。下面是一个它与-k选项一起使用的例子:

ubuntu@VM-8-8-ubuntu:~$ gzip -vk testdata.txt 
testdata.txt:    -12.5% -- created testdata.txt.gz

最后是使用gzip解压一个文件:

gzip -d filename.gz
ubuntu@VM-8-8-ubuntu:~$ gzip -d compress/
gzip: compress/ is a directory -- ignored
ubuntu@VM-8-8-ubuntu:~$ gzip -d compress/aaa.txt.gz 
ubuntu@VM-8-8-ubuntu:~$ cat compress/aaa.txt 
12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`12345678910`

gunzip

gunzip 命令基本上等同于gzip命令,除了-d选项总是默认启用。为了减少记忆负担,建议使用使用gzip -d等效替代。

gunzip filename.gz

gzip -d filename.gz 的效果一样,会解压压缩包,如果发现文件已经存在则会询问是否需要覆盖。

ubuntu@VM-8-8-ubuntu:~$ gzip -r compress/
gzip: compress/aaa.txt.gz already exists; do you wish to overwrite (y or n)? y

tar

tar 要比 gzip更为广泛流传和使用,tar命令用于创建一个归档文件,将多个文件分组在一个文件中。tar的全程叫做tape archive,就是说把指定的内容归档磁盘当中进行持久存储。

下面的命令把名字叫做 archive.tar 磁盘档案,它的内容包含error.txtlist2.txt 这两个文件。

ubuntu@VM-8-8-ubuntu:~$ tar -cf archive.tar error.txt list2.txt

ubuntu@VM-8-8-ubuntu:~$ ll
total 116
drwxr-x--- 8 ubuntu ubuntu  4096 Mar 25 13:35  ./
drwxr-xr-x 4 root   root    4096 Nov 10 07:16  ../
-rw-rw-r-- 1 ubuntu ubuntu     0 Mar 25 11:15 ''$'\033''[200~recipes.txt~'
-rw-rw-r-- 1 ubuntu ubuntu 10240 Mar 25 13:35  archive.tar

可以利用tar -tf的命令查看压缩包的文件内容。

ubuntu@VM-8-8-ubuntu:~$ tar -tf archive.tar 
error.txt
list2.txt

tar 也可以用于配合打包 gzip 压缩之后的文件。

ubuntu@VM-8-8-ubuntu:~$ tar -tf archive.tar 
error.txt
list2.txt
ubuntu@VM-8-8-ubuntu:~$ tar -cf archive.tar list2.txt.gz list.txt.gz 
ubuntu@VM-8-8-ubuntu:~$ tar -tf archive.tar 
list2.txt.gz
list.txt.gz

注意-c 选项代表创建。-f 选项用于将档案写入文件。要从当前文件夹中的存档中提取文件,请使用:

tar -xf archive.tar

-x的选项是用于解压软件的。如果要把当前的文件解压到一个特殊的目录可以使用-C的选项,但是需要注意目录要实际存在才行。

ubuntu@VM-8-8-ubuntu:~$ tar -xf archive.tar -C special
tar: special: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

ubuntu@VM-8-8-ubuntu:~$ tar -xf archive.tar -C compress/

ubuntu@VM-8-8-ubuntu:~$ ls compress/
aaa.txt  list2.txt.gz  list.txt.gz

前面介绍的gzip -d gunzip的命令都是用来解压压缩软件的,在解压缩档案时,你可以使用 gunzipgzip -d,然后解压缩,但 tar -xf会识别它是一个压缩档案并为你做这件事:

ubuntu@VM-8-8-tar -xf compress/list2.txt.gz
ubuntu@VM-8-8-ubuntu:~$ cat compress/list2.txt.gz                                                                                                               ¦Vdlist2.txt

综上所述个人更为建议用tar命令。

alias

别名命令可以把一些复杂指令通过别名的方式替代。比如现代大部分的Linux系统都提供了类似ll的命令替代ls -l,有的云服务器会带上颜色选项。

要查看一个别名命令的实际命令,可以参考下面的内容。

ubuntu@VM-8-8-ubuntu:~$ alias ll
alias ll='ls -alF'

我们同样也可以alias命令来指定自己的别名指令。

ubuntu@VM-8-8-ubuntu:~$ alias lsa='ls -la'

但是注意这种方式不能让命令持久化,在Session会话结束之后alias自定义就会失效

要使其永久化需要将命令添加到 shell 配置中,如果使用 Bash shell,则可能是 ~/.bashrc~/.profile,或者 ~/.bash_profile,具体取决于使用的操作系统。

如果命令中有变量,请注意引号要用双引号,变量在定义时解析,它在调用时解析使用单引号,这两个是不同的:

alias lsthis="ls $PWD"
alias lscurrent='ls $PWD'

第一个命令当中的$PWD,指的是shell当前所处的文件夹。举个栗子,如果现在浏览到新的文件夹,ls current会列出新文件夹中的文件,lsthis仍然会列出你定义别名时所在的文件夹中的文件。

ubuntu@VM-8-8-ubuntu:~$ alias lsthis="ls $PWD"
ubuntu@VM-8-8-ubuntu:~$ alias lscurrent='ls $PWD'

ubuntu@VM-8-8-ubuntu:~$ lsthis
''$'\033''[200~recipes.txt~'   compress    list2.txt      list.txt.gz      otherfile2.txt   testdata2.txt   testdata.txt.gz
 archive.tar                   error.txt   list2.txt.gz   newrecipes.txt   otherfile.txt    testdata.txt
ubuntu@VM-8-8-ubuntu:~$ lscurrent 
''$'\033''[200~recipes.txt~'   compress    list2.txt      list.txt.gz      otherfile2.txt   testdata2.txt   testdata.txt.gz
 archive.tar                   error.txt   list2.txt.gz   newrecipes.txt   otherfile.txt    testdata.txt

上面的结果看出两个命令的结果类似。

ubuntu@VM-8-8-ubuntu:~$ mkdir current
ubuntu@VM-8-8-ubuntu:~$ cd current/

ubuntu@VM-8-8-ubuntu:~/current$ lsthis
''$'\033''[200~recipes.txt~'   compress   error.txt   list2.txt.gz   newrecipes.txt   otherfile.txt   testdata.txt
 archive.tar                   current    list2.txt   list.txt.gz    otherfile2.txt   testdata2.txt   testdata.txt.gz
 
ubuntu@VM-8-8-ubuntu:~/current$ lscurrent 

从上面的案例来看,如果是新建的文件夹lscurrent是会显示当前的目录,lsthis依然会现实构建别名时候的所有文件。

cat

某些地方和tail命令比较类似,可以通过cat向文件添加内容。

ubuntu@VM-8-8-ubuntu:~$ cat error.txt 

Command 'pirntf' not found, did you mean:
  command 'printf' from deb coreutils (8.32-4.1ubuntu1)
Try: sudo apt install <deb name>

ubuntu@VM-8-8-ubuntu:~$ cat error.txt

Command 'pirntf' not found, did you mean:
  command 'printf' from deb coreutils (8.32-4.1ubuntu1)
Try: sudo apt install <deb name>

ubuntu@VM-8-8-ubuntu:~$ vim error.txt 

ubuntu@VM-8-8-ubuntu:~$ cat error.txt >> error2.txt

ubuntu@VM-8-8-ubuntu:~$ cat error2.txt 

Command 'pirntf' not found, did you mean:
  command 'printf' from deb coreutils (8.32-4.1ubuntu1)
Try: sudo apt install <deb name>

最简单的用法是用cat查看一个文件:

ubuntu@VM-8-8-ubuntu:~/current$ cat ../testdata.txt
abcdefg
hijklmn
aa
aa

cat 后面跟多个文件会合并显示多个文件的内容:

ubuntu@VM-8-8-ubuntu:~/current$ cat ../testdata.txt ../otherfile.txt
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn

利用>重定向输出流的方式的特性,我们可以用cat合并两个文件的结果输出到第三个文件:

ubuntu@VM-8-8-ubuntu:~/current$ cat ../testdata.txt ../otherfile.txt
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn
ubuntu@VM-8-8-ubuntu:~/current$ cat ../testdata.txt ../otherfile.txt > ./merge.txt
ubuntu@VM-8-8-ubuntu:~/current$ cat merge.txt 
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn

如果想要合并数据之后往一个已存在的文件追加,可以用 >> 符号:

ubuntu@VM-8-8-ubuntu:~/current$ cat merge.txt 
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn
ubuntu@VM-8-8-ubuntu:~/current$ cat ../testdata.txt ../otherfile.txt >> ./merge.txt
ubuntu@VM-8-8-ubuntu:~/current$ cat merge.txt 
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn
abcdefg
hijklmn
aa
aa
abcdefg
hijklmn

有时候在阅读代码文件,为了更好的定位所在位置,可以用-n参数打印行号:

ubuntu@VM-8-8-ubuntu:~/current$ cat -n merge.txt 
     1    abcdefg
     2    hijklmn
     3    aa
     4    aa
     5    abcdefg
     6    hijklmn
     7    abcdefg
     8    hijklmn
     9    aa
    10    aa
    11    abcdefg
    12    hijklmn

可以只用-b给非空行添加数字,或者你也可以用-s删除所有多空行。

ubuntu@VM-8-8-ubuntu:~/current$ cat -n merge.txt 
     1    abcdefg
     2    hijklmn
     3    aa
     4    aa
     5    
     6    
     7    abcdefg
     8    hijklmn
     9    abcdefg
    10    hijklmn
    11    aa
    12    
    13    
    14    aa
    15    abcdefg
    16    hijklmn
ubuntu@VM-8-8-ubuntu:~/current$ cat -sn merge.txt 
     1    abcdefg
     2    hijklmn
     3    aa
     4    aa
     5    
     6    abcdefg
     7    hijklmn
     8    abcdefg
     9    hijklmn
    10    aa
    11    
    12    aa
    13    abcdefg
    14    hijklmn
ubuntu@VM-8-8-ubuntu:~/current$ cat -bn merge.txt 
     1    abcdefg
     2    hijklmn
     3    aa
     4    aa


     5    abcdefg
     6    hijklmn
     7    abcdefg
     8    hijklmn
     9    aa


    10    aa
    11    abcdefg
    12    hijklmn

cat 命令比较常见的使用是搭配管道符传递结果给其他命令使用。

less

less 命令是作者经常使用的命令,它以漂亮的交互式UI显示存储在文档中的内容。

ubuntu@VM-8-8-ubuntu:~/current$ less merge.txt 

如果想要退出这一的交互式界面可以在键盘上按一下 q 键,在交互模式当中可以使用方向键向上和向下键导航文档内容,也可以使用空格键和 b 逐页导航。您也可以按 G 跳到文档末尾,然后按 g 跳回到开头。

如果想向后搜索,您可以通过按 / 并键入要搜索的单词来搜索文档内的内容。向前搜索则可以使用 符号并键入一个单词。

注意这些操作都只是可视化操作,如果想要立刻进行编辑,可以直接按一下 v,它会使用默认的编辑器,多数情况下会会是 vim。

笔者这里自己实验下来是 Nano

按 F 键进入跟随模式或观看模式。当文档被其他人更改时,例如从另一个进程更改,可以实时查看更改(个人未进行实验)。

less 也可以打开多个文档,并通过使用 :n(转到下一个文档)和:p(转到上一个文档)浏览。

ubuntu@VM-8-8-ubuntu:~/current$ less merge.txt ../testdata.txt

比如我打开这两个文件,在下面的截图中通过交互模式了解信息。

tail

tail 的最佳使用是在调用-f选项时,在末尾打开文件并观察文件的变化,只要文件中有新的内容,它就会被打印在窗口中。

这对于观察日志文件来说是非常棒的:

ubuntu@VM-8-8-ubuntu:~$ tail -f /var/log/syslog
Mar 27 21:07:01 localhost CRON[2319800]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:08:01 localhost CRON[2320054]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:09:01 localhost CRON[2320309]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:10:01 localhost CRON[2320567]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:10:01 localhost CRON[2320568]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:10:01 localhost CRON[2320570]: (root) CMD (/usr/local/qcloud/YunJing/clearRules.sh > /dev/null 2>&1)
Mar 27 21:11:01 localhost CRON[2320831]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:01 localhost CRON[2321085]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:53 localhost systemd[1]: Started Session 188653 of User ubuntu.
Mar 27 21:13:01 localhost CRON[2321438]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')

注意上面的命令会进入交互模式并且阻塞打印命令,如果要退出可以使用 ctrl + C

我们改变方式可以只打印末尾的10行内容:

ubuntu@VM-8-8-ubuntu:~$ tail -n 10 /var/log/syslog
Mar 27 21:10:01 localhost CRON[2320568]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:10:01 localhost CRON[2320570]: (root) CMD (/usr/local/qcloud/YunJing/clearRules.sh > /dev/null 2>&1)
Mar 27 21:11:01 localhost CRON[2320831]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:01 localhost CRON[2321085]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:53 localhost systemd[1]: Started Session 188653 of User ubuntu.
Mar 27 21:13:01 localhost CRON[2321438]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:14:01 localhost CRON[2321715]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321974]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321975]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321977]: (root) CMD (/usr/local/qcloud/YunJing/clearRules.sh > /dev/null 2>&1)

你可以使用行号前的 "+"来打印整个文件内容,从特定的行开始:

tail -n +10 <filename>

ubuntu@VM-8-8-ubuntu:~$ tail -n 10 /var/log/syslog
Mar 27 21:10:01 localhost CRON[2320568]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:10:01 localhost CRON[2320570]: (root) CMD (/usr/local/qcloud/YunJing/clearRules.sh > /dev/null 2>&1)
Mar 27 21:11:01 localhost CRON[2320831]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:01 localhost CRON[2321085]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:12:53 localhost systemd[1]: Started Session 188653 of User ubuntu.
Mar 27 21:13:01 localhost CRON[2321438]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:14:01 localhost CRON[2321715]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321974]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321975]: (root) CMD (flock -xn /tmp/stargate.lock -c '/usr/local/qcloud/stargate/admin/start.sh > /dev/null 2>&1 &')
Mar 27 21:15:01 localhost CRON[2321977]: (root) CMD (/usr/local/qcloud/YunJing/clearRules.sh > /dev/null 2>&1)

wc

wc 命令为我们提供了关于文件或通过管道接收的输入中的有用信息。

ubuntu@VM-8-8-ubuntu:~$ echo test >> test.txt
ubuntu@VM-8-8-ubuntu:~$ wc test.txt 
1 1 5 test.txt

返回的第一列是行数,第二列是字数,第三列是字节数。

ubuntu@VM-8-8-ubuntu:~$ ls -al | wc
     34     301    1935

如果想要只返回行数、字数、字节数,可以用选项-l-w-c执行:

ubuntu@VM-8-8-ubuntu:~$ wc -l test.txt 
1 test.txt
ubuntu@VM-8-8-ubuntu:~$ wc -w test.txt 
1 test.txt
ubuntu@VM-8-8-ubuntu:~$ wc -c test.txt 
5 test.txt

注意上面这些例子的结果和书中不太一样,因为不同的字符集算字节数是不一样的,在ASCII字符集中,字节相当于字符,但在非ASCII字符集中,字符的数量可能不同,因为有些字符可能需要多个字节,再比如Unicode中就会出现这种情况。

在这种情况下,-m标志将有助于获得更为准确的值:

ubuntu@VM-8-8-ubuntu:~$ wc -m test.txt
5 test.txt

pwd

pwd:print name of current/working directory。并不是 password 的缩写,他的作用就是打印当前所在的目录。

ubuntu@VM-8-8-ubuntu:/$ pwd
/
ubuntu@VM-8-8-ubuntu:/$ cd ~
ubuntu@VM-8-8-ubuntu:~$ pwd
/home/ubuntu

env

env命令可以通过设置环境变量,但是需要注意env设置的自定义环境变量默认在shell范围(也就是一次会话)。案例如下:

env USER=flavio node app.js

可以通过这个命令了解那些环境变量被设置,案例如下:

env -i node app.js

注意上面的命令会报错,此时node没有设置在全局的path环境变量。如果需要解决此问题,可以使用完整路径进行执行。

通过i参数可以特定命令的参数:

env i NAME=favio node app.js

如果去掉i参数可以展示原始环境变量的全貌,env 命令不带任何参数可以打印当前shell的所有环境变量设置。

LESSCLOSE=/usr/bin/lesspipe %s %s
XDG_SESSION_CLASS=user
TERM=xterm
LESSOPEN=| /usr/bin/lesspipe %s
USER=ubuntu
DISPLAY=localhost:10.0
SHLVL=1
XDG_SESSION_ID=211095
XDG_RUNTIME_DIR=/run/user/1000
SSH_CLIENT=120.231.210.178 1960 22
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
SSH_TTY=/dev/pts/0
_=/usr/bin/env
.....

使用-u选项使你运行的程序内部无法访问一个变量,例如下面这段代码将HOME变量从命令环境中删除:

ubuntu@VM-8-8-ubuntu:~$ env -u HOME node app.js
node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module '/home/ubuntu/app.js'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

uname

此命令返回当前操作系统的代号,比如作者机器返回的代号是 darwin(也就是Mac系统)。

-m参数可以打印出当前的系统硬件名称,比如Intel是x86 64。

ubuntu@VM-8-8-ubuntu:~$ uname -m
x86_64

-p参数可以打印处理器型号。

ubuntu@VM-8-8-ubuntu:~$ uname -p
x86_64

-s参数可以打印操作系统名称,注意和系统代号不同打印更为详细。

ubuntu@VM-8-8-ubuntu:~$ uname -s
Linux

-r参数打印发行版本。

ubuntu@VM-8-8-ubuntu:~$ uname -r
5.15.0-48-generic

-v参数打印版本。

ubuntu@VM-8-8-ubuntu:~$ uname -v
#54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022

-n参数打印当前网络节点名称。

ubuntu@VM-8-8-ubuntu:~$ uname -n
VM-8-8-ubuntu

-a参数打印所有的可见信息。

ubuntu@VM-8-8-ubuntu:~$ uname -a
Linux VM-8-8-ubuntu 5.15.0-48-generic #54-Ubuntu SMP Fri Aug 26 13:26:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

-o 代表参数处理。

ubuntu@VM-8-8-ubuntu:~$ uname -o
GNU/Linux

MAC操作系统支持命令sw_vers命令打印有关MACOS的信息。

image.png

crontab

定时任务可以让 Linux 设置每个小时,每天,或者其他间隔时间运行脚本。

查看Linux定时任务使用crontab -l参数。

ubuntu@VM-8-8-ubuntu:~$ crontab -l
no crontab for ubuntu

可以使用命令crontab -e参数修改当前的定时任务。

ubuntu@VM-8-8-ubuntu:~$ crontab -e
no crontab for ubuntu - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

注意-e的修改命令有可能使用默认的 Linux 编辑器,大部分人的机器默认可能是vim,个人使用之后发现是nanao。当然可以使用一些办法修改为nano。

EDITOR=nano crontab -e

输入crontab -e之后,现在你可以添加一行命令在每一个cron job任务。

cronjob 命令内部的语法对于初学者比较"抽象"。可以用网址:https://crontab-generator.org。 定制定时设置。当然可以国内搜索 cron,同样有很多好用的网站。

如果我们想要每分钟的第五秒打印一下当前时间,我们可以像下面的操作:

  1. 进入到作者介绍的网页,指定每分钟第五秒执行,然后输入指令。

image.png

image.png

image.png

  1. 我们在vim当中添加5 * * * * echo $(date +%F) >/dev/null 2>&1,然后是用-xq保存并且退出。
  2. 可以继续执行crontab -l可以看到刚刚新增的定时任务:
ubuntu@VM-8-8-ubuntu:~$ crontab -l
# Edit this file to introduce tasks to be run by cron.
# Print hello at 5 second intervals
5 * * * * echo $(date +%F) >/dev/null 2>&1
  1. 如果要删除,继续执行crontab -e,在编辑器删除对应的文本即可。

export

export 命令常用于导出变量到当前的 Shell,注意在不同的场景export作用范围不一样。

ubuntu@VM-8-8-ubuntu:~$ TEST=“TEST”
ubuntu@VM-8-8-ubuntu:~$ echo $TEST
“TEST”

默认情况下,如果在local shell当中设置了test变量,可以看到值为 TEST,在读取的时候script.sh脚本添加echo test。实际运行echo打印结果可能是nothing

nothing是因为涉及到 Linux 运行shell脚本机制,此时会新建子shell程序,这个子shell是无法读取到当前shell的变量。

有时你需要在变量上附加一些东西,这通常是通过PATH变量完成的,你可以使用这种语法:

export PATH=$PATH:/new/path

如果想要当前用户的shell永久生效,可以修改.bash profile.bashrc 设置文件中添加变量。删除一个环境变量可以使用export -n参数。

export -n

当然如果export命令不加任何参数,可以查看所有的环境变量:

ubuntu@VM-8-8-ubuntu:~$ export
declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
declare -x DISPLAY="localhost:10.0"
declare -x HISTSIZE="1000"
declare -x HISTTIMEFORMAT="%F %T "
declare -x HOME="/home/ubuntu"
declare -x LANG="en_US.UTF-8"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LOGNAME="ubuntu"
....

history

默认情况下使用 history 可以查看最近的所有命令。

ubuntu@VM-8-8-ubuntu:~$ history
    1  2023-03-28 21:46:09  
    2  2022-12-27 15:37:46 useradd zxd
    3  2022-12-27 15:37:52 su
    4  2022-12-29 10:37:05 ls
    5  2022-12-29 10:37:06 clear
    6  2022-12-29 10:37:08 su root
    7  2023-01-24 13:29:10 tracepath www.baidu.com
    8  2023-01-24 22:53:26 sudo apt-get install npm
  406  2023-03-28 21:56:32 du ah |sort nr | head
  407  2023-03-28 21:56:41 du -ah | sort -nr | head
  408  2023-03-28 22:01:57 TEST=“TEST”
  409  2023-03-28 22:02:05 echo $TEST
  410  2023-03-28 22:04:26 history
ubuntu@VM-8-8-ubuntu:~$ 

使用感叹符号!,可以重新执行对应序号的命令。

  408  2023-03-28 22:01:57 TEST=“TEST”
  409  2023-03-28 22:02:05 echo $TEST
  410  2023-03-28 22:04:26 history
ubuntu@VM-8-8-ubuntu:~$ !echo
echo $TEST
“TEST”

上面的字符会过的一大串从后往前的历史命令顺序进行模糊匹配命令,比如敲入ps会找到最近执行过的ps命令,!ps就可以替代上一次执行命令。

如果想要执行指定的某一条历史命令,则查看历史命令列表记住序号,然后是用下面的方式执行:

ubuntu@VM-8-8-ubuntu:~$ !409
echo $TEST
“TEST”

我们可以使用感叹号序号的组合重新执行,特别强调history命令默认存储近500个命令,按照LRU最少使用的队列原则,或者执行行时间的顺序淘汰。

使用-c参数我们可以清空所有的历史记录。

ubuntu@VM-8-8-ubuntu:~$ history -c
ubuntu@VM-8-8-ubuntu:~$ 
ubuntu@VM-8-8-ubuntu:~$ history 
    1  2023-03-29 07:46:49 history 

如果想要模糊查找历史命令的部分关键词检索,可以使用管道符grep搜索。

traceroute

了解这个命令需要对于网络模型有一定认识,根据IP协议可以得知网络传输最少一跳才能到达目标主机的局域网段。

尝试访问Internet上的主机时,您会通过家庭路由器,然后到达ISP网络,ISP网络又通过其自己的上游网络路由器,依此类推,直到最终到达主机。

这个命令作用简单来说就是收集到达目标主机中间经过的路由信息。在CenterOs系统中这个命令默认是不存在,需要手动安装:

[zxd@localhost ~]$ sudo yum install -y traceroute

traceroute的语法如下:

traceroute <host>

具体的使用案例如下:

[zxd@localhost ~]$ traceroute flaviocopes.com
traceroute to flaviocopes.com (172.66.47.151), 30 hops max, 60 byte packets
 1  gateway (192.168.58.2)  0.208 ms  0.148 ms  0.112 ms
 2  * * *
 3  * * *

下面是再Ubuntu系统上的测试:

# 安装traceroute
ubuntu@VM-8-8-ubuntu:~$ sudo apt install traceroute
...
ubuntu@VM-8-8-ubuntu:~$ traceroute www.baidu.com
traceroute to www.baidu.com (14.215.177.39), 30 hops max, 60 byte packets
 1  * 11.71.74.193 (11.71.74.193)  0.985 ms *
 2  * * *
 3  * * *
 4  10.162.32.233 (10.162.32.233)  1.184 ms  1.172 ms 10.196.92.129 (10.196.92.129)  6.547 ms
 5  10.162.32.145 (10.162.32.145)  1.444 ms 10.196.2.101 (10.196.2.101)  2.608 ms 10.162.32.149 (10.162.32.149)  0.967 ms
 6  * * *
 7  * * 113.96.5.13 (113.96.5.13)  2.452 ms
 8  90.96.135.219.broad.fs.gd.dynamic.163data.com.cn (219.135.96.90)  4.194 ms 121.14.14.162 (121.14.14.162)  4.007 ms 90.96.135.219.broad.fs.gd.dynamic.163data.com.cn (219.135.96.90)  4.602 ms
 9  14.215.32.102 (14.215.32.102)  6.397 ms 14.29.121.182 (14.29.121.182)  6.673 ms 14.215.32.90 (14.215.32.90)  5.802 ms

并非每个traceroute的路由器都会返回我们信息(各种中间代理)。在这种情况下路由跟踪打印 * * *。否则,我们可以看到主机名、IP 地址和一些性能指标。

对于每个路由器,我们都可以看到 3 个样本,这意味着 traceroute 默认尝试 3 次,它很好地指示到达它所需的时间。

与简单地对该主机执行 ping 执行时间,就可以跟踪路由为什么需要长时间才能到对方主机。

为了让网络达到预期效果,可以通过-q的参数指定尝试的次数:

traceroute to flaviocopes.com (172.66.47.151), 30 hops max, 60 byte packets
 1  gateway (192.168.58.2)  0.083 ms
 2  *
 3  *

最后是个人的腾讯云服务器实验结果:

ubuntu@VM-8-8-ubuntu:~$ traceroute google.com
traceroute to google.com (142.251.42.238), 30 hops max, 60 byte packets
 1  11.71.74.225 (11.71.74.225)  1.145 ms  1.115 ms  1.296 ms
 2  11.71.120.104 (11.71.120.104)  1.107 ms * *
 3  * * *
 4  10.162.32.233 (10.162.32.233)  0.986 ms 10.162.32.241 (10.162.32.241)  1.002 ms 10.162.32.233 (10.162.32.233)  0.938 ms
 5  10.196.93.230 (10.196.93.230)  1.489 ms 10.162.32.149 (10.162.32.149)  1.462 ms 10.196.93.230 (10.196.93.230)  1.934 ms
 6  * * *
 7  113.96.8.193 (113.96.8.193)  4.770 ms * *
 8  113.96.4.165 (113.96.4.165)  2.943 ms 113.96.4.77 (113.96.4.77)  1.973 ms 113.96.4.185 (113.96.4.185)  4.139 ms


 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

clear

clear 清除在当前终端中运行的所有先前命令。

image.png

注意:此命令有一个方便的快捷方式:ctrl-L

完成清理操作后,将无法访问滚动以查看先前输入的命令的输出。因此如果想要查看之前的命令,可以改用 clear -x,它仍然可以清除屏幕,但允许使用向上滚动来返回查看上一个工作。

如果是SSH配合工具的连接clear非常有用。哪怕clear也不需要过分担心。

passwd

Linux 使用 passwd 命令来修改用户的密码。

passwd

敲入命令之后,Linux首先会要求输入旧密码,然后输入新密码和确认密码。

需要注意普通用户修改自己的密码会被Linux密码强度校验规则拦截,不符合规则的密码是无法被设置的,root用户例外。
ubuntu@VM-8-8-ubuntu:~$ passwd
Changing password for ubuntu.
Current password: 

如果密码和之前一样,则是类似下面的提示:

ubuntu@VM-8-8-ubuntu:~$ passwd
Changing password for ubuntu.
Current password: 
New password: 
Retype new password: 
The password has not been changed.
New password: 
Retype new password: 
The password has not been changed.

如果是root用户可以使用下面的方法修改其他用户的密码:

passwd <username> <new password>

注意root提示中没有出现要求输入旧密码的操作,root用户可以无视当前用户的旧密码,任意修改任何用户的密码。

ping

ping命令相信不用过多介绍,这里直接给一个例子:

xander@xander:~$ ping www.baidu.com
PING www.baidu.com (120.232.145.185) 56(84) bytes of data.

默认情况下ping在每秒进行尝试一次,它会一直运行,除非用户手动停止 (ctrl+c)

ping -c 2 google.com

个人的实验结果如下:

xander@xander:~$ ping -c 2 google.com
PING google.com (142.251.42.238) 56(84) bytes of data.


--- google.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1024ms

一旦停止它将打印一些关于结果的统计数据,丢失包裹的百分比,以及关于网络性能的统计数据。

通过上面的打印信息和相关统计,可以看到获取响应的时间以及丢包率。

ping主机的host是很有用的,可以知道该主机是否可以到达(假设它实现了ping),以及它花多长时间回到你身边的距离。通常情况下,服务器在地理上越近,返回给你的时间就越短,因为简单的物理规律导致较长的距离在电缆中引入更多的延迟。

现代的很多服务器为了减少负荷或者为了网络安全通常会禁ping。ping数据包也可以被防火墙过滤掉。

协议

注意ping使用ICMP协议(互联网控制信息协议)工作,这是一个与TCP或UDP一样的网络层协议。可以理解为请求带有一个特殊的数据包,而服务端收到数据包之后解析包给出回应。

作用

  • 检查服务器是否可达
  • 检查域名或者IP的正确性
  • 检测网络通信状况和质量

sudo

sudo 通常用于以 root 身份运行命令。sudo命令可以让一个非root身份的角色执行和root身份等同的大部分操作(注意不是全部),但是注意这需要通过特殊配置允许。

权限是高度可配置的,这在多用户服务器环境中尤其出色,并且可以通过 sudo 授予某些用户运行特定命令的访问权限。

ubuntu@VM-8-8-ubuntu:~$ sudo nano /etc/hosts

image.png

如果需要让用户具备执行sudo的能力,可以修改/etc/hosts文件,否则编辑器会修改失败。下面的命令相当于切换到root用户:

sudo -i

只要知道root用户的密码,基本上任何用户都可以使用 sudo 身份运行命令。你可以使用sudo以任何用户身份运行命令,root是缺省默认值,使用-u选项可以指定另一个用户:

sudo -u flavio ls /Users/flavio

su

su 命令用于登录的时候切换到另一个用户,对于此命令的使用常常出现在一些需要其他用户权限的场景。

su <username>

如果su命令不带任何其他参数或者用户名称,则默认切换到root并且此时Linux会直接提示输入密码:

[zxd@localhost ~]$ su
Password: 
su will start a new shell as another user.
su 将以另一个用户的身份启动一个新的shell。

这句话比较关键,根据之前学习的env命令,切换到一个新的shell意味着有可能出现环境变量失效的情况。使用exit命令,可以回退到切换之前的角色。

[zxd@localhost ~]$ su
Password: 
hello boy
[root@localhost zxd]# exit
exit
[zxd@localhost ~]$ 

who

who 可以查看当前的Linux中有谁在登陆。

除非你使用的是一个多人都能访问的服务器,否则你有可能是唯一一个登录的用户,但是需要注意同一个用户多次登录会有下面的效果。

xander@xander:~$ who
xander   pts/0        2023-03-11 00:31 (192.168.110.1)
xander   pts/1        2023-03-11 02:42 (192.168.110.1)

比较有意思的是,同一个用户会有多个登陆登录事件是因为每个Shell 都会算入有效访问。可以通过who命令查看当前系统谁最后登陆过以及登陆时间。

-aH 标志将展示显示更多信息,包括空闲时间和终端的进程 ID:

ubuntu@VM-8-8-ubuntu:~$ who -aH
NAME       LINE         TIME             IDLE          PID COMMENT  EXIT
           system boot  2022-12-27 15:39
LOGIN      tty1         2022-12-27 15:39              1100 id=tty1
LOGIN      ttyS0        2022-12-27 15:39              1098 id=tyS0
           run-level 5  2022-12-27 15:39
ubuntu   + pts/0        2023-04-02 12:09   .        161627 (120.229.67.2)
           pts/1        2023-03-16 13:21           2430467 id=ts/1  term=0 exit=0
           pts/2        2023-03-16 13:19           2430547 id=ts/2  term=0 exit=0
           pts/3        2023-03-29 08:10           2712328 id=ts/3  term=0 exit=0

命令who am i可以查看自己:

ubuntu@VM-8-8-ubuntu:~$ who am i
ubuntu   pts/0        2023-04-02 12:09 (120.229.67.2)

配合参数-aH可以展示更多的信息:

ubuntu@VM-8-8-ubuntu:~$ who -aH am i
NAME       LINE         TIME             IDLE          PID COMMENT  EXIT
ubuntu   + pts/3        2023-04-02 13:16   .        178153 (120.229.67.2)

Xander
198 声望51 粉丝