2011-05-12 186 views
15

我正在尝试使用script命令记录bash会话。Bash脚本:使用bash脚本中的“脚本”命令记录会话

script命令是使用bash脚本执行的,但一旦它执行,bash脚本就会终止。

我试图用不同的组合总是调用相同的结果(一旦命令被调用就终止bash脚本)。我得到的输出如下:

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

我也试图跟到底,但再没有运气的&调用命令。

任何人都可以告诉我如何从bash脚本调用命令吗?

感谢

+1

请向我们展示您的bash脚本,或者至少是'script'行。 – 2011-05-12 22:22:46

+0

从脚本提示做一个ps(无参数),这应该显示发生了什么。你为什么认为它不起作用?如果这是因为打字稿是“空的”,那么你正在遭受缓冲。 – cdarke 2011-05-13 13:05:53

+0

@Robin Green:你可以在这里找到我的脚本:[链接](http://pastebin.com/CuAyPfhM) – limp 2011-05-14 14:26:05

回答

16

你的shell脚本并没有终止。它仍在运行。您正在收到提示,因为script正在产生新的外壳。

的应用案例script是:

  1. 开始script(产生一个新的shell)
  2. 就命令
  3. 出口外壳(注销),并下降到以前的shell
  4. 检查或打印日志文件由script创建

所以基本上script按预期工作。你将不得不寻找另一种方式来实现你想要的。

,您可以登录你的脚本是这样执行:

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

说明:

  • exec > logfile 2>&1重定向输出和错误记录到logfile
  • set -x使得bash的打印执行它
  • 之前的每一个命令

考试ple:

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

此方法的缺点是脚本不打印输出供人看。一切都进入日志文件。

或者你可以做这样的:

#! /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 
+0

使用BSD脚本命令(MacOS X),你不会使用'-c'参数或引号命令。这将是'script bash -x foo.sh' – 2018-02-16 22:21:14

5

你的bash脚本仍在运行,但它也催生了新的交互的shell。bash脚本正在等待script完成,这只会在交互式shell被终止时(通过被杀死或者由用户键入exit)发生。

为了使命令后scriptscript记录,像这样做:

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

然而,script将停止运行命令后运行。

要在script中运行多个命令,请将这些命令放在另一个bash脚本中,并将该bash脚本指定为要运行到-c选项的命令。

+0

谢谢!这完全是我在找的东西。我做了很多make x,make y等,并在命令行中单独编写脚本。我最终使用了一个.sh文件,并为我的每个make命令调用了'script results1.txt -c“make x”'。很有用! – redhotspike 2013-03-12 19:51:35

+0

使用BSD脚本命令(MacOS X),您不需要命令周围的“-c”参数或引号。它将会是'script build_log echo'*这行应该出现在“build_log”日志文件中......“ – 2018-02-16 22:15:59

2

您可以在shell脚本中使用一个技巧来启动脚本或不启动它。基于一个特殊的参数,它可以选择使用一个特殊的参数来执行它,以便脚本不会再次启动。

这应该最有可能的解释我的意思:

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. 

我已经试过这一点,它工作得很好。除非你特别关注那些需要传递的参数以及脚本计划被恶意用户使用,否则这应该就足够了:)。

3

以下的execve的想法,你也可以使用一个环境变量:

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

朱杰的答案是伟大的,但不能正确地传递参数。基本问题是在双引号字符串中使用[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第二次执行。