Вы можете использовать EasyMock.make ThreadSafe, чтобы убедиться, что поток экземпляров экземпляра безопасен
Используйте "мишень" для перенаправления в файл и экран. В зависимости от оболочки Вы используете, сначала необходимо перенаправить stderr к stdout использование
./a.out 2>&1 | tee output
или
./a.out |& tee output
В csh, существует встроенная команда, названная "сценарием", который получит все, что переходит к экрану в файл. Вы запускаете его путем ввода "сценария", затем выполнения независимо от того, что это - Вы, хотят получить, затем поразить управление-D для закрытия файла сценария. Я не знаю об эквиваленте для sh/bash/ksh.
кроме того, так как Вы теперь указали, что это Ваши собственные sh сценарии, которые можно изменить, можно сделать перенаправление внутренне путем окружения целого сценария фигурными скобками или скобками, как
#!/bin/sh
{
... whatever you had in your script before
} 2>&1 | tee output.file
для перенаправления stderr к stdout добавляют это при команде: 2>&1
Для вывода к терминалу и вхождения в файл необходимо использовать tee
, Оба вместе были бы похожи на это:
mycommand 2>&1 | tee mylogfile.log
РЕДАКТИРОВАНИЕ: Для встраивания в Ваш сценарий Вы сделали бы то же. Таким образом, Ваш сценарий
#!/bin/sh
whatever1
whatever2
...
whatever3
закончился бы как
#!/bin/sh
( whatever1
whatever2
...
whatever3 ) 2>&1 | tee mylogfile.log
Используйте программу мишени и копируйте stderr к stdout.
program 2>&1 | tee > logfile
Я создал сценарий по имени "RunScript.sh". Содержание этого сценария:
${APP_HOME}/${1}.sh ${2} ${3} ${4} ${5} ${6} 2>&1 | tee -a ${APP_HOME}/${1}.log
я называю его как это:
./RunScript.sh ScriptToRun Param1 Param2 Param3 ...
Это работает, но это требует, чтобы сценарии приложения были выполнены с помощью внешнего сценария. Это немного топорно.
Используйте эти script
, команда в Вашем сценарии (человек 1 сценарий)
Создает сценарий оболочки обертки (2 строки), который настраивает сценарий () и затем называет выход.
Часть 1: часть 2 wrap.sh
#!/bin/sh
script -c './realscript.sh'
exit
: Результат realscript.sh
#!/bin/sh
echo 'Output'
:
~: sh wrap.sh
Script started, file is typescript
Output
Script done, file is typescript
~: cat typescript
Script started on fr. 12. des. 2008 kl. 18.07 +0100
Output
Script done on fr. 12. des. 2008 kl. 18.07 +0100
~:
Год спустя вот старый сценарий bash для регистрации чего угодно. Например,
teelog make ...
записывает в журнал сгенерированное имя (и посмотрите, как записать в журнал вложенные make
s).
#!/bin/bash
me=teelog
Version="2008-10-9 oct denis-bz"
Help() {
cat <<!
$me anycommand args ...
logs the output of "anycommand ..." as well as displaying it on the screen,
by running
anycommand args ... 2>&1 | tee `day`-command-args.log
That is, stdout and stderr go to both the screen, and to a log file.
(The Unix "tee" command is named after "T" pipe fittings, 1 in -> 2 out;
see http://en.wikipedia.org/wiki/Tee_(command) ).
The default log file name is made up from "command" and all the "args":
$me cmd -opt dir/file logs to `day`-cmd--opt-file.log .
To log to xx.log instead, either export log=xx.log or
$me log=xx.log cmd ...
If "logdir" is set, logs are put in that directory, which must exist.
An old xx.log is moved to /tmp/\$USER-xx.log .
The log file has a header like
# from: command args ...
# run: date pwd etc.
to show what was run; see "From" in this file.
Called as "Log" (ln -s $me Log), Log anycommand ... logs to a file:
command args ... > `day`-command-args.log
and tees stderr to both the log file and the terminal -- bash only.
Some commands that prompt for input from the console, such as a password,
don't prompt if they "| tee"; you can only type ahead, carefully.
To log all "make" s, including nested ones like
cd dir1; \$(MAKE)
cd dir2; \$(MAKE)
...
export MAKE="$me make"
!
# See also: output logging in screen(1).
exit 1
}
#-------------------------------------------------------------------------------
# bzutil.sh denisbz may2008 --
day() { # 30mar, 3mar
/bin/date +%e%h | tr '[A-Z]' '[a-z]' | tr -d ' '
}
edate() { # 19 May 2008 15:56
echo `/bin/date "+%e %h %Y %H:%M"`
}
From() { # header # from: $* # run: date pwd ...
case `uname` in Darwin )
mac=" mac `sw_vers -productVersion`"
esac
cut -c -200 <<!
${comment-#} from: $@
${comment-#} run: `edate` in $PWD `uname -n` $mac `arch`
!
# mac $PWD is pwd -L not -P real
}
# log name: day-args*.log, change this if you like --
logfilename() {
log=`day`
[[ $1 == "sudo" ]] && shift
for arg
do
log="$log-${arg##*/}" # basename
(( ${#log} >= 100 )) && break # max len 100
done
# no blanks etc in logfilename please, tr them to "-"
echo $logdir/` echo "$log".log | tr -C '.:+=[:alnum:]_\n' - `
}
#-------------------------------------------------------------------------------
case "$1" in
-v* | --v* )
echo "$0 version: $Version"
exit 1 ;;
"" | -* )
Help
esac
# scan log= etc --
while [[ $1 == [a-zA-Z_]*=* ]]; do
export "$1"
shift
done
: ${logdir=.}
[[ -w $logdir ]] || {
echo >&2 "error: $me: can't write in logdir $logdir"
exit 1
}
: ${log=` logfilename "$@" `}
[[ -f $log ]] &&
/bin/mv "$log" "/tmp/$USER-${log##*/}"
case ${0##*/} in # basename
log | Log ) # both to log, stderr to caller's stderr too --
{
From "$@"
"$@"
} > $log 2> >(tee /dev/stderr) # bash only
# see http://wooledge.org:8000/BashFAQ 47, stderr to a pipe
;;
* )
#-------------------------------------------------------------------------------
{
From "$@" # header: from ... date pwd etc.
"$@" 2>&1 # run the cmd with stderr and stdout both to the log
} | tee $log
# mac tee buffers stdout ?
esac