Как знать, находитесь ли Вы в машинописном тексте?

Вы являетесь передающими \b$2\b кому: grep буквально из-за одинарных кавычек. Позволить $2 для расширения до значения аргумента использовать "$2". Кроме того, заключение в кавычки между одинарными левыми кавычками может стать хитрым; использовать $(…), который имеет то же значение как `…` (замена команды), но ведет себя нормально относительно заключения в кавычки.

if [ $(grep -c -e "\b$2\b" /etc/group) -eq 0 ]; then …

Затем, подсчет соответствий является чрезмерно сложным: можно использовать grepстатус возврата, чтобы знать, были ли соответствия. Передайте -q опция сказать grep то, что Вы не интересуетесь никаким выводом, просто статус возврата.

if ! grep -q -e "\b$2\b" /etc/group; then …

Затем, Ваш поиск является неправильным. Вы ищете слово $2, но это могло соответствовать имени пользователя или части названия группы, которое содержит знак пунктуации или несколько более экзотических несоответствий. Название группы является первым разграниченным двоеточием полем, так поиск этого.

if ! grep -q -e "^$2:" /etc/group; then …

Обратите внимание, что Вы, возможно, должны санировать вход: $2 не должен содержать символ, для которого это является особенным grep или это - разделитель группы.

case $2 in
  *[][\.*^$]*) echo "Unsupported character in the group name";;
esac
if ! grep -q -e "^$2:" /etc/group; then …

Наконец, grep /etc/group не правильный инструмент здесь, если можно избежать его. Можно только найти локальные названия группы тем путем, не группами, происходящими из NIS или LDAP или необычных установок. Большинство современных нельдов (по крайней мере, Солярис, Linux и *BSD) имеет a getent команда для получения записей от системных баз данных включая базу данных группы.

if ! getent group "$2" >/dev/null; then …

(Для пользователей, вместо заглядывания /etc/passwd, использовать getent passwd, или более портативно звоните id.)

10
20.03.2013, 17:37
4 ответа

Возможно, с:

if lsof -tac script "$(tty)" > /dev/null; then
  echo "I'm running under script"
else
  echo "I'm not"
fi

Вы могли добавить что-то как:

lsof -tac script "$(tty)" > /dev/null && PS1="[script] $PS1"

К Вашему ~/.zshrc или ~/.bashrc, так информация о том, являетесь ли Вы в script или не было бы видимо на Вашем приглашении оболочки.

С другой стороны, если Вы не можете гарантировать это lsof будьте установлены Вы могли сделать (принятие неизмененной IFS):

terminal=$(ps -o comm= -p $(ps -o ppid= -p $(ps -o sid= -p "$$")))
[ "$terminal" = script ] && PS1="[script] $PS1"

Эвристика должна получить название команды родителя лидера сессии, который обычно был бы эмулятором терминала (xterm, script, screen...).

7
27.01.2020, 20:02
  • 1
    @teikakazura, эвристическая часть была то, потому что Вам не гарантируют это, это будет родительский процесс лидера сессии. Ничто, чтобы сделать с изодромным с предварением повторным использованием здесь как Ваш лидер сессии и ее родитель обычно все еще не будет вокруг при выполнении той команды. Вы могли сказать, что первый является эвристикой, а также мы просто проверяем имя процесса. Любая команда, имя которой также script и имеет открытый tty, также вызвал бы положительную ложь. –  Stéphane Chazelas 23.02.2017, 09:28
  • 2
    @teikakazura приблизительно (2), которые проверили бы ppid текущей оболочки. Здесь, Вы хотите проверить ppid лидера сессии (обычно, который был бы оболочкой это script запущенный). –  Stéphane Chazelas 23.02.2017, 09:28

Интересная проблема. Я нашел, что маленький сценарий удара мог сделать задание довольно надежно:

#!/bin/bash

PP=$(ps -o ppid= $$)

while [[ $PP != 1 ]]
do
    LINE=$(ps -o ppid= -o comm= $PP | sed 's/^  *//')
    COMM=${LINE#* }
    PP=${LINE%% *}
    if [[ $COMM == script ]]  # Might need a different comparison
    then
        echo "In script"
        exit 0
    fi
done
echo "Not in script"

Я думаю, что это немного отличается, чем предложенный Stephane Chazelas, в котором мой сценарий прокладывает себе путь parent:child отношения, которые имеют процессы Linux/Unix, пока это не находит PID 1, или это находит "сценарий" как процесс.

5
27.01.2020, 20:02
  • 1
    Интересный подход. Однако обратите внимание на это, если, например, Вы запускаете xterm от Вашей сессии сценария тот сценарий будет вещь оболочка, в которой xterm работает в соответствии со сценарием. Хорошо это в некотором смысле, но вывод не идет в машинописный текст. Мой подход проверяет, что терминал, связанный с текущей сессией так, не имел бы той проблемы. спасибо –  Stéphane Chazelas 20.03.2013, 20:34

Если на вашем пути есть личный каталог bin / (например, / home / user / bin, поместите туда сценарий оболочки с назовите 'script' (то же имя, что и двоичный файл) со следующим содержанием:

#!/bin/bash
export SCRIPT_RUNNING=1
exec /usr/bin/script # full path to your script(1) binary

Теперь, в рамках запущенного сценария, вы можете проверить переменную среды SCRIPT_RUNNING и сделать на ее основе все, что захотите.

EDIT:

На самом деле, есть гораздо более простой способ. Ниже все сказано: создайте три файла, ~ / bin / script, ~ / bin / script-shell и ~ / .scriptrc:

~ > ls ~/bin/script ~/bin/script-shell ~/.scriptrc
-rw-r--r-- 1 roadowl users 23 Oct 18 16:52 /home/roadowl/.scriptrc
-rwx------ 1 roadowl users 49 Oct 18 16:53 /home/roadowl/bin/script
-rwx------ 1 roadowl users 56 Oct 18 16:55 /home/roadowl/bin/script-shell

~/bin > cat script
#!/bin/bash
exec /usr/bin/script -c script-shell

~/bin > cat script-shell
#!/bin/bash
exec /bin/bash --rcfile /home/bjd/.scriptrc

~/bin > cat ~/.scriptrc
export PS1="[script] "

Если ваша текущая оболочка - bash, не используйте Не забудьте запустить hash -r после создания этих файлов, чтобы гарантировать запуск ~ / bin / script при вводе 'script' в качестве команды (проверьте с помощью , какой сценарий ).

Как и раньше, обратите внимание, что у вас должен быть ~ / bin в вашем PATH перед стандартным путем, чтобы это работало.

0
27.01.2020, 20:02

TL;DR

В большинстве случаев на локальном хосте лучше всего проверить переменную окружения SCRIPT или наличие ожидаемого выходного файла. Однако есть ряд случаев использования, когда вам придется явно установить переменную или семафор (либо локально, либо на удаленном компьютере ), пометить свое окно (, например. в экране GNU или tmux )или на вкладке вашего терминала, или придумайте какое-либо другое решение, которое не полагается на неявное поведение или поведение по умолчанию, которое может не применяться в вашей конкретной ситуации.

Ниже я привожу несколько примеров того, как проверить переменную SCRIPT в BSD и Linux. Я также предлагаю некоторые предостережения, включая ограничения этого подхода при подключении к удаленному хосту через SSH.

BSD :Проверка СЦЕНАРИЙ Переменная среды

В системах, использующих версии BSD script, вы можете проверить наличие переменной окружения SCRIPT . Сценарий BSD (1 )говорит:

The SCRIPT environment variable is added to the sub-shell. If SCRIPT already existed in the users environment, its value

Например, учитывая:

SHELL=/bin/sh script logfile.log
# script exports SCRIPT to sub-shells, so you can test if
# it's non-empty
[ -n "$SCRIPT" ] && echo "in typescript"

# SCRIPT holds the name of the typescript file you specified,
# or "typescript" by default; his enables you to check if
# you're in a *specific* typescript
[ "$SCRIPT" = "logfile.log" ] || [ "$SCRIPT" = "typescript" ]

# returns name of typescript file or an error message
echo "${SCRIPT?not in typescript}"

# exit status 0 in typescript; show error message and return
# exit status 1 outside the typescript
: "${SCRIPT?not in typescript}"

# this is less reliable, but can be useful in some cases;
# true if in a sub-shell, although there are no guarantees
# the sub-shell was spawned by script
[ "$SHLVL" -gt "1" ]

Linux :Экспорт собственной переменной SCRIPT

Версия, поставляемая с утилитой -linux 2.23.2 (, которая у меня есть под рукой ), не экспортирует переменную SCRIPT по умолчанию. Вы можете просто экспортировать свои собственные, любым способом, которым вы это делаете со своей оболочкой. В снарядах типа Баша:

SCRIPT='typescript' script

Затем вы можете выполнить те же тесты, что и выше.

Предостережения

Команда scriptпозволяет указать команду для запуска, а не просто запускать оболочку. Итак, если ваша команда очищает среду (, например. env -i printenv), сбрасывает вашу переменную SCRIPT или находится в удаленной системе (, например. вход через SSH ), затем СЦЕНАРИЙ не будет распространяться.

Если вы используете SSH, вы можете изучить его распространение с помощью SendEnv или SetEnv на стороне клиента,и AcceptEnv на стороне сервера, но я бы не стал на него полагаться, так как это нетипичное значение по умолчанию для большинства систем. Вы также можете установить PermitLocalCommand на сервере и получить доступ к вашей локальной среде с помощью~C и !echo $SCRIPT, но опять же, я бы не стал полагаться на это, если вы не управляете сервером.

0
03.03.2021, 21:01

Теги

Похожие вопросы