Bash script: Using “script” command from a bash script for logging a session

前端 未结 5 1530
谎友^
谎友^ 2020-12-05 05:03

I am trying to use script command for logging a bash session.

The script command is executed from withing a bash script but as soon as it i

相关标签:
5条回答
  • 2020-12-05 05:12

    Your bash script is still running, but it has spawned a new interactive shell. The bash script is waiting for script to complete, which will only happen when the interactive shell is terminated (either by being killed, or by the user typing exit).

    To make the command after script be logged by script, do it like this:

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

    However, script will stop running after running that command.

    To run multiple commands inside script, put those commands inside another bash script and specify that bash script as the command to run to the -c option.

    0 讨论(0)
  • 2020-12-05 05:26

    juj's answer is great but fails to pass on arguments correctly. The basic problem is the use of $@ inside a double-quoted string. $* should be used instead:

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

    Here's what happens with $@:

    foo.sh:

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

    bar.sh:

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

    Now ./foo.sh with some arguments outputs

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

    This would cause some of the arguments to be passed to script instead of to the second execution of foo.sh.

    0 讨论(0)
  • 2020-12-05 05:31

    You can use a trick within your shell script to start script or not start it. Based on a special argument, it can choose to execute itself with a special argument so that script is not started again.

    This should most likely explain what I mean:

    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.
    

    I have tried this, and it works well. Unless you are particular about the kind of arguments that need to be passed as well as the script is planned to be used by hostile users, this should suffice :).

    0 讨论(0)
  • 2020-12-05 05:35

    Your shell script did not terminate. It is still running. You are getting a prompt because script is spawning a new shell. the prompt you see is the prompt from the spawned shell.

    The normal use case for script is something like this:

    1. start script. this spawns a new shell.
    2. do commands in the new shell.
    3. exit the shell and drop to previous shell
    4. examine the logfile created by script

    So basically script is working as expected. You will have to find another way to achieve what you want.

    You can log the execution of your script like this:

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

    Explanation:

    • exec > logfile 2>&1 redirects stdout and stderr to logfile
    • set -x makes bash print every command before executing it

    Example:

    $ ./foo.sh
      # (no output here because everything goes to logfile)
    $ cat logfile 
    + FOO=BAR
    + echo BAR
    BAR
    

    Disadvantage of this method is that the script prints no output for humans to see. Everything goes to the logfile.

    Alternatively you can do it like this:

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

    Then execute like this:

    $ script -c "bash -x foo.sh"
    Script started, file is typescript
    + FOO=BAR
    + echo BAR
    BAR
    Script done, file is typescript
    

    now output is directly visible and also saved to logfile (default name of logfile 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 讨论(0)
  • 2020-12-05 05:35

    Following execve's idea, you can also use an environment variable:

    #!/bin/sh
    [ -z "$TYPESCRIPT" ] && TYPESCRIPT=1 exec /usr/bin/script -c "TYPESCRIPT=1 $0 $@"
    # your script here...
    
    0 讨论(0)
提交回复
热议问题