Save all command and all output (using script across terminals)











up vote
2
down vote

favorite












For a short period of time, I want to save the command history and output of every command I run in any terminal I open. It should all go in the same file.



So basically I want to run a command (or edit bashrc) such that I can then;




  • Open terminal #1 and run echo hello

  • Open terminal #2 and type ls

  • Close terminal #1 and open terminal #3 and type whoami

  • Close all terminals. Open terminal #4, and type a command to see all the commands run in order above (echo hello, ls, whoami), plus their output, in the order I ran the commands.


I could in theory open each terminal and type



screen -f output.txt


and then



exit


before I closed each terminal, but I don't want to have to remember to type that every time. I just want it done automatically until I manually stop it (by either running a command, or updating bashrc).



Please read the question carefully before declaring it a duplicate. I have searched existing questions and did not find something equivalent (though its possible I missed it).










share|improve this question
























  • Possible duplicate: askubuntu.com/q/161935/295286
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:43










  • @SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
    – n00b
    Dec 1 at 18:44






  • 1




    Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:51










  • You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
    – muru
    Dec 1 at 19:40










  • I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
    – Sergiy Kolodyazhnyy
    Dec 1 at 21:56















up vote
2
down vote

favorite












For a short period of time, I want to save the command history and output of every command I run in any terminal I open. It should all go in the same file.



So basically I want to run a command (or edit bashrc) such that I can then;




  • Open terminal #1 and run echo hello

  • Open terminal #2 and type ls

  • Close terminal #1 and open terminal #3 and type whoami

  • Close all terminals. Open terminal #4, and type a command to see all the commands run in order above (echo hello, ls, whoami), plus their output, in the order I ran the commands.


I could in theory open each terminal and type



screen -f output.txt


and then



exit


before I closed each terminal, but I don't want to have to remember to type that every time. I just want it done automatically until I manually stop it (by either running a command, or updating bashrc).



Please read the question carefully before declaring it a duplicate. I have searched existing questions and did not find something equivalent (though its possible I missed it).










share|improve this question
























  • Possible duplicate: askubuntu.com/q/161935/295286
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:43










  • @SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
    – n00b
    Dec 1 at 18:44






  • 1




    Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:51










  • You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
    – muru
    Dec 1 at 19:40










  • I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
    – Sergiy Kolodyazhnyy
    Dec 1 at 21:56













up vote
2
down vote

favorite









up vote
2
down vote

favorite











For a short period of time, I want to save the command history and output of every command I run in any terminal I open. It should all go in the same file.



So basically I want to run a command (or edit bashrc) such that I can then;




  • Open terminal #1 and run echo hello

  • Open terminal #2 and type ls

  • Close terminal #1 and open terminal #3 and type whoami

  • Close all terminals. Open terminal #4, and type a command to see all the commands run in order above (echo hello, ls, whoami), plus their output, in the order I ran the commands.


I could in theory open each terminal and type



screen -f output.txt


and then



exit


before I closed each terminal, but I don't want to have to remember to type that every time. I just want it done automatically until I manually stop it (by either running a command, or updating bashrc).



Please read the question carefully before declaring it a duplicate. I have searched existing questions and did not find something equivalent (though its possible I missed it).










share|improve this question















For a short period of time, I want to save the command history and output of every command I run in any terminal I open. It should all go in the same file.



So basically I want to run a command (or edit bashrc) such that I can then;




  • Open terminal #1 and run echo hello

  • Open terminal #2 and type ls

  • Close terminal #1 and open terminal #3 and type whoami

  • Close all terminals. Open terminal #4, and type a command to see all the commands run in order above (echo hello, ls, whoami), plus their output, in the order I ran the commands.


I could in theory open each terminal and type



screen -f output.txt


and then



exit


before I closed each terminal, but I don't want to have to remember to type that every time. I just want it done automatically until I manually stop it (by either running a command, or updating bashrc).



Please read the question carefully before declaring it a duplicate. I have searched existing questions and did not find something equivalent (though its possible I missed it).







bash scripts history






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 1 at 19:39









muru

135k19289491




135k19289491










asked Dec 1 at 18:36









n00b

1157




1157












  • Possible duplicate: askubuntu.com/q/161935/295286
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:43










  • @SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
    – n00b
    Dec 1 at 18:44






  • 1




    Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:51










  • You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
    – muru
    Dec 1 at 19:40










  • I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
    – Sergiy Kolodyazhnyy
    Dec 1 at 21:56


















  • Possible duplicate: askubuntu.com/q/161935/295286
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:43










  • @SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
    – n00b
    Dec 1 at 18:44






  • 1




    Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
    – Sergiy Kolodyazhnyy
    Dec 1 at 18:51










  • You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
    – muru
    Dec 1 at 19:40










  • I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
    – Sergiy Kolodyazhnyy
    Dec 1 at 21:56
















Possible duplicate: askubuntu.com/q/161935/295286
– Sergiy Kolodyazhnyy
Dec 1 at 18:43




Possible duplicate: askubuntu.com/q/161935/295286
– Sergiy Kolodyazhnyy
Dec 1 at 18:43












@SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
– n00b
Dec 1 at 18:44




@SergiyKolodyazhnyy that question asks about a single terminal window and the answer does not address how to do it automatically as I have asked for in this question.
– n00b
Dec 1 at 18:44




1




1




Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
– Sergiy Kolodyazhnyy
Dec 1 at 18:51




Fair enough. I'll just point out a couple things: 1) automating such command could be done via ~/.bashrc , which gets sourced when interactive shell is open 2) script is as good as it gets when you want to log terminal / shell activity 3) merging multiple session records is going to be really difficult. So most reasonable solution is screen. What's being asked ( and if ever implemented ) would potentially be awkward and inefficient
– Sergiy Kolodyazhnyy
Dec 1 at 18:51












You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
– muru
Dec 1 at 19:40




You could create a new profile for the terminal that runs screen -f output.txt as the command, and set it as the default profile for the short while you want to save this output.
– muru
Dec 1 at 19:40












I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
– Sergiy Kolodyazhnyy
Dec 1 at 21:56




I've made an attempt at a solution, although please see the Practical considerations part. Instead of dealing with 3 unrelated terminals, I'd suggest just dealing with one and keeping all necessary relevant information in one place.
– Sergiy Kolodyazhnyy
Dec 1 at 21:56










1 Answer
1






active

oldest

votes

















up vote
1
down vote













Potential solution



After some research and experimenting, here's what I came up with:



logstuff(){

while true; do

case $1 in
"on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;n"; tee /dev/tty ; printf ">>>>>n" ) >> logfile.txt) 2>&1 ;
break;;
"off") exec > /dev/tty 2>&1 ;
break;;
*) echo "Please type 'on' or 'off';;
esac
done
}


This bash function should be placed in your ~/.bashrc and is available for use when opening new terminal or after issuing source ~/.bashrc. Logging has to be turned on manually via on and off arguments.





DEMO



Here's how it works in practice:



Do stuff in shell 1:



<shell 1>$ logstuff on
<shell 1>$ stat /etc/passwd
File: /etc/passwd
Size: 2208 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 156236 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-12-01 20:24:02.620000000 +0000
Modify: 2018-10-31 01:33:42.701000999 +0000
Change: 2018-10-31 01:33:42.704998999 +0000
Birth: -
<shell 1>$ logstuff off
<shell 1>$


Do stuff in shell 2:



< shell 2 >$ logstuff on
< shell 2 >$ echo "Hello World !"
Hello World !
< shell 2 >$ logstuff off
< shell 2 >$


Now review the logfile.txt:



<shell 1>$ cat logfile.txt 
>>>>> TIME:Sat Dec 1 21:43:00 UTC 2018 SHELLPID:2225;
<shell 1>$ stat /etc/passwd
File: /etc/passwd
Size: 2208 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 156236 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2018-12-01 20:24:02.620000000 +0000
Modify: 2018-10-31 01:33:42.701000999 +0000
Change: 2018-10-31 01:33:42.704998999 +0000
Birth: -
<shell 1>$ >>>>> TIME:Sat Dec 1 21:43:11 UTC 2018 SHELLPID:2359;
< shell 2 >$ echo "Hello World !"
Hello World !
< shell 2 >$ logstuff off
>>>>>
logstuff off
>>>>>
<shell 1>$




Issues




  • If logstuff on is issued in both terminals first, there's a chance of outputs being mangled together. The way it works is that you have to issue logsutff on in shell 1, then issue commands there, then issue logstuff on in shell 2.

  • This uses process substitution >( ), tee and a subshell. Not the most elegant nor efficient due to bunch of forking and extra pipeline.


  • logfile.txt is stored in current working directory. This should be changed to ~/logfile.txt or however the user sees fit.




Practical considerations



What the question itself asks is somewhat impractical: storing output from multiple shells into one single file means you're storing output of commands from two or more completely unrelated session, which may have different environment variables, different working directories, or working on different filesystems; this means there's whole lot of context lacking if you're intending to use such log text for debugging purposes or solving a problem.



Far better approach would be to have script -f write to log files in one specific directory, potentially with filenames of such logs timestamped or appended the shell PID. Another solution - instead of having 3 different terminals, just use one - screen or my personal favorite byobu-screen. You can attach/detach to a single virtual tty session in screen and it is often used to keep processes running on remote servers where you have to log out but still need a shell session with output and tracebacks running. This can be combined with script as well.






share|improve this answer























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "89"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1097720%2fsave-all-command-and-all-output-using-script-across-terminals%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    Potential solution



    After some research and experimenting, here's what I came up with:



    logstuff(){

    while true; do

    case $1 in
    "on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;n"; tee /dev/tty ; printf ">>>>>n" ) >> logfile.txt) 2>&1 ;
    break;;
    "off") exec > /dev/tty 2>&1 ;
    break;;
    *) echo "Please type 'on' or 'off';;
    esac
    done
    }


    This bash function should be placed in your ~/.bashrc and is available for use when opening new terminal or after issuing source ~/.bashrc. Logging has to be turned on manually via on and off arguments.





    DEMO



    Here's how it works in practice:



    Do stuff in shell 1:



    <shell 1>$ logstuff on
    <shell 1>$ stat /etc/passwd
    File: /etc/passwd
    Size: 2208 Blocks: 8 IO Block: 4096 regular file
    Device: 802h/2050d Inode: 156236 Links: 1
    Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
    Access: 2018-12-01 20:24:02.620000000 +0000
    Modify: 2018-10-31 01:33:42.701000999 +0000
    Change: 2018-10-31 01:33:42.704998999 +0000
    Birth: -
    <shell 1>$ logstuff off
    <shell 1>$


    Do stuff in shell 2:



    < shell 2 >$ logstuff on
    < shell 2 >$ echo "Hello World !"
    Hello World !
    < shell 2 >$ logstuff off
    < shell 2 >$


    Now review the logfile.txt:



    <shell 1>$ cat logfile.txt 
    >>>>> TIME:Sat Dec 1 21:43:00 UTC 2018 SHELLPID:2225;
    <shell 1>$ stat /etc/passwd
    File: /etc/passwd
    Size: 2208 Blocks: 8 IO Block: 4096 regular file
    Device: 802h/2050d Inode: 156236 Links: 1
    Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
    Access: 2018-12-01 20:24:02.620000000 +0000
    Modify: 2018-10-31 01:33:42.701000999 +0000
    Change: 2018-10-31 01:33:42.704998999 +0000
    Birth: -
    <shell 1>$ >>>>> TIME:Sat Dec 1 21:43:11 UTC 2018 SHELLPID:2359;
    < shell 2 >$ echo "Hello World !"
    Hello World !
    < shell 2 >$ logstuff off
    >>>>>
    logstuff off
    >>>>>
    <shell 1>$




    Issues




    • If logstuff on is issued in both terminals first, there's a chance of outputs being mangled together. The way it works is that you have to issue logsutff on in shell 1, then issue commands there, then issue logstuff on in shell 2.

    • This uses process substitution >( ), tee and a subshell. Not the most elegant nor efficient due to bunch of forking and extra pipeline.


    • logfile.txt is stored in current working directory. This should be changed to ~/logfile.txt or however the user sees fit.




    Practical considerations



    What the question itself asks is somewhat impractical: storing output from multiple shells into one single file means you're storing output of commands from two or more completely unrelated session, which may have different environment variables, different working directories, or working on different filesystems; this means there's whole lot of context lacking if you're intending to use such log text for debugging purposes or solving a problem.



    Far better approach would be to have script -f write to log files in one specific directory, potentially with filenames of such logs timestamped or appended the shell PID. Another solution - instead of having 3 different terminals, just use one - screen or my personal favorite byobu-screen. You can attach/detach to a single virtual tty session in screen and it is often used to keep processes running on remote servers where you have to log out but still need a shell session with output and tracebacks running. This can be combined with script as well.






    share|improve this answer



























      up vote
      1
      down vote













      Potential solution



      After some research and experimenting, here's what I came up with:



      logstuff(){

      while true; do

      case $1 in
      "on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;n"; tee /dev/tty ; printf ">>>>>n" ) >> logfile.txt) 2>&1 ;
      break;;
      "off") exec > /dev/tty 2>&1 ;
      break;;
      *) echo "Please type 'on' or 'off';;
      esac
      done
      }


      This bash function should be placed in your ~/.bashrc and is available for use when opening new terminal or after issuing source ~/.bashrc. Logging has to be turned on manually via on and off arguments.





      DEMO



      Here's how it works in practice:



      Do stuff in shell 1:



      <shell 1>$ logstuff on
      <shell 1>$ stat /etc/passwd
      File: /etc/passwd
      Size: 2208 Blocks: 8 IO Block: 4096 regular file
      Device: 802h/2050d Inode: 156236 Links: 1
      Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
      Access: 2018-12-01 20:24:02.620000000 +0000
      Modify: 2018-10-31 01:33:42.701000999 +0000
      Change: 2018-10-31 01:33:42.704998999 +0000
      Birth: -
      <shell 1>$ logstuff off
      <shell 1>$


      Do stuff in shell 2:



      < shell 2 >$ logstuff on
      < shell 2 >$ echo "Hello World !"
      Hello World !
      < shell 2 >$ logstuff off
      < shell 2 >$


      Now review the logfile.txt:



      <shell 1>$ cat logfile.txt 
      >>>>> TIME:Sat Dec 1 21:43:00 UTC 2018 SHELLPID:2225;
      <shell 1>$ stat /etc/passwd
      File: /etc/passwd
      Size: 2208 Blocks: 8 IO Block: 4096 regular file
      Device: 802h/2050d Inode: 156236 Links: 1
      Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
      Access: 2018-12-01 20:24:02.620000000 +0000
      Modify: 2018-10-31 01:33:42.701000999 +0000
      Change: 2018-10-31 01:33:42.704998999 +0000
      Birth: -
      <shell 1>$ >>>>> TIME:Sat Dec 1 21:43:11 UTC 2018 SHELLPID:2359;
      < shell 2 >$ echo "Hello World !"
      Hello World !
      < shell 2 >$ logstuff off
      >>>>>
      logstuff off
      >>>>>
      <shell 1>$




      Issues




      • If logstuff on is issued in both terminals first, there's a chance of outputs being mangled together. The way it works is that you have to issue logsutff on in shell 1, then issue commands there, then issue logstuff on in shell 2.

      • This uses process substitution >( ), tee and a subshell. Not the most elegant nor efficient due to bunch of forking and extra pipeline.


      • logfile.txt is stored in current working directory. This should be changed to ~/logfile.txt or however the user sees fit.




      Practical considerations



      What the question itself asks is somewhat impractical: storing output from multiple shells into one single file means you're storing output of commands from two or more completely unrelated session, which may have different environment variables, different working directories, or working on different filesystems; this means there's whole lot of context lacking if you're intending to use such log text for debugging purposes or solving a problem.



      Far better approach would be to have script -f write to log files in one specific directory, potentially with filenames of such logs timestamped or appended the shell PID. Another solution - instead of having 3 different terminals, just use one - screen or my personal favorite byobu-screen. You can attach/detach to a single virtual tty session in screen and it is often used to keep processes running on remote servers where you have to log out but still need a shell session with output and tracebacks running. This can be combined with script as well.






      share|improve this answer

























        up vote
        1
        down vote










        up vote
        1
        down vote









        Potential solution



        After some research and experimenting, here's what I came up with:



        logstuff(){

        while true; do

        case $1 in
        "on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;n"; tee /dev/tty ; printf ">>>>>n" ) >> logfile.txt) 2>&1 ;
        break;;
        "off") exec > /dev/tty 2>&1 ;
        break;;
        *) echo "Please type 'on' or 'off';;
        esac
        done
        }


        This bash function should be placed in your ~/.bashrc and is available for use when opening new terminal or after issuing source ~/.bashrc. Logging has to be turned on manually via on and off arguments.





        DEMO



        Here's how it works in practice:



        Do stuff in shell 1:



        <shell 1>$ logstuff on
        <shell 1>$ stat /etc/passwd
        File: /etc/passwd
        Size: 2208 Blocks: 8 IO Block: 4096 regular file
        Device: 802h/2050d Inode: 156236 Links: 1
        Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
        Access: 2018-12-01 20:24:02.620000000 +0000
        Modify: 2018-10-31 01:33:42.701000999 +0000
        Change: 2018-10-31 01:33:42.704998999 +0000
        Birth: -
        <shell 1>$ logstuff off
        <shell 1>$


        Do stuff in shell 2:



        < shell 2 >$ logstuff on
        < shell 2 >$ echo "Hello World !"
        Hello World !
        < shell 2 >$ logstuff off
        < shell 2 >$


        Now review the logfile.txt:



        <shell 1>$ cat logfile.txt 
        >>>>> TIME:Sat Dec 1 21:43:00 UTC 2018 SHELLPID:2225;
        <shell 1>$ stat /etc/passwd
        File: /etc/passwd
        Size: 2208 Blocks: 8 IO Block: 4096 regular file
        Device: 802h/2050d Inode: 156236 Links: 1
        Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
        Access: 2018-12-01 20:24:02.620000000 +0000
        Modify: 2018-10-31 01:33:42.701000999 +0000
        Change: 2018-10-31 01:33:42.704998999 +0000
        Birth: -
        <shell 1>$ >>>>> TIME:Sat Dec 1 21:43:11 UTC 2018 SHELLPID:2359;
        < shell 2 >$ echo "Hello World !"
        Hello World !
        < shell 2 >$ logstuff off
        >>>>>
        logstuff off
        >>>>>
        <shell 1>$




        Issues




        • If logstuff on is issued in both terminals first, there's a chance of outputs being mangled together. The way it works is that you have to issue logsutff on in shell 1, then issue commands there, then issue logstuff on in shell 2.

        • This uses process substitution >( ), tee and a subshell. Not the most elegant nor efficient due to bunch of forking and extra pipeline.


        • logfile.txt is stored in current working directory. This should be changed to ~/logfile.txt or however the user sees fit.




        Practical considerations



        What the question itself asks is somewhat impractical: storing output from multiple shells into one single file means you're storing output of commands from two or more completely unrelated session, which may have different environment variables, different working directories, or working on different filesystems; this means there's whole lot of context lacking if you're intending to use such log text for debugging purposes or solving a problem.



        Far better approach would be to have script -f write to log files in one specific directory, potentially with filenames of such logs timestamped or appended the shell PID. Another solution - instead of having 3 different terminals, just use one - screen or my personal favorite byobu-screen. You can attach/detach to a single virtual tty session in screen and it is often used to keep processes running on remote servers where you have to log out but still need a shell session with output and tracebacks running. This can be combined with script as well.






        share|improve this answer














        Potential solution



        After some research and experimenting, here's what I came up with:



        logstuff(){

        while true; do

        case $1 in
        "on" ) exec > >( ( printf ">>>>> TIME:$(date) SHELLPID:$$;n"; tee /dev/tty ; printf ">>>>>n" ) >> logfile.txt) 2>&1 ;
        break;;
        "off") exec > /dev/tty 2>&1 ;
        break;;
        *) echo "Please type 'on' or 'off';;
        esac
        done
        }


        This bash function should be placed in your ~/.bashrc and is available for use when opening new terminal or after issuing source ~/.bashrc. Logging has to be turned on manually via on and off arguments.





        DEMO



        Here's how it works in practice:



        Do stuff in shell 1:



        <shell 1>$ logstuff on
        <shell 1>$ stat /etc/passwd
        File: /etc/passwd
        Size: 2208 Blocks: 8 IO Block: 4096 regular file
        Device: 802h/2050d Inode: 156236 Links: 1
        Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
        Access: 2018-12-01 20:24:02.620000000 +0000
        Modify: 2018-10-31 01:33:42.701000999 +0000
        Change: 2018-10-31 01:33:42.704998999 +0000
        Birth: -
        <shell 1>$ logstuff off
        <shell 1>$


        Do stuff in shell 2:



        < shell 2 >$ logstuff on
        < shell 2 >$ echo "Hello World !"
        Hello World !
        < shell 2 >$ logstuff off
        < shell 2 >$


        Now review the logfile.txt:



        <shell 1>$ cat logfile.txt 
        >>>>> TIME:Sat Dec 1 21:43:00 UTC 2018 SHELLPID:2225;
        <shell 1>$ stat /etc/passwd
        File: /etc/passwd
        Size: 2208 Blocks: 8 IO Block: 4096 regular file
        Device: 802h/2050d Inode: 156236 Links: 1
        Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
        Access: 2018-12-01 20:24:02.620000000 +0000
        Modify: 2018-10-31 01:33:42.701000999 +0000
        Change: 2018-10-31 01:33:42.704998999 +0000
        Birth: -
        <shell 1>$ >>>>> TIME:Sat Dec 1 21:43:11 UTC 2018 SHELLPID:2359;
        < shell 2 >$ echo "Hello World !"
        Hello World !
        < shell 2 >$ logstuff off
        >>>>>
        logstuff off
        >>>>>
        <shell 1>$




        Issues




        • If logstuff on is issued in both terminals first, there's a chance of outputs being mangled together. The way it works is that you have to issue logsutff on in shell 1, then issue commands there, then issue logstuff on in shell 2.

        • This uses process substitution >( ), tee and a subshell. Not the most elegant nor efficient due to bunch of forking and extra pipeline.


        • logfile.txt is stored in current working directory. This should be changed to ~/logfile.txt or however the user sees fit.




        Practical considerations



        What the question itself asks is somewhat impractical: storing output from multiple shells into one single file means you're storing output of commands from two or more completely unrelated session, which may have different environment variables, different working directories, or working on different filesystems; this means there's whole lot of context lacking if you're intending to use such log text for debugging purposes or solving a problem.



        Far better approach would be to have script -f write to log files in one specific directory, potentially with filenames of such logs timestamped or appended the shell PID. Another solution - instead of having 3 different terminals, just use one - screen or my personal favorite byobu-screen. You can attach/detach to a single virtual tty session in screen and it is often used to keep processes running on remote servers where you have to log out but still need a shell session with output and tracebacks running. This can be combined with script as well.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 10 at 23:59









        Gavin Morton

        30111




        30111










        answered Dec 1 at 21:55









        Sergiy Kolodyazhnyy

        69k9143303




        69k9143303






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Ask Ubuntu!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1097720%2fsave-all-command-and-all-output-using-script-across-terminals%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Quarter-circle Tiles

            build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

            Mont Emei