Linux命令基礎使用

1.基礎知識

當我們打開終端時,終端軟件會為我們打開一個shell軟件,這個shell會顯示一個提示符,然後等待用戶輸入命令,類似下面這個:

然後我們就可以在這個界面中執行Linux命令瞭,shell做為一個命令解釋器,它會解釋並執行用戶輸入的命令。
這種shell有多種,如sh、csh、tcsh、zsh、fish、bash,而目前Linux環境中使用得最廣泛的就是bash。

2.命令參數與選項 

Linux命令基本都是如下的形式:

cat -n temp.txt


這個命令表示輸出temp.txt的內容,同時包含行號,其中,cat是命令程序,-n是選項,而temp.txt則是命令參數。
一般來說,選項用來控制命令的行為,參數用來給命令輸入數據。

3.標準輸入、標準輸出、標準錯誤

命令除瞭參數與選項外,還有標準輸入、標準輸出與標準錯誤這3個概念,如下:

標準輸入

同樣是用來給命令輸入數據,它與命令參數的區別是,參數一般是一個(或多個)簡短的文本值,而標準輸入是一個輸入流,命令可從其中讀取大量數據,類似java的System.in。

cat < temp.txt


它等效於cat temp.txt,但本質卻是不同的,cat temp.txt是cat這個程序內部會去讀取temp.txt文件的內容,cat是知道它在讀取temp.txt的,而cat < temp.txt是cat這個程序在讀取標準輸入中的數據,至於標準輸入中的數據從何而來,cat是不知道的。

同時,Linux命令中也經常使用 – 這個特殊的文件名來表示標準輸入文件,如下四個命令是等效的:

# cat不指定輸入文件時,默認就讀取標準輸入
cat
# cat認為 - 代表標準輸入文件
cat -
# /dev/stdin是具體的標準輸入文件
cat /dev/stdin
# 指定讀取0(標準輸入)這個文件描述符
cat <&0


標準輸出

每個命令都有一個標準輸出,這個類似標準輸入,也是一個流,不過它是用來給命令向外部輸出數據的,默認是屏幕,它類似javaSystem.out。如下:

# 命令默認寫出內容到標準輸出
echo hello | cat  
# 顯示指定寫到標準輸出文件
echo hello | cat > /dev/stdout


另外,在有些命令中,也會使用-來代表標準輸出文件。

標準錯誤 

標準錯誤概念上和標準輸出類似,不過它是用來程序報告錯誤的,類似javaSystem.err

如下:

# 顯示指定寫到標準錯誤文件
echo hello | cat > /dev/stderr


4.管道

管道的作用是把命令之間連接起來,讓它們之間可以傳遞數據,上面其實已經見過管道,如下:

echo hello | cat


echo程序將hello寫到標準輸出,| 將echo的標準輸出與cat的標準輸入連接起來,前面標準輸出寫出什麼數據,| 就會將這個數據傳到後面程序的標準輸入,行為就像管道一樣。

默認情況下,管道隻能將前面的標準輸出傳遞給後面的程序,如果想將標準錯誤也傳遞給後面程序,可以使用|&

# 標準輸出與標準錯誤都通過管道傳遞給cat
echo hello |& cat
# 與上面等價
echo hello 2>&1 | cat


5.重定向

輸入重定向,將文件內容重定向為程序的標準輸入

cat < temp.txt


也是輸入重定向,可即時輸入多行文本,bashHere Document語法

cat <<EOF
hello,java
hello,bash
EOF
<<<


也是輸入重定向,可即時輸入一行文本,bashHere String語法

cat <<<hello
>


標準輸出內容重定向到文件,覆蓋寫入

echo hello | cat > temp.txt
>>


標準輸出內容重定向到文件,追加寫入

echo hello | cat >> temp.txt
>&2


標準輸出內容重定向到標準錯誤

echo hello >&2
# 其實也可以寫成這樣
echo hello 1>&2
2>&1


標準錯誤重定向到標準輸出

# 標準輸出與標準錯誤都重定向到app.log,註意2>&1要放在後面
echo hello | cat > app.log 2>&1
# 簡寫形式,與上面等價
echo hello | cat &> app.log


6.管道與重定向揭秘

程序中使用文件描述符來引用一個文件,類似java中的File對象,但它是一個數字,又有點像指針,這個指針指向具體的文件。

而linux中,0就是標準輸入的文件描述符,1就是標準輸出的文件描述符,2就是標準錯誤的文件描述符

重定向本質是改變文件描述符的指向,如下:

1、執行cat命令後,在另一個shell中查看此cat的文件描述符,發現1標準輸出指向/dev/pts/1。

2、結束cat,我們再執行cat > temp.txt,在另一個shell中查看此cat的文件描述符,發現1標準輸出這個文件描述符指向瞭/tmp/temp.txt,所以,懂瞭麼~

管道本質是創建一個臨時管道文件,將前面程序的1標準輸出指向這個臨時文件,後面程序的0標準輸入也指向這個臨時文件,如下:

1、執行cat|cat命令

2、不要退出,在另一個shell中查看這兩個cat的文件描述符,如下:

註:shell會默認為管道符 | 創建臨時管道文件,如果有需要你也可以通過mkfifo顯示創建管道文件。

註:隻執行一個cat後,命令在等待輸入流的數據,所以看起來卡住瞭,這時可以使用Ctrl + d來退出,這和Ctrl + c是不同的,Ctrl + d作用類似於EOF信號,而Ctrl + c是中斷瞭進程。

7.Linux命令分類

基礎命令
(cd ls cp mv rm pwd du df tree find locate touch stat basename dirname realpath tar)
(echo printf seq yes tee date time dos2unix iconv bc sleep watch true)
文本命令
(find xargs grep sed awk jq cat head tail wc sort uniq comm join paste cut tr)
進程管理
(ps pstree kill pidof pgrep pkill nohup jobs bg fg disown fuser)
信息收集類
(lsof /proc netstat)
系統信息類
(lscpu lsblk lsscsi fdisk hostname uname dmesg ifconfig ethtool)
資源監控類
(top free vmstat iostat sar iftop dstat nmon glances bpytop)
診斷類
(strace tcpdump gdb gprof pmap pstack gcore perf systemtap bcc bpftrace)
網絡工具類
(ncat socat ping telnet host nslookup traceroute mtr ngrep tshark tcpdump nmap whois)

註:網絡類命令在這篇文章裡面有過系統介紹,感興趣可前往查看常用網絡命令總結

開發輔助類
(curl wget mysql screen tmux ssh scp sshpass expect nano vim emacs)
用戶管理類
(su sudo w who whoami id)

8.常用基礎命令

輸出 

# 輸出hello,並且尾部輸出一個換行符
$ echo hello
hello
# 輸出hello,尾部無換行符
$ echo -n hello
# -e使用echo可以解釋\n\t這樣的轉義符
$ echo -e 'a\nb\tc'
a
b       c
# 效果類似-e,不過用的是bash的語法特性
$ echo $'a\nb\tc'
a
b       c

# 格式化輸出,類似C語言的printf函數
$ printf "id:%d,name:%s\n" 1001 zhangsan
id:1001,name:zhangsan
# 參數多於占位符時,printf會重復
$ printf "id:%d,name:%s\n" 1001 zhangsan 1002 lisi 1003 wangwu
id:1001,name:zhangsan
id:1002,name:lisi
id:1003,name:wangwu

目錄操作 

# 切換到/home目錄
$ cd /home
# 切換到當前用戶傢目錄
$ cd
# ~也代表傢目錄
$ cd ~
# 切換到上次的目錄
$ cd -

# 顯示當前目錄
$ pwd

# 列出目錄下的文件或目錄
$ ls
# 列出當前目錄與一層子目錄,用瞭shell的*號擴展功能
$ ls *
# 列出文件或目錄,並顯示詳細信息,ll命令與其等價
$ ls -l
# 列出文件或目錄,時間倒序
$ ls -lt
# 列出文件或目錄,大小倒序
$ ls -lS

# 樹形顯示目錄與子目錄中的文件
$ tree
# 隻顯示2層目錄結構,-L 2表示遞歸深度為2
$ tree -L 2

# 顯示目錄以及子目錄的大小
$ du -h
# 顯示當前目錄的大小
$ du -h -s
# -d1表示遞歸深度為1,即顯示當前目錄下的目錄或文件大小
$ du -h -a -d1

# 當前目錄下,創建temp目錄
$ mkdir temp
# 創建多級目錄
$ mkdir -p temp/test/work
# 當前目錄下,刪除temp目錄,需保證待刪目錄是空的
$ rmdir temp

# 重命名目錄,也可以重命名文件
$ mv temp temp_bak
# 移動目錄,也可以移動文件
$ mv temp /tmp/temp_bak

文件操作

# 創建文件,touch實際是用來更新文件訪問時間的,不過如果文件不存在會默認創建它
$ touch temp.txt
# 寫入hello,會覆蓋原來內容
$ echo hello > temp.txt
# 追加寫入hello
$ echo hello >> temp.txt
# 查看文件內容
$ cat temp.txt
# 清空文件內容
$ echo -n > temp.txt
# 復制文件
$ cp temp.txt temp_bak.txt
# 刪除文件
$ rm temp_bak.txt
# 查看文件類型
$ file temp.txt
temp.txt: ASCII text
# 查看文件屬性,大小/日期等
$ stat temp.txt
  File: temp.txt
  Size: 6               Blocks: 8          IO Block: 4096   regular file
Device: 810h/2064d      Inode: 186702      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    work)   Gid: ( 1000/    work)
Access: 2021-10-10 15:24:11.256764900 +0800
Modify: 2021-10-10 15:24:09.326764900 +0800
Change: 2021-10-10 15:24:09.326764900 +0800
 Birth: -
# 隻獲取文件大小
$ stat -c %s temp.txt
6
# 獲取路徑上最後一級目錄或文件名
$ basename demo/temp.txt
temp.txt
# 獲取目錄名
$ dirname demo/temp.txt
demo
# 獲取全路徑名稱
$ realpath demo/temp.txt
/home/work/demo/temp.txt
# 獲取軟鏈接指向的文件
$ readlink /bin
usr/bin
# 修改文件所有者與讀寫權限
$ chown -R work:work test/
$ chmod -R 775 test/
# 查看文件系統空間使用情況
$ df -h
#將本地/home/work/目錄下的文件上傳到遠程/home/work/目錄裡
$ scp -r /home/work/* work@10.76.2.83:/home/work/
#將遠程/home/work/目錄下的文件下載到本地/home/work/目錄裡
$ scp -r work@10.76.2.83:/home/work/* /home/work/

文件打包與壓縮 

#壓縮文件為*.tar.gz(f必須在最後面)
$ tar -cvzf files.tar.gz files/
#這兩個命令與上面等價
$ tar -cvf files.tar files/
$ gzip files.tar
#查看壓縮文件
$ tar -tvzf files.tar.gz
#解壓tar.gz文件到/opt/目錄
$ tar -xvzf file.tar.gz -C /opt/
#解壓zip、Jar文件
$ unzip arthas-bin.zip -d arthas-bin/
$ unzip -O cp936 file.zip
#解壓rar文件
$ rar x file.rar

進程管理

# 列出所有進程,BSD格式
$ ps aux
# 列出所有進程,Linux格式
$ ps -ef
# 列出java進程
$ ps -fC java
# 查看進程號為523的進程
$ ps -fp 523
# 查看進程樹
$ pstree -Tp
# 查看當前shell的進程樹,其中$$會被shell解釋為當前shell的進程號
$ pstree -Tp -s $$
init(1)───init(104)───init(105)───wsltermd(106)───bash(107)───bash(121)───pstree(7203)
# 殺死523號進程
$ kill 523
# 強制殺死523號進程,如果你確定強殺也沒關系的話
$ kill -9 523
# 列出所有java進程的進程號,類似命令還有pidof
$ pgrep java
# 殺死所有java進程
$ pkill java


其它

# seq可以輸出連續數字
$ seq 4
1
2
3
4
$ seq 3 5
3
4
5

# yes會不斷輸出y,本是用來自動確認交互腳本的,但其也可指定輸出字串
$ yes hello | head -n4
hello
hello
hello
hello

# 顯示當前時間串
$ date +'%FT%T%z'
2021-10-10T16:31:50+0800
# 顯示當前時間綴
$ date +%s
1633854633
# 時間串與時間綴互轉
$ date -d '2021-10-10T16:31:50+0800' +%s
1633854710
$ date -d '@1633854710' +'%FT%T%z'
2021-10-10T16:31:50+0800

# time用來測量命令執行時間,sleep用來睡眠指定時間,默認秒
$ time sleep 5

real    0m5.010s
user    0m0.001s
sys     0m0.000s

# tee用於同時寫數據到文件和標準輸出
$ seq 5 | tee temp.txt
1
2
3
# 同時tee也可以用於觀察流過管道的數據,隻需要寫到/dev/tty即可,而bc是一個命令行版的科學計算器
$ seq -s+ 4 | tee /dev/tty | bc
1+2+3+4
10

# 將windows的換行符\r\n替換為\n
$ dos2unix temp.txt

# 將文件編碼從GBK轉到UTF-8
$ iconv -f GBK -t UTF-8 temp.txt > temp_utf8.txt

# watch用於不斷觀察命令輸出結果,如下觀察日志的寫入情況
$ watch -d -n1 ls -lt logs/

# split用於文件拆分,比如按10M大小拆分日志文件,拆分後文件名類似app0001
$ split -b 10m app.log -d -a4 app

# type用於查看命令安裝位置,which命令也可以,不過更推薦使用type
$ type ps
ps is hashed (/usr/bin/ps)

9.如何學習Linux命令

# 命令內置的help,一般記錄瞭各命令選項的作用
$ awk --help
# man與info記錄瞭命令的詳細說明
$ man awk
$ info awk
# tldr記錄瞭命令常見用法
$ tldr awk
# cht.sh綜合瞭tldr與man的能力
$ curl cht.sh/awk/:learn |less -R
# coreutils軟件包含有日常使用的絕大多數常用命令,值得瞭解下
$ info coreutils


更美觀的Linux命令
如果你喜歡折騰,就把下面鏈接中的全部裝上吧!
https://github.com/ibraheemdev/modern-unix

知識延伸指引:
標準輸入沒有重定向時,指向/dev/pts/1,它是啥東西?

到此這篇關於Linux命令基礎使用的文章就介紹到這瞭,更多相關Linux命令使用內容請搜索GuideAH以前的文章或繼續瀏覽下面的相關文章,希望大傢以後多多支持GuideAH!

閱讀更多: