Незначительные выпуски могут быть обновлены с yum
команда:
yum upgrade
Если Вы захотите использовать файлы на DVD, то необходимо будет определить другой локальный вкусный репозиторий в /etc/yum.repos.d/
(например, dvd.repo
):
[rhel-cd]
name=Red Hat Enterprise Linux $releasever - $basearch - CD
baseurl=file:///media/RHEL/Server/
enabled=1
gpgcheck=0
Займите место baseurl
с точкой монтирования DVD
Из [11671]man bash[11672] (выбрано исключительно потому, что это имеет лучшее описание, чем мой [11673]man sh[11674] - использование одинаково независимо):
-c
Если опция -c присутствует, то команды читаются из первой строки command_string аргумента без опции. Если после аргумента command_string есть аргументы, то они следующие назначенные позиционным параметрам, начиная с $0.
:help :botright
:help :saveas
:help :split
ПРИМЕЧАНИЕ: Другие уже объяснили механику $ 0
, поэтому я пропущу все это.
Я обычно обхожу эту проблему в сторону и просто использую команду readlink -f $ 0
. Это всегда будет возвращать вам полный путь того, что вы дадите ему в качестве аргумента.
Скажем, я здесь, чтобы начать с:
$ pwd
/home/saml/tst/119929/adir
Создайте каталог + файл:
$ mkdir adir
$ touch afile
$ cd adir/
Теперь начните показывать ссылку для чтения
:
$ readlink -f ../adir
/home/saml/tst/119929/adir
$ readlink -f ../
/home/saml/tst/119929
$ readlink -f ../afile
/home/saml/tst/119929/afile
$ readlink -f .
/home/saml/tst/119929/adir
Теперь с согласованный результат, возвращаемый, когда мы запрашиваем $ 0
через readlink
, мы можем использовать просто dirname $ (readlink -f $ 0)
, чтобы получить абсолютный путь к скрипту -или- basename $ (readlink -f $ 0)
, чтобы получить фактическое имя сценария.
На моей странице man
написано:
$0
: расширяется доимени
shell
илиshell script
.
Похоже, это переводится как argv[0]
текущей оболочки - или первый неоперанд аргумент командной строки, который интерпретируемая в данный момент оболочка получает при вызове. Ранее я утверждал, что sh ./somescript
передаст свою $0 $ENV
переменную в sh
но это было неверно, поскольку shell
является новым процессом и вызывается с новым $ENV
.
Таким образом sh ./somescript.sh
отличается от . ./somescript.sh
который запускается в текущем окружении и $0
уже установлен.
Вы можете проверить это, сравнив $0
с /proc/$$/status
.
echo 'script="/proc/$$/status"
echo $0
cat "$script"' \
> ./script.sh
sh ./script.sh ; . ./script.sh
Спасибо за исправление, @toxalot. Я кое-чему научился.
Вот две ситуации, когда каталог не будет включен:
> bash scriptname
scriptname
> bash <scriptname
bash
В обоих случаях текущим каталогом должен быть каталог, в котором находится scriptname.
В первом случае значение $0
все равно может быть передано в grep
, поскольку он предполагает, что аргумент FILE относится к текущему каталогу.
Во втором случае, если справка и информация о версии печатается только в ответ на определенную опцию командной строки, это не должно быть проблемой. Я не уверен, зачем кому-то вызывать сценарий таким образом для печати справки или информации о версии.
Предостережения
Если сценарий изменяет текущий каталог, вы не захотите использовать относительные пути.
Если сценарий является исходным, значение $0
обычно будет вызывающим сценарием, а не исходным.
Для чего-то подобного я использую:
rPath="$(dirname $(realpath $0))"
echo $rPath
rPath=$(dirname $(readlink -e -- "$0"))
echo $rPath
rPath
всегда имеет одно и то же значение.
В наиболее распространенных случаях $ 0
будет содержать путь, абсолютный или относительный к сценарию, поэтому
script_path=$(readlink -e -- "$0")
( при условии, что есть команда readlink
и она поддерживает -e
), как правило, это достаточно хороший способ получить канонический абсолютный путь к сценарию.
$ 0
назначается из аргумента, определяющего сценарий, переданный интерпретатору.
Например, в:
the-shell -shell-options the/script its args
$ 0
получает сценарий /
.
Когда вы запустите:
the/script its args
Ваша оболочка выполнит:
exec("the/script", ["the/script", "its", "args"])
Если сценарий содержит #! / bin / sh -
she-bang, например, система преобразует это в:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "the/script", "its", "args"])
(если он не содержит she-bang, или, в более общем смысле, если система возвращает ошибку ENOEXEC, то это ваш оболочка, которая будет делать то же самое)
В некоторых системах есть исключение для сценариев setuid / setgid, когда система открывает сценарий на некотором fd
x
и запускает вместо этого:
exec("/bin/sh", ["/bin/sh" or "the/script", "-", "/dev/fd/x", "its", "args"])
чтобы избежать состояния гонки (в этом случае $ 0
будет содержать / dev / fd / x
).
Теперь вы можете возразить, что / dev / fd / x
- это путь к этому сценарию. Однако обратите внимание, что если вы читаете из $ 0
, вы сломаете скрипт по мере использования ввода.
Теперь есть разница, если имя вызываемой команды сценария не содержит косой черты. В:
the-script its args
Ваша оболочка будет искать скрипт
в $ PATH
. $ PATH
может содержать абсолютные или относительные (включая пустую строку) пути к некоторым каталогам. Например, если $ PATH
содержит / bin: / usr / bin:
и сценарий
находится в текущем каталоге, оболочка выполнит следующее:
exec("the-script", ["the-script", "its", "args"])
, который станет:
exec("/bin/sh", ["/bin/sh" or "the-script", "-", "the-script", "its", "args"]
Или, если он найден в / usr / bin
:
exec("/usr/bin/the-script", ["the-script", "its", "args"])
exec("/bin/sh", ["/bin/sh" or "the-script" or "/usr/bin/the-script",
"-", "/usr/bin/the-script", "its", "args")
Во всех вышеупомянутых случаях, кроме углового случая setuid, $ 0
будет содержать путь (абсолютный или относительный) к скрипту.
Теперь сценарий также может называться:
the-interpreter the-script its args
Когда сценарий
, как указано выше, не содержит символов косой черты, поведение немного отличается от оболочки к оболочке.
Старые реализации AT&T ksh
фактически безоговорочно искали сценарий в $ PATH
(что на самом деле было ошибкой и дырой в безопасности для сценариев setuid), поэтому $ 0
на самом деле не содержал путь к сценарию, если только поиск $ PATH
действительно не нашел the-script
в текущем каталоге.
Более новый AT&T ksh
будет пытаться интерпретировать сценарий
в текущем каталоге, если он доступен для чтения. В противном случае он будет искать читаемый и исполняемый скрипт
в $ PATH
.
Для bash
он проверяет, находится ли the-script
в текущем каталоге (и не является ли неработающая символическая ссылка), и если нет, ищет читаемый (не обязательно исполняемый) сценарий
в $ PATH
.
zsh
в эмуляция sh
будет работать так же, как bash
, за исключением того, что если the-script
является неработающей символической ссылкой в текущем каталоге, она не будет найдите сценарий
в $ PATH
и вместо этого сообщит об ошибке.
Все другие оболочки, подобные Борну, не ищут скрипт
в $ PATH
.
В любом случае, для всех этих оболочек, если вы обнаружите, что $ 0
не содержит /
и не читается, то, вероятно, он был найден в $ PATH
.Затем, поскольку файлы в $ PATH
, вероятно, будут исполняемыми, вероятно, будет безопасным приближением использовать команду -v - "$ 0"
, чтобы найти его путь (хотя это не работают, если $ 0
также является именем встроенной оболочки или ключевым словом (в большинстве оболочек)).
Итак, если вы действительно хотите прикрыть этот случай, вы можете написать его:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}""; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
( ""
, добавленный к $ PATH
, чтобы сохранить конечный пустой элемент с оболочки, у которых $ IFS
действует как разделитель вместо разделителя ).
Теперь,есть более эзотерические способы вызвать сценарий. Можно сделать:
the-shell < the-script
Или:
cat the-script | the-shell
В этом случае $ 0
будет первым аргументом ( argv [0]
), который получил интерпретатор (выше the-shell
, но это может быть что угодно, хотя обычно это либо базовое имя, либо один путь к этому интерпретатору).
Определение того, что вы находитесь в такой ситуации, по значению $ 0
ненадежно. Вы можете посмотреть на вывод ps -o args = -p "$$"
, чтобы получить подсказку. В случае с конвейером нет реального способа вернуться к пути к скрипту.
Можно также сделать:
the-shell -c '. the-script' blah blih
Тогда, за исключением zsh
(и некоторой старой реализации оболочки Bourne), $ 0
будет бла
. Опять же, трудно найти путь к сценарию в этих оболочках.
Или:
the-shell -c "$(cat the-script)" blah blih
и т. Д.
Чтобы убедиться, что у вас есть правильное $ progname
, вы можете искать в нем конкретную строку, например:
progname=$0
[ -r "$progname" ] || progname=$(
IFS=:; set -f
for i in ${PATH-$(getconf PATH)}:; do
case $i in
"") p=$progname;;
*/) p=$i$progname;;
*) p=$i/$progname
esac
[ -r "$p" ] && exec printf '%s\n' "$p"
done
exit 1
) && progname=$(readlink -e -- "$progname") ||
progname=unknown
[ -f "$progname" ] && grep -q 7YQLVVD3UIUDTA32LSE8U9UOHH < "$progname" ||
progname=unknown
Но опять же, я не думаю, что это того стоит.
Я хочу grep текущего скрипта, чтобы я мог распечатать справку и версию информация из раздела комментариев вверху.
Хотя $ 0
содержит имя сценария, он может содержать путь с префиксом в зависимости от способа вызова сценария, я всегда использовал $ {0 ## * /}
для печати имя сценария в выводе справки, которое удаляет любой начальный путь из $ 0
.
Взято из Advanced Bash Scripting guide - Раздел 10.2. Подстановка параметров
$ {var # Pattern}
Удаление из
$ var
самой короткой части$ Pattern
, который соответствует внешнему интерфейсу$ var
.
$ {var ## Pattern}
Удалите из
$ var
самую длинную часть$ Pattern
, которая соответствует передней части$ var
.
Таким образом, самая длинная часть $ 0
, которая соответствует * /
, будет префиксом всего пути, возвращающим только имя сценария.