本文探討了在 Linux 上運(yùn)行 shell 命令的各種方法。

在Linux 上工作時(shí),您可能會(huì)遇到一些未按您預(yù)期的方式執(zhí)行的文件——例如,您可能在當(dāng)前目錄中有一個(gè)文件,但是當(dāng)您輸入它的名稱時(shí)它沒有運(yùn)行。你得到file_name.sh command not found了,但實(shí)際上,文件在那里。該文件不起作用,即使具有執(zhí)行權(quán)限,因?yàn)楫?dāng)你在 shell 上寫一些東西并運(yùn)行它時(shí),你的$PATH變量會(huì)被檢查。如果目錄內(nèi)有任何匹配的命令$PATH,例如/usr/bin,它將執(zhí)行。除非有匹配的命令,否則您將收到錯(cuò)誤消息。
因此,您需要解決文件的路徑。讓我們創(chuàng)建一個(gè)簡(jiǎn)單的Linux shell 腳本并對(duì)該腳本具有執(zhí)行權(quán)限。以下示例是用Bash Shell編寫的。
mkdir test && cd test
echo 'echo "hello world PID:$$ ParentPID:$PPID"' > test.sh
chmod 755 test.sh
創(chuàng)建腳本后,讓我們按順序執(zhí)行它們。
殼1測(cè)試.sh2#test.sh:找不到命令34. 測(cè)試.sh5#hello world PID:19245 ParentPID:1924367. ./test.sh # 同上。它只是明確指定當(dāng)前目錄。8#hello world PID:19245
ParentPID:19243910./test.sh #hello world PID:23044 ParentPID:1924511bash test.sh #hello world PID:23045 ParentPID:19245
$PATH除非當(dāng)前目錄在環(huán)境變量中,否則直接給出文件名不起作用。當(dāng)您使用POSIX標(biāo)準(zhǔn) shell(如 ksh)時(shí),第二個(gè)命令也會(huì)失敗,因?yàn)樵谶\(yùn)行命令 shell 時(shí)檢查/命令內(nèi)部是否存在。如果有,那么它會(huì)查找您處理的當(dāng)前工作目錄或絕對(duì)路徑。與此相反,然后它查看里面的命令$PATH。我當(dāng)前正在處理的目錄不在 PATH 內(nèi),因此會(huì)出現(xiàn)錯(cuò)誤。
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
假設(shè)您正在使用Bash。通過執(zhí)行兩者. file.sh或. ./file.sh結(jié)果來運(yùn)行文件將是相同的,但不是./test.sh. source和bash命令呢?
如果您使用任何 shell 命令,例如 Bash 或 ksh,您將生成一個(gè)新的 shell 來運(yùn)行該命令。因此,您設(shè)置的每個(gè)變量在新 shell 中都不可用。另一方面,source使用當(dāng)前的 shell 并且不產(chǎn)生新的 shell 進(jìn)程。因此,您在文件中所做的任何更改都會(huì)影響您當(dāng)前的 shell。上面,正如您從輸出中看到的那樣,當(dāng)您執(zhí)行./或bash因?yàn)樗鼈冋诋a(chǎn)生新進(jìn)程時(shí),PID 會(huì)發(fā)生變化。如上所示,命令的父進(jìn)程 ID (PPID)bash test.sh等于命令的進(jìn)程 ID (PID) . ./test.sh。
讓我們?cè)O(shè)置一個(gè)變量并在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變量輸出,因?yàn)樾碌?shell 不知道。它沒有設(shè)置在新外殼中。讓我們?cè)谀_本中設(shè)置一個(gè)變量。
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在當(dāng)前 shell 中運(yùn)行,因此我們可以看到新變量。這就是運(yùn)行該bash .bashrc命令不會(huì)更新您的 PATH 變量的原因。您應(yīng)該使用source命令運(yùn)行或使用.. 因此,您必須使用 source 命令來更改 PATH 變量。
最后,讓我們嘗試使用此信息來更改和設(shè)置 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
結(jié)論
./或shell命令(bash、ksh)啟動(dòng)新的 shell 并運(yùn)行命令。
. file_name或source命令在當(dāng)前 shell 上運(yùn)行。