Таким образом, я получил этот сценарий от этого руководства: 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 [ "$UID" -ne "$ROOT_UID" ]
но я получал Недопустимую ошибку числа, потому что, по-видимому-ne только используется для строки, таким образом, я изменил его на! =.
Вместо того, чтобы выполнить его с
sh script.sh
выполните его с
bash script.sh
(или добавить #!/bin/bash
как первая строка, которая установит интерпретатор).
sh
оболочка в Ubuntu не bash
, но отдельная названная оболочка dash
. dash
не имеет стольких же функций сколько bash
, который делает это более эффективным, но эти недостающие возможности иногда повреждают сценарии, предназначенные для bash
. Одна такая функция $UID
переменная, которая не определяется в dash
.
Это означает это, когда сценарий выполняется в dash
, сравнение станет ["" != "0"]
, который оценивает к истинному, какой пользователь выполняет его. Однако, если это выполняется в bash
с корневыми полномочиями строки будут равны, и сценарий будет работать.
Поскольку McLovin говорит, автоматически набор, только для чтения UID
(и EUID
) переменная является специальной функцией bash
(и некоторые другие оболочки). Это не стандартно для оболочек стиля Границы и sh
как может предполагаться, не устанавливает эти переменные. В частности, sh
в Ubuntu (в настоящее время, по умолчанию) dash
, который не устанавливает их.
У Вас есть две опции:
bash
вместо sh
.bash
.bash
Вы не сказали нам название своего сценария (который является хорошо). Я собираюсь назвать его cleanup
, поскольку это - название подобного сценария в руководстве, Вы работаете от.
Обратите внимание в особенности, что я не называю его чем-то как cleanup.sh
. Это вызвано тем, что я не рекомендую назвать его с a .sh
суффикс:
.sh
суффикс предполагает, что это совместимо с sh
!.sh
или .bash
суффикс может даже быть интерпретирован, поскольку предложение Вашего файла является "библиотекой", а не "высокоуровневым" сценарием. Таким образом, то, что это предоставляет код, который будет получен другими сценариями (например, с .
встроенный), а не на самом деле выполненный непосредственно.Однако включая a .sh
суффикс не будет влиять на техническое поведение Вашего сценария всегда. Нет никакого технического преимущества или недостатка, связанного с выполнением так.
Добавьте hashbang строку как самую первую строку Вашего сценария: #!/bin/bash
Сделайте свой исполняемый файл сценария с chmod +x cleanup
.
Теперь можно запустить скрипт путем выполнения команды:
./cleanup
, когда это находится в текущем каталоге. (Особенно при сценариях для образования, исследования, тестирования, забавы или другого ограниченного или одноразового использования, это - возможно, наиболее распространенный способ.)
/path/to/cleanup
, в целом. Если первая команда содержит a /
это интерпретируется как путь к исполняемому файлу. (Это - причина вышеупомянутого ./
синтаксис, как .
означает текущий каталог.)
Первым словом я имею в виду команду до, но не включая ее первое незавершенное пространство или вкладку:
foo-bar/baz
первое слово foo-bar/baz qux
, в то время как spam\ ham
первое слово spam\ ham eggs
потому что пространство прежде ham
оставлен с обратной косой чертой.
cleanup
, если это находится в каталоге в Вашем PATH
(и никакой каталог не перечислил, сначала имеет исполняемый файл того же имени, и оно не заменяется встроенной оболочкой, функция или псевдоним).
Независимо от действительно ли сценарий cleanup
имеет a #!...
строка hashbang или что говорит та строка:
sh cleanup
будет все еще (попытаться к), выполняет его с sh
как интерпретатор.bash cleanup
будет все еще (попытаться к), выполняет его с bash
как интерпретатор.Это вызвано тем, что в тех случаях Вы на самом деле выполняете интерпретатор (sh
или bash
) и передача названия сценария к интерпретатору, чтобы быть выполненным. Много программ принимают, что названия файлов открываются на командной строке и оболочках как sh
и bash
следуйте этой конвенции.
Если Вы хотите сделать свой сценарий портативным, самый простой путь не состоит в том, чтобы использовать $UID
вообще, и вместо этого используйте некоторое средство, доступное всем оболочкам стиля Границы.
В целом нет никакого встроенного средства оболочки для определения идентификатора пользователя. Но можно использовать id
. Это - внешняя программа, а не встроенная оболочка, но как cat
и ls
, разумно ожидать, что это будет присутствовать.
id
отдельно производит набор информации, но id -u
дает просто эффективный идентификатор пользователя.
Таким образом вместо if [ "$UID" != "$ROOT_UID" ]
, можно использовать:
if [ "$(id -u)" != "$ROOT_UID" ]
Технически, это не эквивалентно. $UID
в bash
дает идентификатор реального пользователя, и id -u
действительно соответствует bash
$EUID
. Если Вы действительно хотите UID а не EUID, использовать id -ru
.