【Linux】《The Command Line Handbook》 讀書筆記(上半部分)

Xander發表於2023-04-06

【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)

相關文章