Bash script: использование команды script "из Bash script для ведения журнала сеанса

Я пытаюсь использовать команду script для регистрации сеанса bash.

Команда script выполняется с помощью bash script, но как только она будет выполнена, завершается bash script.

Я попытался вызвать команду, используя различные комбинации, всегда с тем же результатом (завершение bash script, как только вызывается команда). Результат, который я получаю, следующий:

Script started, file is typescript
[email protected]: ...

Я также попытался вызвать команду с & в конце, но опять же без везения.

Может ли кто-нибудь сказать мне, как мне вызвать команду из bash script?

Спасибо

Ответ 1

Ваша оболочка script не завершилась. Он все еще работает. Вы получаете приглашение, потому что script создает новую оболочку.

Вариант использования для script:

  • start script (порождает новую оболочку)
  • выполнить команды
  • выйти из оболочки (выйти из системы) и перейти к предыдущей оболочке
  • проверить или распечатать файл журнала, созданный script

Итак, в основном script работает так, как ожидалось. Вам нужно будет найти другой способ достижения желаемого.

Вы можете выполнить запись вашего script следующим образом:

#! /bin/bash
exec > logfile 2>&1
set -x
FOO=BAR
echo $FOO

Пояснение:

  • exec > logfile 2>&1 перенаправляет stdout и stderr в файл журнала
  • set -x делает bash печатать каждую команду перед ее выполнением

Пример:

$ ./foo.sh
$ cat logfile 
+ FOO=BAR
+ echo BAR
BAR

Недостатком этого метода является то, что script не выводит данные для людей. Все идет в файл журнала.

В качестве альтернативы вы можете сделать это следующим образом:

#! /bin/bash
# nothing special here
FOO=BAR
echo $FOO

Затем выполните следующее:

$ script -c "bash -x foo.sh"
Script started, file is typescript
+ FOO=BAR
+ echo BAR
BAR
Script done, file is typescript
$ cat typescript 
Script started on Mi 18 Mai 2011 01:05:29 CEST
+ FOO=BAR
+ echo BAR
BAR

Script done on Mi 18 Mai 2011 01:05:29 CEST

Ответ 2

Ваш bash script все еще запущен, но он создал новую интерактивную оболочку. bash script ожидает завершения script, что произойдет только тогда, когда интерактивная оболочка будет завершена (либо убита, либо пользователем, набрав exit).

Чтобы сделать команду после script занесенной в журнал script, выполните следующие действия:

script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'

Однако script перестанет работать после выполнения этой команды.

Чтобы запустить несколько команд внутри script, поместите эти команды в другой bash script и укажите, что bash script в качестве команды для запуска с параметром -c.

Ответ 3

Следуя идее execve, вы также можете использовать переменную среды:

#!/bin/sh
[ -z "$TYPESCRIPT" ] && TYPESCRIPT=1 exec /usr/bin/script -c "TYPESCRIPT=1 $0 [email protected]"
# your script here...

Ответ 4

Вы можете использовать трюк в своей оболочке script для запуска script или не запускать его. Основываясь на специальном аргументе, он может выбрать выполнение со специальным аргументом, чтобы script не запускался снова.

Это, скорее всего, объяснит, что я имею в виду:

if [ "$1" != "noscript" ] ; then
        # execute self with the noscript special arg so that the second execution DOES NOT start script again.
        exec script -q -c "$0 noscript $1 $2 $3" /build/buildlog_`date '+%Y%m%d%H%M%S'`.log
        echo Problem in $0, please check.
        exit 1;
fi 
...Rest of the script should follow here.

Я пробовал это, и он работает хорошо. Если вы не особо относитесь к тем аргументам, которые необходимо передать, а также к script планируется использовать враждебными пользователями, этого должно быть достаточно:).

Ответ 5

Ответ на

juj велик, но не удается правильно передать аргументы. Основная проблема заключается в использовании [email protected] внутри строки с двумя кавычками. $* следует использовать вместо:

#!/bin/sh
[ -z "$TYPESCRIPT" ] && TYPESCRIPT=1 exec /usr/bin/script -c "TYPESCRIPT=1  $0 $*"
# your script here...

Вот что происходит с [email protected]:

foo.sh:

#!/bin/sh
if [ -z $FOO ]
then
    FOO=1 exec $0 [email protected]
else
    ./echo_args.sh "$0 [email protected]"
fi

bar.sh:

#!/bin/sh
echo 0 $0
echo 1 $1
echo 2 $2
echo 3 $3

Теперь ./foo.sh with some arguments выводит

0 ./bar.sh
1 /path/to/foo.sh with
2 some
3 arguments

Это приведет к тому, что некоторые аргументы будут переданы в script вместо второго выполнения foo.sh.