Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Bash脚本:使用;脚本“;来自bash脚本的用于记录会话的命令_Linux_Bash - Fatal编程技术网

Linux Bash脚本:使用;脚本“;来自bash脚本的用于记录会话的命令

Linux Bash脚本:使用;脚本“;来自bash脚本的用于记录会话的命令,linux,bash,Linux,Bash,我正在尝试使用script命令记录bash会话 script命令从使用bash脚本开始执行,但一旦执行,bash脚本就会终止 我尝试使用各种组合调用该命令,但结果总是一样的(调用该命令后立即终止bash脚本)。我得到的输出如下: Script started, file is typescript root@ubuntu: ... 最后,我还尝试使用&调用该命令,但同样没有成功 有人能告诉我如何从bash脚本调用该命令吗 谢谢您的shell脚本没有终止。它还在运行。您将收到一个提示,因为scr

我正在尝试使用
script
命令记录bash会话

script
命令从使用bash脚本开始执行,但一旦执行,bash脚本就会终止

我尝试使用各种组合调用该命令,但结果总是一样的(调用该命令后立即终止bash脚本)。我得到的输出如下:

Script started, file is typescript
root@ubuntu: ...
最后,我还尝试使用
&
调用该命令,但同样没有成功

有人能告诉我如何从bash脚本调用该命令吗


谢谢

您的shell脚本没有终止。它还在运行。您将收到一个提示,因为
script
正在生成一个新的shell。您看到的提示是来自生成的shell的提示

script
的正常用例如下所示:

#! /bin/bash
exec > logfile 2>&1
set -x
FOO=BAR
echo $FOO
#! /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
script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'
  • 启动
    脚本
    。这会产生一个新的外壳
  • 在新shell中执行命令
  • 退出shell并放到上一个shell
  • 检查由
    脚本创建的日志文件
  • 所以基本上
    script
    是按预期工作的。你必须找到另一种方法来实现你想要的

    您可以如下方式记录脚本的执行:

    #! /bin/bash
    exec > logfile 2>&1
    set -x
    FOO=BAR
    echo $FOO
    
    #! /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
    
    script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'
    
    说明:

    • exec>logfile2>&1
      将stdout和stderr重定向到日志文件
    • set-x
      使bash在执行命令之前打印每个命令
    例如:

    $ ./foo.sh
      # (no output here because everything goes to logfile)
    $ cat logfile 
    + FOO=BAR
    + echo BAR
    BAR
    
    这种方法的缺点是脚本不会打印任何输出供人查看。所有内容都会记录到日志文件中

    或者,您可以这样做:

    #! /bin/bash
    exec > logfile 2>&1
    set -x
    FOO=BAR
    echo $FOO
    
    #! /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
    
    script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'
    
    然后像这样执行:

    #! /bin/bash
    exec > logfile 2>&1
    set -x
    FOO=BAR
    echo $FOO
    
    #! /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
    
    script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'
    
    现在,输出直接可见,并保存到日志文件(日志文件的默认名称为
    typescript


    bash脚本仍在运行,但它生成了一个新的交互式shell。bash脚本正在等待
    script
    完成,这只会在交互式shell终止时发生(被终止,或者用户键入
    exit

    要使
    script
    之后的命令由
    script
    记录,请执行以下操作:

    #! /bin/bash
    exec > logfile 2>&1
    set -x
    FOO=BAR
    echo $FOO
    
    #! /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
    
    script build_log -c 'echo -e "* This line should appear inside the /"build_log/" log file..."'
    
    但是,
    script
    将在运行该命令后停止运行


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

    您可以在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.
    

    我试过这个,效果很好。除非您特别了解需要传递的参数类型以及恶意用户计划使用的脚本,否则这就足够了:)

    按照Exeve的想法,您还可以使用环境变量:

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

    juj的回答很好,但没有正确地传递论点。基本问题是在双引号字符串中使用
    $@
    <代码>$*
    应改为:

    #!/bin/sh
    [ -z "$TYPESCRIPT" ] && TYPESCRIPT=1 exec /usr/bin/script -c "TYPESCRIPT=1  $0 $*"
    # your script here...
    
    下面是使用
    $@
    时发生的情况:

    foo.sh

    #!/bin/sh
    if [ -z $FOO ]
    then
        FOO=1 exec $0 $@
    else
        ./echo_args.sh "$0 $@"
    fi
    
    #!/bin/sh
    echo 0 $0
    echo 1 $1
    echo 2 $2
    echo 3 $3
    
    bar.sh

    #!/bin/sh
    if [ -z $FOO ]
    then
        FOO=1 exec $0 $@
    else
        ./echo_args.sh "$0 $@"
    fi
    
    #!/bin/sh
    echo 0 $0
    echo 1 $1
    echo 2 $2
    echo 3 $3
    
    现在使用一些参数输出
    /foo.sh

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

    这将导致一些参数被传递到
    script
    ,而不是第二次执行
    foo.sh

    请向我们显示您的bash脚本,或者至少是
    脚本
    行。在脚本提示符下执行ps(无参数),这将显示正在发生的情况。你为什么认为它不起作用?如果是因为typescript是“空的”,那么您正在遭受缓冲的痛苦。@Robin Green:您可以在这里找到我的脚本:谢谢!这正是我要找的。我做了很多make x、make y等,并在命令行中分别编写它们的脚本。最后我使用了一个.sh文件,并为每个make命令调用了
    scriptresults1.txt-c“make x”
    。非常有用!使用BSD脚本命令(MacOS X),您不需要在命令周围使用
    -c
    参数或引号。这将是
    script build\u log echo'*这一行应该出现在“build\u log”日志文件中…
    使用BSD脚本命令(MacOS X)时,您不需要在命令周围使用
    -c
    参数或引号。它将是
    scriptbash-xfoo.sh