從PATH說起的shell命令列替換

2021-09-20 00:26:15 字數 3454 閱讀 7690

許久之前,師弟問了我乙個問題,為什麼shell中新增環境變數的寫法是下面這種方式

path=~/.lib:$path; export path
而下面這種會報錯呢?

$path=~/.lib:$path; export path
當時我的回答是,"shell就是這樣子規定的呀"。 回答的同時,也突然間發現有些自己感覺很熟悉的概念,原來自己並沒有那麼清楚,因此這一篇講講shell的命令列替換。先說結論

shell會在命令執行前對命令列進行一些替換

shell替換有如下幾種:

替換語法

含義歷史

!之前使用命令

大括號{}

指定的文字

代字型大小~username

使用者的主目錄

變數$, $

shell和環境變數

算術$((..))

整數運算

命令替換

`...`, $(...)

執行在子shell裡命令的輸出

路徑名*,?,[...],[^...]

檔案系統中匹配的檔名

歷史替換是以!開頭的替換方式,以下面歷史記錄為例

歷史記錄

$ !! # 執行上乙個命令,即history

$ !1021 # 支援第1021個命令 即ls

$ !-2 # 執行倒數第二個命令,即ls

大括號替換: 它會將裡的內容展開為多個單詞,可以快速建立有一定規律的檔案. 下面這個命令就把"chap0"替換成了chap01, chap02, chap03, 以及每個都還有乙個html和text對應。

$ mkdir -p chap0/

$ tree chap0*

chap01

├── html

└── text

chap02

├── html

└── text

chap03

├── html

└── text

代字型大小代替: 我們經常會看到別人文章會寫用vim ~/.bashrc修改家目錄下的配置檔案,其中~預設就會替代成自己家目錄路徑,可以用echo ~確認。

那麼問題來了,如何我想快速到別人的家目錄下,應該怎麼操作。只要在~加上別人的使用者名稱就行了。比如說我/home 下還有乙個使用者叫做abc, 那麼檢視它家目錄下的內容就是

ls ~abc
注:~a可以用tab補全成~abc

變數替換: shell會把$或者$變數名替換成變數所指代的具體字元,比如說我將abc指代為ls,那麼shell就會將$abc解釋成ls,然後執行ls

abc=ls

$abs

# desktop bin biosoft blastdb miniconda3 ncbi

也就是$path=~/.lib:$path; export path報錯的原因是,shell在執行命令前會把$path成原來path裡的字串,顯然無法達到修改path的目的

算術替換: shell命令列支援整數型的數**算,下面的運算都是可以的,但是就別拿100/2.5這種浮點運算為難shell了。

echo $((1+2))

echo $((1-2))

echo $((100*101))

echo $((100/50))

命令替換:這個替換非常的實用,可以將shell命令的輸入結果立刻作為輸入,而不是額外建立乙個變數命。有乙個應用場景就是在的分析報告裡加上完成時間點

touch reports.$(date +%d%b%y).log
路徑名替換:路徑替換的語法就4種,*表示0或更多的任意字元,?表示乙個任意字元,[...]表示括號內的字元之一,[^...]不包括括號內的字元

以上就是shell命令列替換的幾種形式。當然為了再一次強調"shell會在命令執行前對命令列進行一些替換",下面舉乙個反面例子來說明下。

linux的/etc目錄下有很多以conf結尾的配置檔案,我們可以用find命令快速的定位到它們。

find /etc -name *.conf
上面的命令看起來沒啥毛病,但是只要多做一件事情,就會有報錯哦

touch a.conf b.conf

find /etc -name *.conf

# 如下是報錯

find: paths must precede expression: b.conf

usage: find [-h] [-l] [-p] [-olevel] [-d help|tree|search|stat|rates|opt|exec|time] [path...] [expression]

你會不會好奇,明明是相同的命令,卻又不同的境遇呢?讓我解釋下,在剛開始的時候,檔案下面沒有"a.conf","b.conf",儘管shell看到"*"會有一種進行通配的衝動,但是很可惜沒有物件讓它統配。後來我們建立了這兩個檔案,給shell找到通配的機會,於是實際執行的命令就成了 "find /etc -name a.conf b.conf"。 由於後面這兩個是檔案路徑,不符合find的命令要求,就導致了報錯。

其實報錯還好,有些時候沒有報錯,程式執行得到錯誤的結果反而更慘

如何避免這種錯誤呢?我們就需要用到"避免\*這個元字元被shell解釋。

除了雙引號,避免shell進行替換的符號還有 反斜槓\ , 和單引號 '. 單引號和雙引號的區別在於,單引號內部所有字元都是普通字元而已,而雙引號裡的美元符號$, 感嘆號! 和反引號 ` 還能被shell解釋

從Ajax的HelloWorld說起

從ajax的helloworld說起 收藏 就這個經典的helloworld示例,學習ajax的互動模式。還是從如何建立helloworld說起吧 1 建立 xmlhttprequest 物件 2 初始化非同步請求,xmlhttprequest物件如何做 中轉站 的工作,就在這裡體現 先獲取個客戶端...

從python的yield說起

感覺是在需要返回某個值的地方通過yield來代替return,不是很明白其用法,所以仔細研究下。乙個使用了yiled關鍵字的函式就不再是乙個普通的函式了,而是乙個生成器函式 generator function 當函式被呼叫的時候將返回乙個迭代器 iterator 所以下面將分別講解迭代器和生成器這...

從《我的青春我做主》說起

憑著對 奮鬥 的喜歡,和號稱 奮鬥 姊妹篇的蠱惑。看了 我的青春我做主 委實讓人失望了一把。首先,台詞給人感覺很假,很做作,更像在演話劇。其次,陸毅確實很帥,也比以前成熟了很多,他的加入讓本劇有了韓劇的味道。這一點,他比不了陸濤,陸濤給人的感覺更平實 奮鬥 的熱播一方面說明80後的崛起,開始掌握這個...