Ответ 1
Я думаю, что Сэм хочет сделать, может быть невозможно.
В какой степени возможно обходное решение с половинным баком, зависит от...
- ... оболочка пользователей по умолчанию и
- ... какие альтернативные оболочки им разрешено использовать.
Если я правильно понимаю требования Сэма, он хочет иметь "script",
myscript
, то есть...
- ... не напрямую исполняемый файл, вызвав его именем
myscript
(т.е. имеетchmod a-x
); - ... не косвенно исполняемый для пользователей путем вызова
sh myscript
или вызовbash myscript
- ... только работает с его содержащимися функциями и командами, если их вызывает
sourcing it:
. myscript
Первыми вещами, которые следует учитывать, являются эти
- При вызове script непосредственно по его имени (
myscript
) требуется первая строка в script как#!/bin/bash
или аналогичный. Это напрямую определит, какие установленный экземпляр исполняемого файла bash (или символьной ссылки) будет вызываться для запуска script. Это будет новый процесс оболочки. Это требует сам скриптовый файл для установки установленного флага. - Запуск script путем вызова двоичного файла оболочки с именем script (путь +) как
аргумент (
sh myscript
), тот же, что и "1". - , за исключением того, что флажок исполняемого файла не нужно устанавливать, а первая строка - hashbang не требуется либо. Единственное, что нужно, это то, что вызов пользователю нужен доступ для чтения к файлу сценария. - Вызов script путем поиска его имени файла (
. myscript
) - это очень то же самое, что и "1." - кроме того, что это не новая оболочка, которая вызывается. Все Команды script выполняются в текущей оболочке, используя ее среду (а также "загрязнение" его среды любыми (новыми) переменными, которые он может установить или изменение. (Обычно это очень опасная вещь: но здесь это может быть используется для выполненияexit $RETURNVALUE
при определенных условиях....)
Для "1.":
Легкость в достижении: chmod a-x myscript
предотвратит myscript
от
непосредственно исполняемый файл. Но это не выполнит требования "2." и "3." .
Для '2.' и "3." :
Гораздо труднее достичь. Invokations от sh myscript
требуют чтения
привилегии для файла. Таким образом, очевидный выход может показаться chmod a-r
myscript
. Однако это также не разрешит "3." : вы не сможете
введите script.
Как насчет написания script таким образом, который использует башизм? Башизм - это
конкретный способ сделать то, что другие оболочки не понимают: используя
конкретные переменные, команды и т.д. Это можно использовать внутри script для
откройте это условие и "сделайте что-нибудь" (например, "display warning.txt",
"mailto admin" и т.д.). Но в аду нет способа, чтобы это предотвратило sh
или
bash
или любая другая оболочка от чтения и пытается выполнить все следующие
команды/строки, записанные в script, если вы не убили оболочку, вызвав
exit
.
Примеры: в Bash среда, видимая script, знает $BASH
,
$BASH_ARGV
, $BASH_COMMAND
, $BASH_SUBSHELL
, BASH_EXECUTION_STRING
.... Если
вызывается sh
(также если источник внутри sh
), исполняющая оболочка увидит
все эти $BASH_*
как пустые переменные среды. Опять же, это можно было бы использовать
внутри script, чтобы обнаружить это условие и "сделать что-то"... но не
запретить выполнение следующих команд!
Теперь я предполагаю, что...
- ... script использует
#!/bin/bash
в качестве первой строки, - ... пользователи установили bash в качестве своей оболочки и вызывают команды в следующая таблица из bash, и это их оболочка входа,
- ...
sh
доступен, и это символическая ссылка наbash
илиdash
.
Это означает, что возможны следующие вызовы, при этом перечисленные значения для переменных среды
vars+invok | ./scriptname | sh scriptname | bash scriptname | . scriptname ---------------+--------------+---------------+-----------------+------------- $0 | ./scriptname | ./scriptname | ./scriptname | -bash $SHLVL | 2 | 1 | 2 | 1 $SHELLOPTS | braceexpand: | (empty) | braceexpand:.. | braceexpand: $BASH | /bin/bash | (empty) | /bin/bash | /bin/bash $BASH_ARGV | (empty) | (empty) | (empty) | scriptname $BASH_SUBSHELL | 0 | (empty) | 0 | 0 $SHELL | /bin/bash | /bin/bash | /bin/bash | /bin/bash $OPTARG | (empty) | (empty) | (emtpy) | (emtpy)
Теперь вы можете поместить логику в свой текст script:
- Если
$0
не равно-bash
, тогда выполнитеexit $SOMERETURNVALUE
.
В случае, если script был вызван через sh myscript
или bash myscript
, тогда он будет
выйдите из вызывающей оболочки. В случае, если он был запущен в текущей оболочке, он будет
продолжать работать. (Предупреждение: в случае, если script имеет любые другие операторы exit
ваша текущая оболочка будет "убита"...)
Итак, введите в свой неисполняемый myscript.txt
в начале своего начала что-то вроде
это может сделать что-то близкое к вашей цели:
echo BASH=$BASH
test x${BASH} = x/bin/bash && echo "$? : FINE.... You're using 'bash ...'"
test x${BASH} = x/bin/bash || echo "$? : RATS !!! -- You're not using BASH and I will kick you out!"
test x${BASH} = x/bin/bash || exit 42
test x"${0}" = x"-bash" && echo "$? : FINE.... You've sourced me, and I'm your login shell."
test x"${0}" = x"-bash" || echo "$? : RATS !!! -- You've not sourced me (or I'm not your bash login shell) and I will kick you out!"
test x"${0}" = x"-bash" || exit 33