そこで私はこのガイドからこのスクリプトを入手しました: 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 条件は false になりますが、このスクリプトの実行中に「このスクリプトを実行するには root である必要があります。」というメッセージが表示されます。
また、元のスクリプトでは、このif条件は次のように指定されていました。
if [ "$UID" -ne "$ROOT_UID" ]
しかし、どうやら -ne は文字列にのみ使用されるため、不正な数値エラーが発生したため、!= に変更しました。
答え1
代わりに、
sh script.sh
実行する
bash script.sh
(または、#!/bin/bash
インタープリターを設定する最初の行として追加します)。
sh
Ubuntuのシェルはない bash
ですが、 と呼ばれる別のシェルがありますdash
。dash
は ほど多くの機能を持たないためbash
、より効率的ですが、これらの機能が不足しているため、 向けのスクリプトが機能しなくなることがありますbash
。そのような機能の1つは $UID
、変数です。定義されていませんでdash
。
つまり、スクリプトが で実行されるとdash
、比較は となり["" != "0"]
、どのユーザーが実行しているかに関係なく true と評価されます。ただし、 でルート権限を使用して実行されるとbash
、文字列は等しくなり、スクリプトは機能します。
答え2
としてマクラヴィンは言う、自動的に設定される読み取り専用UID
(およびEUID
)変数は、bash
(および他のシェル)。これは標準ではありませんボーンスタイルのシェルこれらの変数を設定することはsh
想定できません。特にsh
Ubuntuでは(現在、デフォルトでは)dash
、設定されません。
次の 2 つのオプションがあります。
- スクリプトが
bash
ではなくによって実行されるようにしますsh
。 - スクリプトを変更して、移植性を高め、 を必要としないようにします
bash
。
スクリプトを実行するbash
スクリプトの名前を教えてくれませんでした(大丈夫です)。cleanup
、これは、作業中のガイド内の同様のスクリプトの名前です。
特に私がないのように呼びますcleanup.sh
。これは、接尾辞付きの名前を付けることをお勧めしないためです.sh
。
- 接尾辞
.sh
は、 と互換性があることを示しますsh
。 - ほとんどのスクリプトにはサフィックスがまったく付けられておらず、
.sh
または.bash
サフィックスが付いていると、ファイルが「トップレベル」スクリプトではなく「ライブラリ」であると解釈されることもあります。つまり、実際に直接実行されるのではなく、他のスクリプトによってソースされるコード (たとえば、.
組み込みスクリプトを使用) が提供されるということです。
ただし、.sh
サフィックスを追加しても、スクリプトの技術的な動作にはまったく影響しません。サフィックスを追加しても、技術的な利点や欠点はありません。
追加ハッシュバンラインスクリプトの最初の行として:#!/bin/bash
スクリプトを実行可能にすると。chmod +x cleanup
今ならできるスクリプトを実行する次のコマンドを実行します:
./cleanup
、現在のディレクトリにある場合。(特に、教育、調査、テスト、楽しみ、またはその他の限定的または 1 回限りの使用のためにスクリプトを作成する場合、これがおそらく最も一般的な方法です。)/path/to/cleanup
一般的には です。コマンドの最初の単語に が含まれている場合、/
それは実行可能ファイルへのパスとして解釈されます。(これが上記の構文の理由です./
。 は.
現在のディレクトリを意味します。)による最初の単語最初のコマンドまで(最初のコマンドは含まない)逃げられないスペースまたはタブ:
foo-bar/baz
は の最初の単語ですfoo-bar/baz qux
が、 はspam\ ham
の最初の単語です。これは、spam\ ham eggs
その前のスペースham
がバックスラッシュでエスケープされているためです。cleanup
、それがあなたのディレクトリ内にある場合PATH
(そして最初にリストされたディレクトリに同じ名前の実行ファイルが存在せず、それがシェル組み込み、関数、 またはエイリアス)。
スクリプトの有無にかかわらずcleanup
ハッシュバン行#!...
またはその行の内容は次のとおりです。
sh cleanup
sh
インタープリターとして実行しようとします。bash cleanup
bash
インタープリターとして実行しようとします。
これは、これらのケースでは、実際にインタープリタ (sh
またはbash
) を実行し、実行するスクリプトの名前をインタープリタに渡すためです。多くのプログラムは、コマンドラインで開くファイル名を受け入れ、 や などのシェルはsh
このbash
規則に従います。
スクリプトをポータブルにする
スクリプトを移植可能にしたい場合、最も簡単な方法は、 を$UID
まったく使用せず、代わりにすべての Bourne スタイルのシェルで利用可能な機能を使用することです。
一般的に、ユーザーIDを決定するための組み込みシェル機能はありません。しかし、id
これはシェルの組み込みプログラムではなく外部プログラムですが、cat
そしてls
、それが存在すると予想するのは合理的です。
id
単独では大量の情報が出力されますが、id -u
有効なユーザー ID のみが提供されます。
したがってif [ "$UID" != "$ROOT_UID" ]
、 の代わりに、以下を使用できます。
if [ "$(id -u)" != "$ROOT_UID" ]
技術的には、これは同等ではありません。$UID
ではbash
実際のユーザー ID が提供され、実際には のid -u
に対応します。 EUID ではなく UID が必要な場合は、 を使用します。bash
$EUID
id -ru