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).
bash scripts history
add a comment |
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).
bash scripts history
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 isscreen
. 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 runsscreen -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 thePractical 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
add a comment |
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).
bash scripts history
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
bash scripts history
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 isscreen
. 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 runsscreen -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 thePractical 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
add a comment |
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 isscreen
. 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 runsscreen -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 thePractical 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
add a comment |
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 issuelogsutff on
in shell 1, then issue commands there, then issuelogstuff 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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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 issuelogsutff on
in shell 1, then issue commands there, then issuelogstuff 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.
add a comment |
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 issuelogsutff on
in shell 1, then issue commands there, then issuelogstuff 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.
add a comment |
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 issuelogsutff on
in shell 1, then issue commands there, then issuelogstuff 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.
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 issuelogsutff on
in shell 1, then issue commands there, then issuelogstuff 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.
edited Dec 10 at 23:59
Gavin Morton
30111
30111
answered Dec 1 at 21:55
Sergiy Kolodyazhnyy
69k9143303
69k9143303
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 isscreen
. 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