所以我從本指南中得到了這個腳本:www.tldp.org/LDP/abs/abs-guide.pdf
LOG_DIR=/var/log
ROOT_UID=0
LINES=50
E_XCD=86
E_NOTROOT=87
if [ "$UID" != "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi
if [ -n "$1" ]
then
lines=$1
else
lines=$LINES
fi
cd $LOG_DIR
if [ 'pwd' != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi
現在我在終端機上執行了 sudo su 並回顯 $UID,這給了我 0。運行此腳本時。
同樣在原始腳本中,此 if 條件給出為
if [ "$UID" -ne "$ROOT_UID" ]
但我收到非法數字錯誤,因為顯然 -ne 僅用於字串,所以我將其更改為 !=。
答案1
而不是執行它
sh script.sh
執行它
bash script.sh
(或新增#!/bin/bash
為第一行來設定解釋器)。
sh
Ubuntu 中的 shell是不是 bash
,但是有一個名為 的單獨 shell dash
。dash
沒有與 一樣多的功能bash
,這使得它更加高效,但這些缺失的功能有時會破壞用於bash
.其中一個特徵就是 $UID
變量,它是沒有定義的在dash
。
這意味著當腳本在 中執行時dash
,比較將變為["" != "0"]
,無論哪個使用者執行它,其計算結果都是 true。但是,如果以 root 權限運行bash
,則字串將相等,並且腳本將正常工作。
答案2
作為麥克洛文 說,自動設定的唯讀UID
(和EUID
)變數是bash
(以及其他一些外殼)。這不是標準的伯恩風格的貝殼並且sh
不能假設設定這些變數。特別sh
是,在 Ubuntu 中(目前預設)dash
,這不會設定它們。
您有兩個選擇:
- 使您的腳本運行
bash
而不是sh
. - 更改您的腳本,使其更加可移植並且不需要
bash
.
運行你的腳本bash
您還沒有告訴我們您的腳本的名稱(沒關係)。我要稱呼它為cleanup
,因為這是您正在使用的指南中類似腳本的名稱。
特別注意的是我是不是稱為類似的東西cleanup.sh
。這是因為我不建議您使用後綴命名它.sh
:
- 後綴
.sh
表示它與sh
! - 大多數腳本根本沒有後綴,並且具有
.sh
或.bash
後綴甚至可能被解釋為表明您的文件是“庫”而不是“頂級”腳本。也就是說,它提供由其他腳本(例如,使用.
內建腳本)獲取的程式碼,而不是實際直接運行。
但是,包含.sh
後綴不會以任何方式影響腳本的技術行為。這樣做沒有任何技術優勢或劣勢。
添加一個哈希棒線作為腳本的第一行:#!/bin/bash
使您的腳本可執行和。chmod +x cleanup
現在你可以運行你的腳本透過運行命令:
./cleanup
,當它位於當前目錄中時。 (特別是在為教育、探索、測試、娛樂或其他有限或一次性用途編寫腳本時,這可能是最常見的方式。)/path/to/cleanup
, 一般來說。如果命令的第一個字包含 a,則/
它被解釋為可執行檔的路徑。 (這就是上述語法的原因./
,as.
表示當前目錄。)經過第一個字我的意思是命令直到但不包括它的第一個未逃脫的space 或 tab:
foo-bar/baz
是 的第一個單詞foo-bar/baz qux
,spam\ ham
而是的第一個單詞,spam\ ham eggs
因為前面的空格ham
是用反斜線轉義的。cleanup
,如果它位於您的目錄中PATH
(並且首先列出的目錄沒有同名的可執行文件,並且它沒有被外殼內置,功能, 或者別名)。
不管有沒有劇本cleanup
有一個#!...
hashbang 行或該行所說的內容:
sh cleanup
仍將(嘗試)sh
作為解釋器來運行它。bash cleanup
仍將(嘗試)bash
作為解釋器來運行它。
這是因為,在這些情況下,您實際上正在執行解釋器(sh
或bash
)並將腳本的名稱傳遞給解釋器以執行。許多程式接受要在命令列上開啟的檔案名,並且 shell 喜歡sh
並bash
遵循此約定。
使您的腳本可移植
如果您想要讓腳本可移植,最簡單的方法是$UID
根本不使用,而是使用所有 Bourne 風格 shell 都可用的一些工具。
一般來說,沒有內建的 shell 工具來確定使用者 ID。但你可以使用id
。這是一個外部程式而不是內建的 shell,但就像cat
和ls
,有理由預期它會出現。
id
它本身會輸出一堆訊息,但id -u
只給出有效的使用者 ID。
因此if [ "$UID" != "$ROOT_UID" ]
,您可以使用:
if [ "$(id -u)" != "$ROOT_UID" ]
從技術上來說,這不等價。$UID
inbash
給予真實的使用者 ID,並且id -u
確實對應於bash
s $EUID
。如果您確實想要 UID 而不是 EUID,請使用id -ru
.