天天看點

Bash、Source、“.”和“./”執行的差別

每日分享最新,最流行的軟體開發知識與最新行業趨勢,希望大家能夠一鍵三連,多多支援,跪求關注,點贊,留言。

Bash、Source、“.”和“./”執行的差別

本文探讨了在 Linux 上運作 shell 指令的各種方法。

在Linux 上工作時,您可能會遇到一些未按您預期的方式執行的檔案——例如,您可能在目前目錄中有一個檔案,但是當您輸入它的名稱時它沒有運作。你得到file_name.sh command not found了,但實際上,檔案在那裡。該檔案不起作用,即使具有執行權限,因為當你在 shell 上寫一些東西并運作它時,你的$PATH變量會被檢查。如果目錄内有任何比對的指令$PATH,例如/usr/bin,它将執行。除非有比對的指令,否則您将收到錯誤消息。

是以,您需要解決檔案的路徑。讓我們建立一個簡單的Linux shell 腳本并對該腳本具有執行權限。以下示例是用Bash Shell編寫的。

mkdir test && cd test

echo 'echo "hello world PID:$ ParentPID:$PPID"' > test.sh

chmod 755 test.sh

建立腳本後,讓我們按順序執行它們。

殼1測試.sh2#test.sh:找不到指令34. 測試.sh5#hello world PID:19245 ParentPID:1924367. ./test.sh # 同上。它隻是明确指定目前目錄。8#hello world PID:19245 ParentPID:19243910./test.sh #hello world PID:23044 ParentPID:1924511bash test.sh #hello world PID:23045 ParentPID:19245

$PATH除非目前目錄在環境變量中,否則直接給出檔案名不起作用。當您使用POSIX标準 shell(如 ksh)時,第二個指令也會失敗,因為在運作指令 shell 時檢查/指令内部是否存在。如果有,那麼它會查找您處理的目前工作目錄或絕對路徑。與此相反,然後它檢視裡面的指令$PATH。我目前正在處理的目錄不在 PATH 内,是以會出現錯誤。

test.sh

#test.sh: command not found

. test.sh

#hello world PID:19245 ParentPID:19243

. ./test.sh # this is same with above. it is just specifies current directory explicitly.

#hello world PID:19245 ParentPID:19243

./test.sh #hello world PID:23044 ParentPID:19245

bash test.sh #hello world PID:23045 ParentPID:19245

假設您正在使用Bash。通過執行兩者. file.sh或. ./file.sh結果來運作檔案将是相同的,但不是./test.sh. source和bash指令呢?

如果您使用任何 shell 指令,例如 Bash 或 ksh,您将生成一個新的 shell 來運作該指令。是以,您設定的每個變量在新 shell 中都不可用。另一方面,source使用目前的 shell 并且不産生新的 shell 程序。是以,您在檔案中所做的任何更改都會影響您目前的 shell。上面,正如您從輸出中看到的那樣,當您執行./或bash因為它們正在産生新程序時,PID 會發生變化。如上所示,指令的父程序 ID (PPID)bash test.sh等于指令的程序 ID (PID) . ./test.sh。

讓我們設定一個變量并在test.sh腳本中列印它。

bash -posix

test.sh

#bash: test.sh: command not found

. test.sh

#bash: .: test.sh: file not found

. ./test.sh

#hello world PID:23493 ParentPID:19245

./test.sh

#hello world PID:23539 ParentPID:23493

bash test.sh

#hello world PID:23540 ParentPID:23493

exit

顯然,該bash test.sh指令沒有給出$STR變量輸出,因為新的 shell 不知道。它沒有設定在新外殼中。讓我們在腳本中設定一個變量。

echo 'NEWSTR="WORLD"' >> test.sh

echo 'echo "NEWSTR is $NEWSTR"' >> test.sh

bash test.sh

#hello world PID:25318 ParentPID:19245

#STR is #NEWSTR is WORLD

echo $NEWSTR #this will give empty output

#

. test.sh

#hello world PID:19245 ParentPID:19243

#STR is HELLO #NEWSTR is WORLD

echo $NEWSTR

# WORLD

source test.sh

#hello world PID:19245 ParentPID:19243

# STR is # NEWSTR is WORLD

echo $NEWSTR

# WORLD

.并source在目前 shell 中運作,是以我們可以看到新變量。這就是運作該bash .bashrc指令不會更新您的 PATH 變量的原因。您應該使用source指令運作或使用.. 是以,您必須使用 source 指令來更改 PATH 變量。

最後,讓我們嘗試使用此資訊來更改和設定 PATH 變量。

mkdir directory && cd directory

echo 'echo "FILE"' > file.sh && chmod 755 file.sh

echo 'echo "COMMAND"' > echocommand && chmod 755 echocommand

pwd

# /home/ofk/test/directory

cd

# change PATH variable inside your .profile (or where ever you set PATH) file and add above path

# PATH="$PATH:/home/ofk/test/directory"

bash .profile

# try to run echocommand or file.sh

echocommand

# echocommand: command not found

file.sh

# file.sh: command not found

source .profile

echocommand

# COMMAND

file.sh

# FILE

結論

./或shell指令(bash、ksh)啟動新的 shell 并運作指令。

. file_name或source指令在目前 shell 上運作。

繼續閱讀