避免 UNIX 和 Linux 中的常見(jiàn)錯誤
您是否遇到過(guò) Execute permission denied
或 The parameter list is too long
這樣的錯誤消息?您想知道錯誤的原因嗎?這些是 UNIX 和 Linux 新手經(jīng)常遇到的錯誤,他們可能不知道如何避免這些問(wèn)題。本文解釋這些錯誤并提供解決方法。
./foo: 0403-006 Execute permission denied.
您編寫(xiě)或下載了一個(gè)新的 shell 腳本,很想試試它。這聽(tīng)起來(lái)不錯,但是在試圖執行這個(gè)命令時(shí),收到了錯誤消息 ./foo: 0403-006 Execute permission denied
。怎么回事兒?這個(gè)消息可能源于兩個(gè)問(wèn)題:
您不具有執行這個(gè)命令的足夠權限。
對于腳本中定義的 shell,您不具有足夠的權限,無(wú)法告訴 shell 應該如何解釋腳本和其中的命令。
您不具有執行這個(gè)命令的足夠權限
檢查權限最簡(jiǎn)便的方法是,查看您是作為哪個(gè)用戶(hù)登錄服務(wù)器的,然后查看 ls –l
的輸出:
# id uid=5008(cormany) gid=330(atc) groups=110(sales),201(sshd) # ls -l foo -rwxrw-r-- 1 cormany atc 75 Jun 10 18:46 foo
根據這個(gè)示例,您是作為用戶(hù) cormany 登錄的,而 shell 腳本的所有者是 cormany,他具有 rwx 權限(即讀、寫(xiě)和執行)。這沒(méi)問(wèn)題,所以我們考慮下一個(gè)可能的原因。
對于腳本中定義的 shell,您不具有足夠的權限,無(wú)法告訴 shell 應該如何解釋腳本和其中的命令
我們來(lái)看看腳本的內部:
# cat foo #!/bin/ksh.new echo "This is a just a test" exit 0
根據第一行,這個(gè)腳本看起來(lái)應該作為 Korn shell 腳本進(jìn)行解釋。通過(guò)檢查所用的 shell 的權限,可以確認實(shí)際上是否可以使用它:
# ls –l /bin/ksh.new -r-xr-x--- 5 bin bin 289072 May 27 19:03 /bin/ksh.new
作為 root 用戶(hù),修改要使用的 shell 的文件權限,然后再試一次:
切換為 root 用戶(hù):
# su - root's Password:
確認您現在是 root 用戶(hù)而不是原來(lái)的用戶(hù):
# id uid=0(root) gid=0(system) groups=2(bin),3(sys),7(security),8(cron),10(audit),11(lp)
修改文件的權限:
# chmod 555 /bin/ksh.new
確認文件權限已經(jīng)改變了:
# ls -l /bin/ksh.new -r-xr-xr-x 1 bin bin 289072 Jun 10 18:45 /bin/ksh.new
退出
su
,恢復為原來(lái)的用戶(hù):# exit # id uid=5008(cormany) gid=330(atc) groups=110(sales),201(sshd)
再次嘗試執行腳本:
# ./foo This is a just a test
好了,問(wèn)題解決了!
ksh: bar: not found.
您編寫(xiě)了另一個(gè)腳本 bar 并把它保存在 ~cormany/scripts 目錄中。在使用完整路徑或在當前工作目錄 (~cormany/scripts) 中執行這個(gè)腳本時(shí),它工作正常;但是,由于某種原因,如果在另一個(gè)目錄中只輸入腳本名,就無(wú)法運行它:
# pwd /home/cormany/scripts # /home/cormany/scripts/bar This is another test # ./bar This is another test # cd # pwd /home/cormany # barksh: bar: not found.
一切正常,只是無(wú)法從另一個(gè)目錄運行這個(gè)腳本。這樣的錯誤消息通常有三種情況:
對于試圖執行的文件,您沒(méi)有權限。
文件不存在或不在您認為的目錄中。
文件存在而且在預期的位置,您對這個(gè)文件也有足夠的權限。
對于試圖執行的文件,您沒(méi)有權限
您知道不是這個(gè)原因,因為在提供完全限定的路徑時(shí)或在命令目錄中時(shí)能夠執行這個(gè)腳本。如果不能排除這種可能性,檢查文件權限應該有助于發(fā)現問(wèn)題的原因:
# ls -la ~cormany/scripts total 56 drwxr-xr-x 2 cormany atc 512 Jun 12 08:30 . drwxr-xr-x 6 cormany atc 512 Jun 10 08:21 .. -rwxr-xr-x 1 cormany atc 42 Sep 06 16:20 amdc -rw-rw-rw- 1 cormany atc 154 Jan 27 23:23 atc -rwxr-xr-x 1 cormany atc 206 Aug 04 20:57 atc.2 -rwxr-xr-x 1 cormany atc 48 Jun 12 08:21 bar -rwxr-xr-x 1 cormany atc 87 Feb 22 16:11 pac
執行 ~cormany/scripts/atc
命令會(huì )失敗,因為這個(gè)文件只對用戶(hù)、組和其他用戶(hù)設置了讀和寫(xiě)權限。只需增加執行權限,即可解決這個(gè)問(wèn)題。
如果無(wú)法執行另一個(gè)目錄中的另一個(gè)命令(例如 ~cormany/scripts.old/cujo),那么也應該檢查那個(gè)文件的權限:
# ls -l ~cormany/other_scripts/cujo ls: 0653-345 /home/cormany/other_scripts/cujo: Permission denied.
初看上去,您甚至沒(méi)有讀權限。我們來(lái)看看目標目錄,看看是怎么回事兒:
# cd ~cormany/scripts.old/cujo ksh: /home/cormany/other_scripts: Permission denied. # ls -l ~cormany/scripts.old/cujo ls: /home/cormany/scripts.old: The file access permissions do not allow the specified action. total 0
這里發(fā)生了什么情況?這是另一種形式的權限錯誤。權限錯誤不總是出現在文件本身,也可能出現在文件路徑中的目錄上:
# ls -ld ~cormany/scripts.old d--------- 2 cormany atc 512 Jan 22 08:42 /home/cormany/scripts.old
如果文件本身有足夠的權限,那么糾正目錄路徑上的權限應該會(huì )解決執行問(wèn)題:
# chmod 755 ~cormany/other_scripts # cd ~cormany/other_scripts # ls –l cujo -rwxr-xr-x 1 cormany atc 48 Jan 26 08:21 cujo
現在,回到原來(lái) ~cormany/scripts/bar 的問(wèn)題。
文件不存在或不在您認為的目錄中
同樣,使用 ls
命令執行快速檢查,應該會(huì )看到這個(gè)文件是否存在:
# ls -l ~cormany/scripts/bar -rwxr-xr-x 1 cormany atc 48 Oct 05 08:21 /home/cormany/scripts/bar
如果在您原來(lái)認為的目錄中沒(méi)有這個(gè)文件,就會(huì )收到以下消息:
# ls -l ~cormany/scripts/bar ls: 0653-341 The file /home/cormany/scripts/bar does not exist.
如果您認為這個(gè)文件在用戶(hù) cormany 的主目錄中的其他地方,可以用 find
命令搜索它(如果您有足夠的權限的話(huà)):
# find ~cormany -name "bar" -ls 16409 1 -rwxr-xr-x 1 cormany atc 48 Sep 06 08:06 /home/cormany/atc/bar 590040 1 -rwxr-xr-x 1 cormany atc 48 Sep 09 08:42 /home/cormany/test/bar
文件存在而且在預期的位置,您對這個(gè)文件也有足夠的權限
前面成功執行時(shí)采用的方法是提供完全限定的命令路徑,或者處于命令目錄中并輸入當前工作目錄(即使用 ./
)。既然現在不在命令目錄中,也不輸入完整路徑,我們就來(lái)檢查一下 PATH 環(huán)境變量的值:
# echo ${PATH} /usr/bin:/etc:/usr/sbin:/usr/ucb:/bin:/usr/bin/X11:/sbin:/usr/ java5/jre/bin:/usr/java5/bin:/usr/ushare/bin:/usr/local/bin
目錄 /home/cormany/scripts 不在路徑中。糾正這個(gè)問(wèn)題有兩種方法:
在 PATH 中添加
~cormany/scripts
。盡管很容易執行這個(gè)修改,但是請記住一點(diǎn):每在 PATH 變量中添加一個(gè)目錄,shell 在搜索命令時(shí)就會(huì )多搜索一個(gè)目錄。如果隨著(zhù)時(shí)間的推移添加了 10 個(gè)目錄,那么在 shell 返回無(wú)法找到文件的結果之前,它要多搜索 10 個(gè)目錄。如果您確實(shí)要這么做,只需執行以下命令:# export PATH=${PATH}:/home/cormany/scripts # echo $PATH /usr/bin:/etc:/usr/sbin:/usr/ucb:/bin:/usr/bin/X11:/sbin:/usr/ java5/jre/bin:/usr/java5/bin:/usr/ushare/bin:/usr/local/bin:/ home/cormany/scripts
注意:把路徑添加到用戶(hù)的 PATH 變量的開(kāi)頭通常是不明智。這么做可能導致執行不需要的命令。如果您覺(jué)得必須把一個(gè)路徑放在開(kāi)頭,一定要謹慎。
把腳本轉移(或復制)到 PATH 變量中已有的目錄中。如果多個(gè)用戶(hù)可能使用這個(gè)腳本,這種解決方案比較好。如果是這種情況,用戶(hù)通常把他們的文件放在 /usr/local/bin 中。
ls: 0653-341 The file . does not exist.
您正在 ~cormany/scripts 目錄中工作。突然,這個(gè)目錄中的腳本都找不到了,您收到一條奇怪的消息,它說(shuō)當前工作目錄不再存在:
# ls -l total 40 -rwxr-xr-x 1 cormany atc 42 Sep 06 16:20 amdc -rw-rw-rw- 1 cormany atc 154 Jan 27 23:23 atc -rwxr-xr-x 1 cormany atc 206 Aug 04 20:57 atc.2 -rwxr-xr-x 1 cormany atc 48 Jun 12 08:21 bar -rwxr-xr-x 1 cormany atc 87 Feb 22 16:11 pac # ./bar This is another test # pwd /home/cormany/scripts # ./barksh: ./bar: not found. # ls -lls: 0653-341 The file . does not exist.
當出現這種情況時(shí),就說(shuō)明通過(guò) rm
命令刪除了您原來(lái)的工作目錄。僅僅創(chuàng )建一個(gè)同名的新目錄不會(huì )解決這個(gè)問(wèn)題,因為文件描述符不一樣。
出現這種事故常常是因為您自己在另一個(gè)窗口中執行了 rm
命令(至少我是這樣)。為了避免這種事故,可以通過(guò) mv
命令修改目錄名。如果修改目錄名,原來(lái)目錄中的用戶(hù)可以繼續工作,只是采用不同的目錄名,因為文件描述符仍然是相同的:
# ls -l total 40 -rwxr-xr-x 1 cormany atc 42 Sep 06 16:20 amdc -rw-rw-rw- 1 cormany atc 154 Jan 27 23:23 atc -rwxr-xr-x 1 cormany atc 206 Aug 04 20:57 atc.2 -rwxr-xr-x 1 cormany atc 48 Jun 12 08:21 bar -rwxr-xr-x 1 cormany atc 87 Feb 22 16:11 pac # ./bar This is another test # pwd /home/cormany/scripts
同樣,假設有人在另一個(gè)會(huì )話(huà)中把您正在工作的目錄改為 ~cormany/scripts.20090601。由于只是轉移目錄和修改目錄名,您仍然可以繼續工作:
# ./bar This is another test # pwd /home/cormany/scripts.20090601
./foo: /usr/bin/ls: 0403-027 The parameter list is too long.
一個(gè)程序在您的 IBM? AIX? 計算機上已經(jīng)運行了幾個(gè)月,沒(méi)有出現問(wèn)題。但是,在這個(gè)程序運行時(shí),它每隔幾分鐘在同一個(gè)日志目錄中創(chuàng )建文件。文件名以 f.<number> 和 e.<number> 開(kāi)頭。目錄越來(lái)越滿(mǎn),ls
命令的響應時(shí)間顯著(zhù)增加。這是可以理解的,因為目錄中的文件太多了。
又過(guò)了幾個(gè)月,這個(gè) AIX 程序一直運行,仍然沒(méi)有問(wèn)題?,F在,有了 100,000 個(gè)以 f. 開(kāi)頭的文件和另外 100,000 個(gè)以 e. 開(kāi)頭的文件?,F在,如果您試圖清理這個(gè)日志目錄,刪除以 f. 開(kāi)頭的文件,就會(huì )收到以下消息:
# rm ~cormany/logs/f.* ksh: /usr/bin/rm: 0403-027 The parameter list is too long.
我認為您太久沒(méi)有清理文件了。但是,現在還不晚。
在執行 delete
等命令時(shí),會(huì )在執行之前檢查和展開(kāi)所有參數。這個(gè)示例尋找 ~cormany/logs/f.*
,這會(huì )展開(kāi)為 rm
命令的 100,000 個(gè)參數。換句話(huà)說(shuō),實(shí)際上執行的并不是 rm ~cormany/logs/f.*
,而是 rm ~cormany/logs/f.1 ~cormany/logs/f.2 ~cormany/logs/f.3 … ~cormany/logs/f.100000
。
與其他 UNIX 和 Linux 操作系統一樣,AIX 規定了可以使用的命令行參數和環(huán)境變量的長(cháng)度。在 AIX 中,可以使用 getconf
命令檢查這個(gè)值。在 getconf
手冊頁(yè)上,應該會(huì )看到 ARG_MAX
:
# man getconf … ARG_MAX Maximum length, in bytes, of the arguments for one of the exec subroutines, including environment data. … # getconf ARG_MAX1048576
這個(gè)值說(shuō)明對于環(huán)境變量和命令行參數可以使用 1,048,576 字節??雌饋?lái)您已經(jīng)超過(guò)了這個(gè)上限。解決這個(gè)問(wèn)題有兩種方法:
使用
smitty chgsys
并修改ARG/ENV list size in 4K byte blocks
以提高這個(gè)值,或者使用chdev
提高這個(gè)值。我不建議在每次遇到這類(lèi)錯誤時(shí)為了圖方便修改系統范圍的參數:這應該是最后一招。不使用帶 100,000 個(gè)參數的
rm
命令(這會(huì )執行失?。?,而是使用find
命令刪除文件,這會(huì )好得多:# find ~cormany/logs –name “f.*” –exec rm {} ;
find
命令在目錄中搜索以 f. 開(kāi)頭的所有文件,而不是在 shell 命令行中放那么多參數。然后,find
命令對找到的每個(gè)文件執行rm
,這樣就會(huì )刪除以 f. 開(kāi)頭的所有文件。
結束語(yǔ)
讀完本文之后,您應該了解了這些常見(jiàn)問(wèn)題,知道如何快速地解決問(wèn)題。錯誤可能看起來(lái)很簡(jiǎn)單,但是在 UNIX 中您必須解決基本錯誤,才能順利地前進(jìn)。愿您能夠順利地排除故障!
linux相關(guān)文章:linux教程
評論