阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈

2019 年 9 月 25 日更新:感謝ラナ・kuaru的辛勤工作,本文現已提供日文版。請點擊下面的連結查看他們的工作。如果您知道本文被翻譯成其他語言,請告訴我,我會將其發佈在這裡。

🇯🇵 閱讀日語

2019 年 7 月 8 日更新:我最近發現大約兩年前發佈在法語留言板上的這篇非常相似的文章。如果您有興趣學習一些 shell 命令——並且您會說 français ,那麼它是對我下面的文章的一個很好的補充。

直到大約一年前,我幾乎只在 macOS 和 Ubuntu 作業系統中工作。在這兩個作業系統上, bash是我的預設 shell。在過去的六、七年裡,我對bash工作原理有了大致的了解,並想為那些剛入門的人概述一些更常見/有用的命令。如果您認為您了解有關bash所有訊息,請無論如何看看下面的內容 - 我已經提供了一些提示和您可能忘記的標誌的提醒,這可以讓您的工作更輕鬆一些。

下面的命令或多或少以敘述風格排列,因此如果您剛開始使用bash ,您可以從頭到尾完成操作。事情到最後通常會變得不那麼常見並且變得更加困難。

<a name="toc"></a>

目錄

- [First Commands, Navigating the Filesystem](#first-commands)
    - [`pwd / ls / cd`](#pwd-ls-cd)
    - [`; / && / &`](#semicolon-andand-and)
- [Getting Help](#getting-help)
    - [`-h`](#minus-h)
    - [`man`](#man)
- [Viewing and Editing Files](#viewing-and-editing-files)
    - [`head / tail / cat / less`](#head-tail-cat-less)
    - [`nano / nedit`](#nano-nedit)
- [Creating and Deleting Files and Directories](#creating-and-deleting-files)
    - [`touch`](#touch)
    - [`mkdir / rm / rmdir`](#mkdir-rm-rmdir)
- [Moving and Copying Files, Making Links, Command History](#moving-and-copying-files)
    - [`mv / cp / ln`](#mv-cp-ln)
    - [Command History](#command-history)
- [Directory Trees, Disk Usage, and Processes](#directory-trees-disk-usage-processes)
    - [`mkdir –p / tree`](#mkdir--p-tree)
    - [`df / du / ps`](#df-du-ps)
- [Miscellaneous](#basic-misc)
    - [`passwd / logout / exit`](#passwd-logout-exit)
    - [`clear / *`](#clear-glob)
- [Disk, Memory, and Processor Usage](#disk-memory-processor)
    - [`ncdu`](#ncdu)
    - [`top / htop`](#top-htop)
- [REPLs and Software Versions](#REPLs-software-versions)
    - [REPLs](#REPLs)
    - [`-version / --version / -v`](#version)
- [Environment Variables and Aliases](#env-vars-aliases)
    - [Environment Variables](#env-vars)
    - [Aliases](#aliases)
- [Basic `bash` Scripting](#basic-bash-scripting)
    - [`bash` Scripts](#bash-scripts)
    - [Custom Prompt and `ls`](#custom-prompt-ls)
- [Config Files](#config-files)
    - [Config Files / `.bashrc`](#config-bashrc)
    - [Types of Shells](#types-of-shells)
- [Finding Things](#finding-things)
    - [`whereis / which / whatis`](#whereis-which-whatis)
    - [`locate / find`](#locate-find)
- [Downloading Things](#downloading-things)
    - [`ping / wget / curl`](#ping-wget-curl)
    - [`apt / gunzip / tar / gzip`](#apt-gunzip-tar-gzip)
- [Redirecting Input and Output](#redirecting-io)
    - [`| / > / < / echo / printf`](#pipe-gt-lt-echo-printf)
    - [`0 / 1 / 2 / tee`](#std-tee)
- [Superuser](#superuser)
    - [`sudo / su`](#sudo-su)
    - [`!!`](#click-click)
- [File Permissions](#file-permissions)
    - [File Permissions](#file-permissions-sub)
    - [`chmod / chown`](#chmod-chown)
- [User and Group Management](#users-groups)
    - [Users](#users)
    - [Groups](#groups)
- [Text Processing](#text-processing)
    - [`uniq / sort / diff / cmp`](#uniq-sort-diff-cmp)
    - [`cut / sed`](#cut-sed)
- [Pattern Matching](#pattern-matching)
    - [`grep`](#grep)
    - [`awk`](#awk)
- [Copying Files Over `ssh`](#ssh)
    - [`ssh / scp`](#ssh-scp)
    - [`rsync`](#rsync)
- [Long-Running Processes](#long-running-processes)
    - [`yes / nohup / ps / kill`](#yes-nohup-ps-kill)
    - [`cron / crontab / >>`](#cron)
- [Miscellaneous](#advanced-misc)
    - [`pushd / popd`](#pushd-popd)
    - [`xdg-open`](#xdg-open)
    - [`xargs`](#xargs)
- [`w / write / wall / lynx`](#w-write-wall-lynx)
- [`nautilus / date / cal / bc`](#nautilus-date-cal-bc)

<a name="the-basics"></a>

基礎

<a name="first-commands"></a>

第一個指令,瀏覽檔案系統

現代檔案系統具有目錄(資料夾)樹,其中目錄要么是根目錄(沒有父目錄),要么是子目錄(包含在單一其他目錄中,我們稱之為“父目錄”)。向後遍歷檔案樹(從子目錄到父目錄)將始終到達根目錄。有些檔案系統有多個根目錄(如 Windows 的磁碟機: C:\A:\等),但 Unix 和類別 Unix 系統只有一個名為\的根目錄。

<a name="pwd-ls-cd"></a>

pwd / ls / cd

[ 返回目錄 ]

在檔案系統中工作時,使用者始終某個目錄中工作,我們稱之為當前目錄或工作目錄。使用pwd列印使用者的工作目錄:

[ andrew@pc01 ~ ]$ pwd
/home/andrew

使用ls列出該目錄的內容(檔案和/或子目錄等):

[ andrew@pc01 ~ ]$ ls
Git  TEST  jdoc  test  test.file

獎金:

使用ls -a顯示隱藏(“點”)文件

使用ls -l顯示文件詳細訊息

組合多個標誌,如ls -l -a

有時您可以連結諸如ls -la之類的標誌,而不是ls -l -a

使用cd更改到不同的目錄(更改目錄):

[ andrew@pc01 ~ ]$ cd TEST/

[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST

[ andrew@pc01 TEST ]$ cd A

[ andrew@pc01 A ]$ pwd
/home/andrew/TEST/A

cd ..是「 cd到父目錄」的簡寫:

[ andrew@pc01 A ]$ cd ..

[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST

cd ~或只是cd是「 cd到我的主目錄」的簡寫(通常/home/username或類似的東西):

[ andrew@pc01 TEST ]$ cd

[ andrew@pc01 ~ ]$ pwd
/home/andrew

獎金:

cd ~user表示「 cduser的主目錄

您可以使用cd ../..等跳轉多個目錄等級。

使用cd -返回到最近的目錄

.是「此目錄」的簡寫,因此cd .不會做太多事情

<a name="semicolon-andand-and"></a>

; / && / &

[ 返回目錄 ]

我們在命令列中輸入的內容稱為命令,它們總是執行儲存在電腦上某處的一些機器碼。有時這個機器碼是一個內建的Linux命令,有時它是一個應用程式,有時它是你自己寫的一些程式碼。有時,我們會想依序執行一個指令。為此,我們可以使用; (分號):

[ andrew@pc01 ~ ]$ ls; pwd
Git  TEST  jdoc  test  test.file
/home/andrew

上面的分號表示我首先 ( ls ) 列出工作目錄的內容,然後 ( pwd ) 列印其位置。連結命令的另一個有用工具是&& 。使用&&時,如果左側命令失敗,則右側命令將不會執行。 ;&&都可以在同一行中多次使用:

# whoops! I made a typo here!
[ andrew@pc01 ~ ]$ cd /Giit/Parser && pwd && ls && cd
-bash: cd: /Giit/Parser: No such file or directory

# the first command passes now, so the following commands are run
[ andrew@pc01 ~ ]$ cd Git/Parser/ && pwd && ls && cd
/home/andrew/Git/Parser
README.md  doc.sh  pom.xml  resource  run.sh  shell.sh  source  src  target

....但是與; ,即使第一個命令失敗,第二個命令也會執行:

# pwd and ls still run, even though the cd command failed
[ andrew@pc01 ~ ]$ cd /Giit/Parser ; pwd ; ls
-bash: cd: /Giit/Parser: No such file or directory
/home/andrew
Git  TEST  jdoc  test  test.file

&看起來與&&類似,但實際上實現了完全不同的功能。通常,當您執行長時間執行的命令時,命令列將等待該命令完成,然後才允許您輸入另一個命令。在命令後面加上&可以防止這種情況發生,並允許您在舊命令仍在執行時執行新命令:

[ andrew@pc01 ~ ]$ cd Git/Parser && mvn package & cd
[1] 9263

額外的好處:當我們在命令後使用&來「隱藏」它時,我們說該作業(或「進程」;這些術語或多或少可以互換)是「後台的」。若要查看目前正在執行的背景作業,請使用jobs指令:

[ andrew@pc01 ~ ]$ 職位

[1]+ 執行 cd Git/Parser/ && mvn package &


<a name="getting-help"></a>

## Getting Help

<a name="minus-h"></a>

### `-h`

[[ Back to Table of Contents ]](#toc)

Type `-h` or `--help` after almost any command to bring up a help menu for that command:

[ andrew@pc01 ~ ]$ du --help

用法:你[選項]...[檔案]...

或: du [選項]... --files0-from=F

對目錄遞歸地總結文件集的磁碟使用情況。

長期權的強制性參數對於短期權也是強制性的。

-0, --null 以 NUL 結束每個輸出行,而不是換行符

-a, --all 計算所有檔案的寫入計數,而不僅僅是目錄

  --apparent-size   print apparent sizes, rather than disk usage; although
                      the apparent size is usually smaller, it may be
                      larger due to holes in ('sparse') files, internal
                      fragmentation, indirect blocks, and the like

-B, --block-size=SIZE 在列印前按 SIZE 縮放大小;例如,

                       '-BM' prints sizes in units of 1,048,576 bytes;
                       see SIZE format below


<a name="man"></a>

### `man`

[[ Back to Table of Contents ]](#toc)

Type `man` before almost any command to bring up a manual for that command (quit `man` with `q`):

LS(1) 使用者指令 LS(1)

姓名

   ls - list directory contents

概要

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

描述

   List  information  about  the FILEs (the current directory by default).
   Sort entries alphabetically if none of -cftuvSUX nor --sort  is  speci-
   fied.
   Mandatory  arguments  to  long  options are mandatory for short options
   too.


<a name="viewing-and-editing-files"></a>

## Viewing and Editing Files

<a name="head-tail-cat-less"></a>

### `head / tail / cat / less`

[[ Back to Table of Contents ]](#toc)

`head` outputs the first few lines of a file. The `-n` flag specifies the number of lines to show (the default is 10):

列印前三行

[ andrew@pc01 ~ ]$ 頭 -n 3 c

文件


`tail` outputs the last few lines of a file. You can get the last `n` lines (like above), or you can get the end of the file beginning from the `N`-th line with `tail -n +N`:

從第 4 行開始列印文件末尾

[ andrew@pc01 ~ ]$ tail -n +4 c

確切地


`cat` concatenates a list of files and sends them to the standard output stream (usually the terminal). `cat` can be used with just a single file, or multiple files, and is often used to quickly view them. (**Be warned**: if you use `cat` in this way, you may be accused of a [_Useless Use of Cat_ (UUOC)](http://bit.ly/2SPHE4V), but it's not that big of a deal, so don't worry too much about it.)

[ andrew@pc01 ~ ]$ 貓 a

歸檔一個

[ andrew@pc01 ~ ]$ 貓 ab

歸檔一個

文件b


`less` is another tool for quickly viewing a file -- it opens up a `vim`-like read-only window. (Yes, there is a command called `more`, but `less` -- unintuitively -- offers a superset of the functionality of `more` and is recommended over it.) Learn more (or less?) about [less](http://man7.org/linux/man-pages/man1/less.1.html) and [more](http://man7.org/linux/man-pages/man1/more.1.html) at their `man` pages.

<a name="nano-nedit"></a>

### `nano / nedit`

[[ Back to Table of Contents ]](#toc)

`nano` is a minimalistic command-line text editor. It's a great editor for beginners or people who don't want to learn a million shortcuts. It was more than sufficient for me for the first few years of my coding career (I'm only now starting to look into more powerful editors, mainly because defining your own syntax highlighting in `nano` can be a bit of a pain.)

`nedit` is a small graphical editor, it opens up an X Window and allows point-and-click editing, drag-and-drop, syntax highlighting and more. I use `nedit` sometimes when I want to make small changes to a script and re-run it over and over.

Other common CLI (command-line interface) / GUI (graphical user interface) editors include `emacs`, `vi`, `vim`, `gedit`, Notepad++, Atom, and lots more. Some cool ones that I've played around with (and can endorse) include Micro, Light Table, and VS Code.

All modern editors offer basic conveniences like search and replace, syntax highlighting, and so on. `vi(m)` and `emacs` have more features than `nano` and `nedit`, but they have a much steeper learning curve. Try a few different editors out and find one that works for you!

<a name="creating-and-deleting-files"></a>

## Creating and Deleting Files and Directories

<a name="touch"></a>

### `touch`

[[ Back to Table of Contents ]](#toc)

`touch` was created to modify file timestamps, but it can also be used to quickly create an empty file. You can create a new file by opening it with a text editor, like `nano`:

[ andrew@pc01 前 ]$ ls

[ andrew@pc01 ex ]$ 奈米 a


_...editing file..._

[ andrew@pc01 前 ]$ ls

A


...or by simply using `touch`:

[ andrew@pc01 ex ]$ touch b && ls

ab


> **Bonus**:
> 
> Background a process with \^z (Ctrl+z)
> 
> ```bash
> [ andrew@pc01 ex ]$ nano a
> ```
> 
> _...editing file, then hit \^z..._
> 
> ```bash
> Use fg to return to nano
> 
> [1]+ Stopped nano a
> [ andrew@pc01 ex ]$ fg
> ```
> 
> _...editing file again..._

---

> **Double Bonus:**
> 
> Kill the current (foreground) process by pressing \^c (Ctrl+c) while it’s running
> 
> Kill a background process with `kill %N` where `N` is the job index shown by the `jobs` command

<a name="mkdir-rm-rmdir"></a>

### `mkdir / rm / rmdir`

[[ Back to Table of Contents ]](#toc)

`mkdir` is used to create new, empty directories:

[ andrew@pc01 ex ]$ ls && mkdir c && ls

ab

ABC


You can remove any file with `rm` -- but be careful, this is non-recoverable!

[ andrew@pc01 ex ]$ rm a && ls

西元前


You can add an _"are you sure?"_ prompt with the `-i` flag:

[ andrew@pc01 前 ]$ rm -ib

rm:刪除常規空文件“b”? y


Remove an empty directory with `rmdir`. If you `ls -a` in an empty directory, you should only see a reference to the directory itself (`.`) and a reference to its parent directory (`..`):

[ andrew@pc01 ex ]$ rmdir c && ls -a

。 ..


`rmdir` removes empty directories only: 

[ andrew@pc01 ex ]$ cd .. && ls 測試/

*.txt 0.txt 1.txt a a.txt bc

[ andrew@pc01 ~ ]$ rmdir 測試/

rmdir:無法刪除“test/”:目錄不為空


...but you can remove a directory -- and all of its contents -- with `rm -rf` (`-r` = recursive, `-f` = force):

[ andrew@pc01 ~ ]$ rm –rf 測試


<a name="moving-and-copying-files"></a>

## Moving and Copying Files, Making Links, Command History

<a name="mv-cp-ln"></a>

### `mv / cp / ln`

[[ Back to Table of Contents ]](#toc)

`mv` moves / renames a file. You can `mv` a file to a new directory and keep the same file name or `mv` a file to a "new file" (rename it):

[ andrew@pc01 ex ]$ ls && mv ae && ls

A B C D

BCDE


`cp` copies a file:

[ andrew@pc01 ex ]$ cp e e2 && ls

BCDE E2


`ln` creates a hard link to a file:

ln 的第一個參數是 TARGET,第二個參數是 NEW LINK

[ andrew@pc01 ex ]$ ln bf && ls

bcde e2 f


`ln -s` creates a soft link to a file:

[ andrew@pc01 ex ]$ ln -sbg && ls

BCDE E2 FG


Hard links reference the same actual bytes in memory which contain a file, while soft links refer to the original file name, which itself points to those bytes. [You can read more about soft vs. hard links here.](http://bit.ly/2D0W8cN)

<a name="command-history"></a>

### Command History

[[ Back to Table of Contents ]](#toc)

`bash` has two big features to help you complete and re-run commands, the first is _tab completion_. Simply type the first part of a command, hit the \<tab\> key, and let the terminal guess what you're trying to do:

[ andrew@pc01 目錄 ]$ ls

另一個長檔名 這是一個長檔名 一個新檔名

[ andrew@pc01 目錄 ]$ ls t


_...hit the TAB key after typing `ls t` and the command is completed..._

[ andrew@pc01 dir ]$ ls 這是檔名

這是長檔名


You may have to hit \<TAB\> multiple times if there's an ambiguity:

[ andrew@pc01 目錄 ]$ ls a

[ andrew@pc01 目錄 ]$ ls an

一個新檔名另一個長檔名


`bash` keeps a short history of the commands you've typed previously and lets you search through those commands by typing \^r (Ctrl+r):

[ andrew@pc01 目錄 ]


_...hit \^r (Ctrl+r) to search the command history..._

(反向搜尋)``:


_...type 'anew' and the last command containing this is found..._

(reverse-i-search)`anew': 觸碰新檔名


<a name="directory-trees-disk-usage-processes"></a>

## Directory Trees, Disk Usage, and Processes

<a name="mkdir--p-tree"></a>

### `mkdir –p / tree`

[[ Back to Table of Contents ]](#toc)

`mkdir`, by default, only makes a single directory. This means that if, for instance, directory `d/e` doesn't exist, then `d/e/f` can't be made with `mkdir` by itself:

[ andrew@pc01 ex ]$ ls && mkdir d/e/f

ABC

mkdir:無法建立目錄「d/e/f」:沒有這樣的檔案或目錄


But if we pass the `-p` flag to `mkdir`, it will make all directories in the path if they don't already exist:

[ andrew@pc01 ex ]$ mkdir -pd/e/f && ls

A B C D


`tree` can help you better visualise a directory's structure by printing a nicely-formatted directory tree. By default, it prints the entire tree structure (beginning with the specified directory), but you can restrict it to a certain number of levels with the `-L` flag:

[ andrew@pc01 前 ]$ 樹 -L 2

|-- 一個

|-- b

|-- c

`--d

`--e

3個目錄,2個文件


You can hide empty directories in `tree`'s output with `--prune`. Note that this also removes "recursively empty" directories, or directories which aren't empty _per se_, but which contain only other empty directories, or other recursively empty directories:

[ andrew@pc01 ex ]$ 樹 --prune

|-- 一個

`--b


<a name="df-du-ps"></a>

### `df / du / ps`

[[ Back to Table of Contents ]](#toc)

`df` is used to show how much space is taken up by files for the disks or your system (hard drives, etc.).

[ andrew@pc01 前 ]$ df -h

已使用的檔案系統大小 可用 使用% 安裝於

udev 126G 0 126G 0% /dev

tmpfs 26G 2.0G 24G 8% /執行

/dev/mapper/ubuntu--vg-root 1.6T 1.3T 252G 84% /


In the above command, `-h` doesn't mean "help", but "human-readable". Some commands use this convention to display file / disk sizes with `K` for kilobytes, `G` for gigabytes, and so on, instead of writing out a gigantic integer number of bytes.

`du` shows file space usage for a particular directory and its subdirectories. If you want to know how much space is free on a given hard drive, use `df`; if you want to know how much space a directory is taking up, use `du`:

[ andrew@pc01 ex ]$ 你

4 ./d/e/f

8./d/e

12 ./天

4./c

20 .


`du` takes a `--max-depth=N` flag, which only shows directories `N` levels down (or fewer) from the specified directory:

[ andrew@pc01 ex ]$ du -h --max-深度=1

12K./天

4.0K./c

20K。


`ps` shows all of the user's currently-running processes (aka. jobs):

[ andrew@pc01 前 ]$ ps

PID TTY 時間 CMD

16642 分/15 00:00:00 ps

25409 點/15 00:00:00 重擊


<a name="basic-misc"></a>

## Miscellaneous

<a name="passwd-logout-exit"></a>

### `passwd / logout / exit`

[[ Back to Table of Contents ]](#toc)

Change your account password with `passwd`. It will ask for your current password for verification, then ask you to enter the new password twice, so you don't make any typos:

[ andrew@pc01 目錄 ]$ 密碼

更改安德魯的密碼。

(目前)UNIX 密碼:

輸入新的 UNIX 密碼:

重新輸入新的 UNIX 密碼:

passwd:密碼更新成功


`logout` exits a shell you’ve logged in to (where you have a user account):

[ andrew@pc01 目錄 ]$ 註銷

────────────────────────────────────────────────── ── ──────────────────────────────

會話已停止

- Press <return> to exit tab
- Press R to restart session
- Press S to save terminal output to file

`exit` exits any kind of shell:

[ andrew@pc01 ~ ]$ 退出

登出

────────────────────────────────────────────────── ── ──────────────────────────────

會話已停止

- Press <return> to exit tab
- Press R to restart session
- Press S to save terminal output to file

<a name="clear-glob"></a>

### `clear / *`

[[ Back to Table of Contents ]](#toc)

Run `clear` to move the current terminal line to the top of the screen. This command just adds blank lines below the current prompt line. It's good for clearing your workspace.

Use the glob (`*`, aka. Kleene Star, aka. wildcard) when looking for files. Notice the difference between the following two commands:

[ andrew@pc01 ~ ]$ ls Git/Parser/source/

PArrayUtils.java PFile.java PSQLFile.java PWatchman.java

PDateTimeUtils.java PFixedWidthFile.java PStringUtils.java PXSVFile.java

PDelimitedFile.java PNode.java PTextFile.java Parser.java

[ andrew@pc01 ~ ]$ ls Git/Parser/source/PD*

Git/Parser/source/PDateTimeUtils.java Git/Parser/source/PDelimitedFile.java


The glob can be used multiple times in a command and matches zero or more characers:

[ andrew@pc01 ~ ]$ ls Git/Parser/source/P D m*

Git/Parser/source/PDateTimeUtils.java Git/Parser/source/PDelimitedFile.java


<a name="intermediate"></a>

# Intermediate

<a name="disk-memory-processor"></a>

## Disk, Memory, and Processor Usage

<a name="ncdu"></a>

### `ncdu`

[[ Back to Table of Contents ]](#toc)

`ncdu` (NCurses Disk Usage) provides a navigable overview of file space usage, like an improved `du`. It opens a read-only `vim`-like window (press `q` to quit):

[ andrew@pc01 ~ ]$ ncdu

ncdu 1.11 ~ 使用箭頭鍵導航,按 ?求助

--- /home/安德魯 ------------------------------------------- ------------------

148.2 MiB [##########] /.m2

91.5 MiB [######] /.sbt

79.8 MiB [######] /.cache

64.9 MiB [####] /.ivy2

40.6 MiB [##] /.sdkman

30.2 MiB [##] /.local

27.4 MiB [#] /.mozilla

24.4 MiB [#] /.nanobackups

10.2 MiB [ ] .confout3.txt

8.4 MiB [          ] /.config
5.9 MiB [          ] /.nbi
5.8 MiB [          ] /.oh-my-zsh
4.3 MiB [          ] /Git
3.7 MiB [          ] /.myshell
1.7 MiB [          ] /jdoc
1.5 MiB [          ]  .confout2.txt
1.5 MiB [          ] /.netbeans
1.1 MiB [          ] /.jenv

564.0 KiB [ ] /.rstudio-desktop

磁碟使用總量:552.7 MiB 表觀大小:523.6 MiB 專案:14618


<a name="top-htop"></a>

### `top / htop`

[[ Back to Table of Contents ]](#toc)

`top` displays all currently-running processes and their owners, memory usage, and more. `htop` is an improved, interactive `top`. (Note: you can pass the `-u username` flag to restrict the displayed processes to only those owner by `username`.)

[ andrew@pc01 ~ ]$ htop

1 [ 0.0%] 9 [ 0.0%] 17 [ 0.0%] 25 [ 0.0%]

2 [ 0.0%] 10 [ 0.0%] 18 [ 0.0%] 26 [ 0.0%]

3 [ 0.0%] 11 [ 0.0%] 19 [ 0.0%] 27 [ 0.0%]

4 [ 0.0%] 12 [ 0.0%] 20 [ 0.0%] 28 [ 0.0%]

5 [ 0.0%] 13 [ 0.0%] 21 [| 1.3%] 29 [ 0.0%]

6 [ 0.0%] 14 [ 0.0%] 22 [ 0.0%] 30 [| 0.6%]

7 [ 0.0%] 15 [ 0.0%] 23 [ 0.0%] 31 [ 0.0%]

8 [ 0.0%] 16 [ 0.0%] 24 [ 0.0%] 32 [ 0.0%]

Mem[|||||||||||||||||||1.42G/252G] 任務:188、366 個; 1 執行

交換電壓[| 2.47G/256G]平均負載:0.00 0.00 0.00

                                    Uptime: 432 days(!), 00:03:55

PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ 指令

9389 安德魯 20 0 23344 3848 2848 R 1.3 0.0 0:00.10 htop

10103 根 20 0 3216M 17896 2444 S 0.7 0.0 5h48:56 /usr/bin/dockerd

1 root       20   0  181M  4604  2972 S  0.0  0.0 15:29.66 /lib/systemd/syst

533 根 20 0 44676 6908 6716 S 0.0 0.0 11:19.77 /lib/systemd/syst

546 根 20 0 244M 0 0 S 0.0 0.0 0:01.39 /sbin/lvmetad -f

1526 根 20 0 329M 2252 1916 S 0.0 0.0 0:00.00 /usr/sbin/ModemMa

1544 根 20 0 329M 2252 1916 S 0.0 0.0 0:00.06 /usr/sbin/ModemMa

F1Help F2Setup F3SearchF4FilterF5Tree F6SortByF7Nice -F8Nice +F9Kill F10Quit


<a name="REPLs-software-versions"></a>

## REPLs and Software Versions

<a name="REPLs"></a>

### REPLs

[[ Back to Table of Contents ]](#toc)

A **REPL** is a Read-Evaluate-Print Loop, similar to the command line, but usually used for particular programming languages.

You can open the Python REPL with the `python` command (and quit with the `quit()` function):

[ andrew@pc01 ~ ]$ python

Python 3.5.2(默認,2018 年 11 月 12 日,13:43:14)...

辭職()


Open the R REPL with the `R` command (and quit with the `q()` function):

[ andrew@pc01 ~ ]$ R

R版3.5.2(2018-12-20)--「蛋殼冰屋」...

q()

儲存工作區影像? [是/否/c]: 否


Open the Scala REPL with the `scala` command (and quit with the `:quit` command):

[ andrew@pc01 ~ ]$ scala

歡迎使用 Scala 2.11.12 ...

斯卡拉>:退出


Open the Java REPL with the `jshell` command (and quit with the `/exit` command):

[ andrew@pc01 ~ ]$ jshell

|歡迎使用 JShell——版本 11.0.1 ...

jshell> /退出


Alternatively, you can exit any of these REPLs with \^d (Ctrl+d). \^d is the EOF (end of file) marker on Unix and signifies the end of input.

<a name="version"></a>

### `-version / --version / -v`

[[ Back to Table of Contents ]](#toc)

Most commands and programs have a `-version` or `--version` flag which gives the software version of that command or program. Most applications make this information easily available:

[ andrew@pc01 ~ ]$ ls --version

ls (GNU coreutils) 8.25 ...

[ andrew@pc01 ~ ]$ ncdu -版本

NCDU 1.11

[ andrew@pc01 ~ ]$ python --version

Python 3.5.2


...but some are less intuitive:

[ andrew@pc01 ~ ]$ sbt scalaVersion

[資訊]2.12.4


Note that some programs use `-v` as a version flag, while others use `-v` to mean "verbose", which will run the application while printing lots of diagnostic or debugging information:

SCP(1) BSD 通用指令手冊 SCP(1)

姓名

 scp -- secure copy (remote file copy program)

-v 詳細模式。導致 scp 和 ssh(1) 列印偵錯訊息

         about their progress.  This is helpful in debugging connection,
         authentication, and configuration problems.


<a name="env-vars-aliases"></a>

## Environment Variables and Aliases

<a name="env-vars"></a>

### Environment Variables

[[ Back to Table of Contents ]](#toc)

**Environment variables** (sometimes shortened to "env vars") are persistent variables that can be created and used within your `bash` shell. They are defined with an equals sign (`=`) and used with a dollar sign (`$`). You can see all currently-defined env vars with `printenv`:

[ andrew@pc01 ~ ]$ printenv

SPARK_HOME=/usr/local/spark

術語=xterm


Set a new environment variable with an `=` sign (don't put any spaces before or after the `=`, though!):

[ andrew@pc01 ~ ]$ myvar=你好


Print a specific env var to the terminal with `echo` and a preceding `$` sign:

[ andrew@pc01 ~ ]$ echo $myvar

你好


Environment variables which contain spaces or other whitespace should be surrounded by quotes (`"..."`). Note that reassigning a value to an env var overwrites it without warning:

[ andrew@pc01 ~ ]$ myvar="你好,世界!" && 回顯 $myvar

你好世界!


Env vars can also be defined using the `export` command. When defined this way, they will also be available to sub-processes (commands called from this shell):

[ andrew@pc01 ~ ]$ export myvar="另一" && echo $myvar

另一個


You can unset an environment variable by leaving the right-hand side of the `=` blank or by using the `unset` command:

[ andrew@pc01 ~ ]$ 取消設定 mynewvar

[ andrew@pc01 ~ ]$ echo $mynewvar


<a name="aliases"></a>

### Aliases

[[ Back to Table of Contents ]](#toc)

**Aliases** are similar to environment variables but are usually used in a different way -- to replace long commands with shorter ones:

[ andrew@pc01 apidocs ]$ ls -l -a -h -t

總計 220K

drwxr-xr-x 5 安德魯 安德魯 4.0K 12 月 21 日 12:37 。

-rw-r--r-- 1 安德魯 安德魯 9.9K 十二月 21 12:37 help-doc.html

-rw-r--r-- 1 安德魯 安德魯 4.5K 12 月 21 日 12:37 script.js

[ andrew@pc01 apidocs ]$ 別名 lc="ls -l -a -h -t"

[ andrew@pc01 apidocs ]$ lc

總計 220K

drwxr-xr-x 5 安德魯 安德魯 4.0K 12 月 21 日 12:37 。

-rw-r--r-- 1 安德魯 安德魯 9.9K 十二月 21 12:37 help-doc.html

-rw-r--r-- 1 安德魯 安德魯 4.5K 12 月 21 日 12:37 script.js


You can remove an alias with `unalias`:

[ andrew@pc01 apidocs ]$ unalias lc

[ andrew@pc01 apidocs ]$ lc

目前未安裝程式“lc”。 …


> **Bonus:**
> 
> [Read about the subtle differences between environment variables and aliases here.](http://bit.ly/2TDG8Tx)
> 
> [Some programs, like **git**, allow you to define aliases specifically for that software.](http://bit.ly/2TG8X1A)

<a name="basic-bash-scripting"></a>

## Basic `bash` Scripting

<a name="bash-scripts"></a>

### `bash` Scripts

[[ Back to Table of Contents ]](#toc)

`bash` scripts (usually ending in `.sh`) allow you to automate complicated processes, packaging them into reusable functions. A `bash` script can contain any number of normal shell commands:

[ andrew@pc01 ~ ]$ echo "ls && touch file && ls" > ex.sh


A shell script can be executed with the `source` command or the `sh` command:

[ andrew@pc01 ~ ]$ 源 ex.sh

桌面 Git TEST c ex.sh 專案測試

桌面 Git TEST c ex.sh 檔案專案測試


Shell scripts can be made executable with the `chmod` command (more on this later):

[ andrew@pc01 ~ ]$ echo "ls && touch file2 && ls" > ex2.sh

[ andrew@pc01 ~ ]$ chmod +x ex2.sh


An executable shell script can be run by preceding it with `./`:

[ andrew@pc01 ~ ]$ ./ex2.sh

桌面 Git TEST c ex.sh ex2.sh 檔案專案測試

桌面 Git TEST c ex.sh ex2.sh 檔案 file2 專案測試


Long lines of code can be split by ending a command with `\`:

[ andrew@pc01 ~ ]$ echo "for i in {1..3}; do echo \

\"歡迎\$i次\";完成” > ex3.sh


Bash scripts can contain loops, functions, and more!

[ andrew@pc01 ~ ]$ 源 ex3.sh

歡迎1次

歡迎2次

歡迎3次


<a name="custom-prompt-ls"></a>

### Custom Prompt and `ls`

[[ Back to Table of Contents ]](#toc)

Bash scripting can make your life a whole lot easier and more colourful. [Check out this great bash scripting cheat sheet.](https://devhints.io/bash)

`$PS1` (Prompt String 1) is the environment variable that defines your main shell prompt ([learn about the other prompts here](http://bit.ly/2SPgsmT)):

[ andrew@pc01 ~ ]$ printf "%q" $PS1

$'\n\[\E[1m\]\[\E[30m\]\A'$'\[\E[37m\]|\[\E[36m\]\u\[\E[37m \]@\[\E[34m\]\h'$'\[\E[32m\]\W\[\E[37m\]|'$'\[\E(B\E[m\] '


You can change your default prompt with the `export` command:

[ andrew@pc01 ~ ]$ export PS1="\n此處指令> "

此處指令> echo $PS1

\n此處指令>


...[you can add colours, too!](http://bit.ly/2TMbEit):

此處指令> export PS1="\e[1;31m\n程式碼: \e[39m"

(這應該是紅色的,但在 Markdown 中可能不會這樣顯示)

程式碼:回顯$PS1

\e[1;31m\n程式碼: \e[39m


You can also change the colours shown by `ls` by editing the `$LS_COLORS` environment variable:

(同樣,這些顏色可能不會出現在 Markdown 中)

程式碼:ls

桌面 Git TEST c ex.sh ex2.sh ex3.sh 檔案 file2 專案測試

程式碼:匯出 LS_COLORS='di=31:fi=0:ln=96:or=31:mi=31:ex=92'

程式碼:ls

桌面 Git TEST c ex.sh ex2.sh ex3.sh 檔案 file2 專案測試


<a name="config-files"></a>

## Config Files

<a name="config-bashrc"></a>

### Config Files / `.bashrc`

[[ Back to Table of Contents ]](#toc)

If you tried the commands in the last section and logged out and back in, you may have noticed that your changes disappeared. _config_ (configuration) files let you maintain settings for your shell or for a particular program every time you log in (or run that program). The main configuration file for a `bash` shell is the `~/.bashrc` file. Aliases, environment variables, and functions added to `~/.bashrc` will be available every time you log in. Commands in `~/.bashrc` will be run every time you log in.

If you edit your `~/.bashrc` file, you can reload it without logging out by using the `source` command:

[ andrew@pc01 ~ ]$ nano ~/.bashrc


_...add the line `echo “~/.bashrc loaded!”` to the top of the file_...

[ andrew@pc01 ~ ]$ 源 ~/.bashrc

~/.bashrc 已載入!


_...log out and log back in..._

最後登入:2019 年 1 月 11 日星期五 10:29:07 從 111.11.11.111

~/.bashrc 已加載!

[ 安德魯@pc01 ~ ]


<a name="types-of-shells"></a>

### Types of Shells

[[ Back to Table of Contents ]](#toc)

_Login_ shells are shells you log in to (where you have a username). _Interactive_ shells are shells which accept commands. Shells can be login and interactive, non-login and non-interactive, or any other combination.

In addition to `~/.bashrc`, there are a few other scripts which are `sourced` by the shell automatically when you log in or log out. These are:

- `/etc/profile`
- `~/.bash_profile`
- `~/.bash_login`
- `~/.profile`
- `~/.bash_logout`
- `/etc/bash.bash_logout`

Which of these scripts are sourced, and the order in which they're sourced, depend on the type of shell opened. See [the bash man page](https://linux.die.net/man/1/bash) and [these](http://bit.ly/2TGCwA8) Stack Overflow [posts](http://bit.ly/2TFHFsf) for more information.

Note that `bash` scripts can `source` other scripts. For instance, in your `~/.bashrc`, you could include the line:

來源~/.bashrc_addl


...which would also `source` that `.bashrc_addl` script. This file can contain its own aliases, functions, environment variables, and so on. It could, in turn, `source` other scripts, as well. (Be careful to avoid infinite loops of script-sourcing!)

It may be helpful to split commands into different shell scripts based on functionality or machine type (Ubuntu vs. Red Hat vs. macOS), for example:

- `~/.bash_ubuntu` -- configuration specific to Ubuntu-based machines
- `~/.bashrc_styles` -- aesthetic settings, like `PS1` and `LS_COLORS`
- `~/.bash_java` -- configuration specific to the Java language

I try to keep separate `bash` files for aesthetic configurations and OS- or machine-specific code, and then I have one big `bash` file containing shortcuts, etc. that I use on every machine and every OS.

Note that there are also _different shells_. `bash` is just one kind of shell (the "Bourne Again Shell"). Other common ones include `zsh`, `csh`, `fish`, and more. Play around with different shells and find one that's right for you, but be aware that this tutorial contains `bash` shell commands only and not everything listed here (maybe none of it) will be applicable to shells other than `bash`.

<a name="finding-things"></a>

## Finding Things

<a name="whereis-which-whatis"></a>

### `whereis / which / whatis`

[[ Back to Table of Contents ]](#toc)

`whereis` searches for "possibly useful" files related to a particular command. It will attempt to return the location of the binary (executable machine code), source (code source files), and `man` page for that command:

[ andrew@pc01 ~ ]$ whereis ls

ls: /bin/ls /usr/share/man/man1/ls.1.gz


`which` will only return the location of the binary (the command itself):

[ andrew@pc01 ~ ]$ 其中 ls

/bin/ls


`whatis` prints out the one-line description of a command from its `man` page:

[ andrew@pc01 ~ ]$ 什麼是哪裡是哪個什麼是

whereis (1) - 尋找指令的二進位、原始檔和手冊頁文件

which (1) - 定位指令

Whatis (1) - 顯示一行手冊頁描述


`which` is useful for finding the "original version" of a command which may be hidden by an alias:

[ andrew@pc01 ~ ]$ 別名 ls="ls -l"

“original” ls 已被上面定義的別名“隱藏”

[ andrew@pc01 ~ ]$ ls

總計 36

drwxr-xr-x 2 安德魯 andrew 4096 Jan 9 14:47 桌面

drwxr-xr-x 4 安德魯 安德魯 4096 十二月 6 10:43 Git

但我們仍然可以使用返回的位置來呼叫「原始」ls

[ andrew@pc01 ~ ]$ /bin/ls

桌面 Git TEST c ex.sh ex2.sh ex3.sh 檔案 file2 專案測試


<a name="locate-find"></a>

### `locate / find`

[[ Back to Table of Contents ]](#toc)

`locate` finds a file anywhere on the system by referring to a semi-regularly-updated cached list of files:

[ andrew@pc01 ~ ]$ 找到 README.md

/home/andrew/.config/micro/plugins/gotham-colors/README.md

/home/andrew/.jenv/README.md

/home/andrew/.myshell/README.md


Because it's just searching a list, `locate` is usually faster than the alternative, `find`. `find` iterates through the file system to find the file you're looking for. Because it's actually looking at the files which _currently_ exist on the system, though, it will always return an up-to-date list of files, which is not necessarily true with `locate`.

[ andrew@pc01 ~ ]$ find ~/ -iname "README.md"

/home/andrew/.jenv/README.md

/home/andrew/.config/micro/plugins/gotham-colors/README.md

/home/andrew/.oh-my-zsh/plugins/ant/README.md


`find` was written for the very first version of Unix in 1971, and is therefore much more widely available than `locate`, which was added to GNU in 1994.

`find` has many more features than `locate`, and can search by file age, size, ownership, type, timestamp, permissions, depth within the file system; `find` can search using regular expressions, execute commands on files it finds, and more.

When you need a fast (but possibly outdated) list of files, or you’re not sure what directory a particular file is in, use `locate`. When you need an accurate file list, maybe based on something other than the files’ names, and you need to do something with those files, use `find`.

<a name="downloading-things"></a>

## Downloading Things

<a name="ping-wget-curl"></a>

### `ping / wget / curl`

[[ Back to Table of Contents ]](#toc)

`ping` attempts to open a line of communication with a network host. Mainly, it's used to check whether or not your Internet connection is down:

[ andrew@pc01 ~ ]$ ping google.com

PING google.com (74.125.193.100) 56(84) 位元組資料。

使用 32 位元組資料 Ping 74.125.193.100:

來自 74.125.193.100 的回覆:位元組=32 時間<1ms TTL=64


`wget` is used to easily download a file from the Internet:

[ andrew@pc01 ~ ]$ wget \

http://releases.ubuntu.com/18.10/ubuntu-18.10-desktop-amd64.iso


`curl` can be used just like `wget` (don’t forget the `--output` flag):

[ andrew@pc01 ~ ]$ 捲曲 \

http://releases.ubuntu.com/18.10/ubuntu-18.10-desktop-amd64.iso \

--輸出ubuntu.iso


`curl` and `wget` have their own strengths and weaknesses. `curl` supports many more protocols and is more widely available than `wget`; `curl` can also send data, while `wget` can only receive data. `wget` can download files recursively, while `curl` cannot.

In general, I use `wget` when I need to download things from the Internet. I don’t often need to send data using `curl`, but it’s good to be aware of it for the rare occasion that you do.

<a name="apt-gunzip-tar-gzip"></a>

### `apt / gunzip / tar / gzip`

[[ Back to Table of Contents ]](#toc)

Debian-descended Linux distributions have a fantastic package management tool called `apt`. It can be used to install, upgrade, or delete software on your machine. To search `apt` for a particular piece of software, use `apt search`, and install it with `apt install`:

[ andrew@pc01 ~ ]$ apt 搜尋漂白位

...bleachbit/bionic、bionic 2.0-2 全部

從系統中刪除不需要的文件

您需要“sudo”來安裝軟體

[ andrew@pc01 ~ ]$ sudo apt installbleachbit


Linux software often comes packaged in `.tar.gz` ("tarball") files:

[ andrew@pc01 ~ ]$ wget \

https://github.com/atom/atom/releases/download/v1.35.0-beta0/atom-amd64.tar.gz


...these types of files can be unzipped with `gunzip`:

[ andrew@pc01 ~ ]$gunzipatom-amd64.tar.gz && ls

原子 amd64.tar


A `.tar.gz` file will be `gunzip`-ped to a `.tar` file, which can be extracted to a directory of files using `tar -xf` (`-x` for "extract", `-f` to specify the file to "untar"):

[ andrew@pc01 ~ ]$ tar -xfatom-amd64.tar && mv \

原子-beta-1.35.0-beta0-amd64 原子 && ls

原子atom-amd64.tar


To go in the reverse direction, you can create (`-c`) a tar file from a directory and zip it (or unzip it, as appropriate) with `-z`:

[ andrew@pc01 ~ ]$ tar -zcf 壓縮.tar.gz 原子 && ls

原子atom-amd64.tar壓縮.tar.gz


`.tar` files can also be zipped with `gzip`:

[ andrew@pc01 ~ ]$ gzipatom-amd64.tar && ls

原子 原子-amd64.tar.gz 壓縮.tar.gz


<a name="redirecting-io"></a>

## Redirecting Input and Output

<a name="pipe-gt-lt-echo-printf"></a>

### `| / > / < / echo / printf`

[[ Back to Table of Contents ]](#toc)

By default, shell commands read their input from the standard input stream (aka. stdin or 0) and write to the standard output stream (aka. stdout or 1), unless there’s an error, which is written to the standard error stream (aka. stderr or 2).

`echo` writes text to stdout by default, which in most cases will simply print it to the terminal:

[ andrew@pc01 ~ ]$ 回顯“你好”

你好


The pipe operator, `|`, redirects the output of the first command to the input of the second command:

'wc'(字數)傳回檔案中的行數、字數、位元組數

[ andrew@pc01 ~ ]$ echo "範例文件" |廁所

  1       2      17

`>` redirects output from stdout to a particular location

[ andrew@pc01 ~ ]$ echo "test" > 文件 && 頭文件

測試


`printf` is an improved `echo`, allowing formatting and escape sequences:

[ andrew@pc01 ~ ]$ printf "1\n3\n2"

1

3

2


`<` gets input from a particular location, rather than stdin:

'sort' 依字母/數字順序對檔案的行進行排序

[ andrew@pc01 ~ ]$ sort <(printf "1\n3\n2")

1

2

3


Rather than a [UUOC](#viewing-and-editing-files), the recommended way to send the contents of a file to a command is to use `<`. Note that this causes data to "flow" right-to-left on the command line, rather than (the perhaps more natural, for English-speakers) left-to-right:

[ andrew@pc01 ~ ]$ printf "1\n3\n2" > 文件 && 排序 < 文件

1

2

3


<a name="std-tee"></a>

### `0 / 1 / 2 / tee`

[[ Back to Table of Contents ]](#toc)

0, 1, and 2 are the standard input, output, and error streams, respectively. Input and output streams can be redirected with the `|`, `>`, and `<` operators mentioned previously, but stdin, stdout, and stderr can also be manipulated directly using their numeric identifiers:

Write to stdout or stderr with `>&1` or `>&2`:

[ andrew@pc01 ~ ]$ 貓測試

回顯“標準輸出”>&1

回顯“標準錯誤”>&2


By default, stdout and stderr both print output to the terminal:

[ andrew@pc01 ~ ]$ ./測試

標準錯誤

標準輸出


Redirect stdout to `/dev/null` (only print output sent to stderr):

[ andrew@pc01 ~ ]$ ./test 1>/dev/null

標準錯誤


Redirect stderr to `/dev/null` (only print output sent to stdout):

[ andrew@pc01 ~ ]$ ./test 2>/dev/null

標準輸出


Redirect all output to `/dev/null` (print nothing):

[ andrew@pc01 ~ ]$ ./test &>/dev/null


Send output to stdout and any number of additional locations with `tee`:

[ andrew@pc01 ~ ]$ ls && echo "測試" | tee 文件1 文件2 文件3 && ls

文件0

測試

文件0 文件1 文件2 文件3


<a name="advanced"></a>

# Advanced

<a name="superuser"></a>

## Superuser

<a name="sudo-su"></a>

### `sudo / su`

[[ Back to Table of Contents ]](#toc)

You can check what your username is with `whoami`:

[ andrew@pc01 abc ]$ whoami

安德魯


...and run a command as another user with `sudo -u username` (you will need that user's password):

[ andrew@pc01 abc ]$ sudo -u 測試觸摸 def && ls -l

總計 0

-rw-r--r-- 1 次測試 0 Jan 11 20:05 def


If `–u` is not provided, the default user is the superuser (usually called "root"), with unlimited permissions:

[ andrew@pc01 abc ]$ sudo touch ghi && ls -l

總計 0

-rw-r--r-- 1 次測試 0 Jan 11 20:05 def

-rw-r--r-- 1 root root 0 Jan 11 20:14 ghi


Use `su` to become another user temporarily (and `exit` to switch back):

[ andrew@pc01 abc ]$ su 測試

密碼:

test@pc01:/home/andrew/abc$ whoami

測試

test@pc01:/home/andrew/abc$ 退出

出口

[ andrew@pc01 abc ]$ whoami

安德魯


[Learn more about the differences between `sudo` and `su` here.](http://bit.ly/2SKQH77)

<a name="click-click"></a>

### `!!`

[[ Back to Table of Contents ]](#toc)

The superuser (usually "root") is the only person who can install software, create users, and so on. Sometimes it's easy to forget that, and you may get an error:

[ andrew@pc01 ~ ]$ apt 安裝 ruby

E:無法開啟鎖定檔案 /var/lib/dpkg/lock-frontend - 開啟(13:權限被拒絕)

E: 無法取得 dpkg 前端鎖定 (/var/lib/dpkg/lock-frontend),您是 root 嗎?


You could retype the command and add `sudo` at the front of it (run it as the superuser):

[ andrew@pc01 ~ ]$ sudo apt install ruby

正在閱讀包裝清單...


Or, you could use the `!!` shortcut, which retains the previous command:

[ andrew@pc01 ~ ]$ apt 安裝 ruby

E:無法開啟鎖定檔案 /var/lib/dpkg/lock-frontend - 開啟(13:權限被拒絕)

E: 無法取得 dpkg 前端鎖定 (/var/lib/dpkg/lock-frontend),您是 root 嗎?

[ andrew@pc01 ~ ]$ sudo !!

sudo apt 安裝 ruby

正在閱讀包裝清單...


By default, running a command with `sudo` (and correctly entering the password) allows the user to run superuser commands for the next 15 minutes. Once those 15 minutes are up, the user will again be prompted to enter the superuser password if they try to run a restricted command.

<a name="file-permissions"></a>

## File Permissions

<a name="file-permissions-sub"></a>

### File Permissions

[[ Back to Table of Contents ]](#toc)

Files may be able to be read (`r`), written to (`w`), and/or executed (`x`) by different users or groups of users, or not at all. File permissions can be seen with the `ls -l` command and are represented by 10 characters:

[ andrew@pc01 ~ ]$ ls -lh

總計 8

drwxr-xr-x 4 安德魯 安德魯 4.0K 1 月 4 日 19:37 品嚐

-rwxr-xr-x 1 安德魯 安德魯 40 Jan 11 16:16 測試

-rw-r--r-- 1 安德魯 安德魯 0 一月 11 16:34 tist


The first character of each line represents the type of file, (`d` = directory, `l` = link, `-` = regular file, and so on); then there are three groups of three characters which represent the permissions held by the user (u) who owns the file, the permissions held by the group (g) which owns the file, and the permissions held any other (o) users. (The number which follows this string of characters is the number of links in the file system to that file (4 or 1 above).)

`r` means that person / those people have read permission, `w` is write permission, `x` is execute permission. If a directory is “executable”, that means it can be opened and its contents can be listed. These three permissions are often represented with a single three-digit number, where, if `x` is enabled, the number is incremented by 1, if `w` is enabled, the number is incremented by 2, and if `r` is enabled, the number is incremented by 4. Note that these are equivalent to binary digits (`r-x` -> `101` -> `5`, for example). So the above three files have permissions of 755, 755, and 644, respectively.

The next two strings in each list are the name of the owner (`andrew`, in this case) and the group of the owner (also `andrew`, in this case). Then comes the size of the file, its most recent modification time, and its name. The `–h` flag makes the output human readable (i.e. printing `4.0K` instead of `4096` bytes).

<a name="chmod-chown"></a>

### `chmod / chown`

[[ Back to Table of Contents ]](#toc)

File permissions can be modified with `chmod` by setting the access bits:

[ andrew@pc01 ~ ]$ chmod 777 測試 && chmod 000 tit && ls -lh

總計 8.0K

drwxr-xr-x 4 安德魯 安德魯 4.0K 1 月 4 日 19:37 品嚐

-rwxrwxrwx 1 安德魯 安德魯 40 Jan 11 16:16 測試

---------- 1 安德魯 安德魯 0 一月 11 16:34 tist


...or by adding (`+`) or removing (`-`) `r`, `w`, and `x` permissions with flags:

[ andrew@pc01 ~ ]$ chmod +rwx Tist && chmod -w 測試 && ls -lh

chmod:測試:新權限是 r-xrwxrwx,而不是 r-xr-xr-x

總計 8.0K

drwxr-xr-x 4 安德魯 安德魯 4.0K 1 月 4 日 19:37 品嚐

-r-xrwxrwx 1 安德魯 安德魯 40 Jan 11 16:16 測試

-rwxr-xr-x 1 安德魯 安德魯 0 一月 11 16:34 tist


The user who owns a file can be changed with `chown`:

[ andrew@pc01 ~ ]$ sudo chown 碼頭測試


The group which owns a file can be changed with `chgrp`:

[ andrew@pc01 ~ ]$ sudo chgrp hadoop tit && ls -lh

總計 8.0K

drwxr-xr-x 4 安德魯 安德魯 4.0K 1 月 4 日 19:37 品嚐

-----w--w- 1 瑪麗娜·安德魯 2011 年 1 月 40 日 16:16 測試

-rwxr-xr-x 1 安德魯 hadoop 0 一月 11 16:34 tist


<a name="users-groups"></a>

## User and Group Management

<a name="users"></a>

### Users

[[ Back to Table of Contents ]](#toc)

`users` shows all users currently logged in. Note that a user can be logged in multiple times if -- for instance -- they're connected via multiple `ssh` sessions.

[ andrew@pc01 ~ ]$ 用戶

安德魯·科林·科林·科林·科林·科林·克里希納·克里希納


To see all users (even those not logged in), check `/etc/passwd`. (**WARNING**: do not modify this file! You can corrupt your user accounts and make it impossible to log in to your system.)

[ andrew@pc01 ~ ]$ alias au="cut -d: -f1 /etc/passwd \

|排序| uniq”&& au

_易於

一個廣告

安德魯...


Add a user with `useradd`:

[ andrew@pc01 ~ ]$ sudo useradd aardvark && au

_易於

土豚

一個廣告...


Delete a user with `userdel`:

[ andrew@pc01 ~ ]$ sudo userdel aardvark && au

_易於

一個廣告

安德魯...


[Change a user’s default shell, username, password, or group membership with `usermod`.](http://bit.ly/2D4upIg)

<a name="groups"></a>

### Groups

[[ Back to Table of Contents ]](#toc)

`groups` shows all of the groups of which the current user is a member:

[ andrew@pc01 ~ ]$ 組

andrew adm cdrom sudo dial plugdev lpadmin sambashare hadoop


To see all groups on the system, check `/etc/group`. (**DO NOT MODIFY** this file unless you know what you are doing.)

[ andrew@pc01 ~ ]$ alias ag=“cut -d: -f1 /etc/group \

|排序”&& ag

管理員

一個廣告

安德魯...


Add a group with `groupadd`:

[ andrew@pc01 ~ ]$ sudo groupadd aardvark && ag

土豚

管理員

一個廣告...


Delete a group with `groupdel`:

[ andrew@pc01 ~ ]$ sudo groupdel aardvark && ag

管理員

一個廣告

安德魯...


[Change a group’s name, ID number, or password with `groupmod`.](https://linux.die.net/man/8/groupmod)

<a name="text-processing"></a>

## Text Processing

<a name="uniq-sort-diff-cmp"></a>

### `uniq / sort / diff / cmp`

[[ Back to Table of Contents ]](#toc)

`uniq` can print unique lines (default) or repeated lines:

[ andrew@pc01 man ]$ printf "1\n2\n2" > a && \ > printf "1\n3\n2" > b

[ andrew@pc01 人 ]$ uniq a

1

2


`sort` will sort lines alphabetically / numerically:

[ andrew@pc01 man ]$ 排序 b

1

2

3


`diff` will report which lines differ between two files:

[ andrew@pc01 人 ]$ diff ab

2c2

< 2


3


`cmp` reports which bytes differ between two files:

[andrew@pc01 人]$ cmp ab

ab 不同:字元 3,第 2 行


<a name="cut-sed"></a>

### `cut / sed`

[[ Back to Table of Contents ]](#toc)

`cut` is usually used to cut a line into sections on some delimiter (good for CSV processing). `-d` specifies the delimiter and `-f` specifies the field index to print (starting with 1 for the first field):

[ andrew@pc01 人 ]$ printf "137.99.234.23" > c

[ andrew@pc01 man ]$ cut -d'.' c-f1

137


`sed` is commonly used to replace a string with another string in a file:

[ andrew@pc01 man ]$ echo "舊" | sed s/舊/新/

新的


...but `sed` is an extremely powerful utility, and cannot be properly summarised here. It’s actually Turing-complete, so it can do anything that any other programming language can do. `sed` can find and replace based on regular expressions, selectively print lines of a file which match or contain a certain pattern, edit text files in-place and non-interactively, and much more.

A few good tutorials on `sed` include:

- [https://www.tutorialspoint.com/sed/](https://www.tutorialspoint.com/sed/)
- [http://www.grymoire.com/Unix/Sed.html](http://www.grymoire.com/Unix/Sed.html)
- [https://www.computerhope.com/unix/used.htm](https://www.computerhope.com/unix/used.htm)

<a name="pattern-matching"></a>

## Pattern Matching

<a name="grep"></a>

### `grep`

[[ Back to Table of Contents ]](#toc)

The name `grep` comes from `g`/`re`/`p` (search `g`lobally for a `r`egular `e`xpression and `p`rint it); it’s used for finding text in files.

`grep` is used to find lines of a file which match some pattern:

[ andrew@pc01 ~ ]$ grep -e " .fi. " /etc/profile

/etc/profile:Bourne shell 的系統範圍 .profile 檔案 (sh(1))

# The file bash.bashrc already sets the default PS1.
fi
fi


...or contain some word:

[ andrew@pc01 ~ ]$ grep "andrew" /etc/passwd

安德魯:x:1000:1000:安德魯,,,:/home/andrew:/bin/bash


`grep` is usually the go-to choice for simply finding matching lines in a file, if you’re planning on allowing some other program to handle those lines (or if you just want to view them).

`grep` allows for (`-E`) use of extended regular expressions, (`-F`) matching any one of multiple strings at once, and (`-r`) recursively searching files within a directory. These flags used to be implemented as separate commands (`egrep`, `fgrep`, and `rgrep`, respectively), but those commands are now deprecated.

> **Bonus**: [see the origins of the names of a few famous `bash` commands](https://kb.iu.edu/d/abnd)

<a name="awk"></a>

### `awk`

[[ Back to Table of Contents ]](#toc)

`awk` is a pattern-matching language built around reading and manipulating delimited data files, like CSV files.

As a rule of thumb, `grep` is good for finding strings and patterns in files, `sed` is good for one-to-one replacement of strings in files, and `awk` is good for extracting strings and patterns from files and analysing them.

As an example of what `awk` can do, here’s a file containing two columns of data:

[ andrew@pc01 ~ ]$ printf "A 10\nB 20\nC 60" > 文件


Loop over the lines, add the number to sum, increment count, print the average:

[ andrew@pc01 ~ ]$ awk 'BEGIN {sum=0;計數=0; OFS=“”} {sum+=$2; count++} END {print "平均值:", sum/count}' 文件

平均:30


`sed` and `awk` are both Turing-complete languages. There have been multiple books written about each of them. They can be extremely useful with pattern matching and text processing. I really don’t have enough space here to do either of them justice. Go read more about them!

> **Bonus**: [learn about some of the differences between `sed`, `grep`, and `awk`](http://bit.ly/2AI3IaN)

<a name="ssh"></a>

## Copying Files Over `ssh`

<a name="ssh-scp"></a>

### `ssh / scp`

[[ Back to Table of Contents ]](#toc)

`ssh` is how Unix-based machines connect to each other over a network:

[ andrew@pc01 ~ ]$ ssh –p安德魯@137.xxx.xxx.89

上次登入:2019 年 1 月 11 日星期五 12:30:52,來自 137.xxx.xxx.199


Notice that my prompt has changed as I’m now on a different machine:

[ andrew@pc02 ~ ]$ 退出

登出

與 137.xxx.xxx.89 的連線已關閉。


Create a file on machine 1:

[ andrew@pc01 ~ ]$ echo "你好" > 你好


Copy it to machine 2 using `scp` (secure copy; note that `scp` uses `–P` for a port #, `ssh` uses `–p`)

[ andrew@pc01 ~ ]$ scp –P你好安德魯@137.xxx.xxx.89:~

你好 100% 0 0.0KB/秒 00:00


`ssh` into machine 2:

[ andrew@pc02 ~ ]$ ssh –p安德魯@137.xxx.xxx.89

上次登入:2019 年 1 月 11 日星期五 22:47:37,來自 137.xxx.xxx.79


The file’s there!

[ andrew@pc02 ~ ]$ ls

你好多xargs

[ andrew@pc02 ~ ]$ 貓你好

你好


<a name="rsync"></a>

### `rsync`

[[ Back to Table of Contents ]](#toc)

`rsync` is a file-copying tool which minimises the amount of data copied by looking for deltas (changes) between files.

Suppose we have two directories: `d`, with one file, and `s`, with two files:

[ andrew@pc01 d ]$ ls && ls ../s

f0

f0 f1


Sync the directories (copying only missing data) with `rsync`:

[ andrew@pc01 d ]$ rsync -off ../s/* .

正在發送增量文件列表...


`d` now contains all files that `s` contains:

[ andrew@pc01 d ]$ ls

f0 f1


`rsync` can be performed over `ssh` as well:

[ andrew@pc02 r ]$ ls

[ andrew@pc02 r ]$ rsync -avz -e "ssh -p “ [email protected]:~/s/* 。

接收增量檔案列表

f0

f1

發送 62 位元組 接收 150 位元組 141.33 位元組/秒

總大小為 0 加速率為 0.00

[ andrew@pc02 r ]$ ls

f0 f1


<a name="long-running-processes"></a>

## Long-Running Processes

<a name="yes-nohup-ps-kill"></a>

### `yes / nohup / ps / kill`

[[ Back to Table of Contents ]](#toc)

Sometimes, `ssh` connections can disconnect due to network or hardware problems. Any processes initialized through that connection will be “hung up” and terminate. Running a command with `nohup` insures that the command will not be hung up if the shell is closed or if the network connection fails.

Run `yes` (continually outputs "y" until it’s killed) with `nohup`:

[ andrew@pc01 ~ ]$ nohup 是 &

[1]13173


`ps` shows a list of the current user’s processes (note PID number 13173):

[ andrew@pc01 ~ ]$ ps | sed -n '/是/p'

13173 分/10 00:00:12 是


_...log out and log back into this shell..._

The process has disappeared from `ps`!

[ andrew@pc01 ~ ]$ ps | sed -n '/是/p'


But it still appears in `top` and `htop` output:

[ andrew@pc01 ~ ]$ 頂部 -bn 1 | sed -n '/是/p'

13173 安德魯 20 0 4372 704 636 D 25.0 0.0 0:35.99 是


Kill this process with `-9` followed by its process ID (PID) number:

[ andrew@pc01 ~ ]$ 殺死 -9 13173


It no longer appears in `top`, because it’s been killed:

[ andrew@pc01 ~ ]$ 頂部 -bn 1 | sed -n '/是/p'


<a name="cron"></a>

### `cron / crontab / >>`

[[ Back to Table of Contents ]](#toc)

`cron` provides an easy way of automating regular, scheduled tasks.

You can edit your `cron` jobs with `crontab –e` (opens a text editor). Append the line:
          • 日期 >> ~/datefile.txt

This will run the `date` command every minute, appending (with the `>>` operator) the output to a file:

[ andrew@pc02 ~ ]$ head ~/datefile.txt

2019 年 1 月 12 日星期六 14:37:01 GMT

2019 年 1 月 12 日星期六


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。

阿川私房教材:學程式,拿 offer!

63 個專案實戰,直接上手!
無需補習,按步驟打造你的面試作品。

立即解鎖你的轉職秘笈