I'm trying to view all commands I have entered and their outputs. I understand that I can use 'history' to view all of my recent commands. However, is there a way I can check for previous outputs of those commands? I have tried looking it up and there does not seem to be a way.
It only stores history of the commands you ran (which you can retrieve by typing history). Unless you already have set the scroll-back to a very high number, there is no way to see the outputs that are older than the set value of scroll-back. Also setting this value to a very high number will make your scrolling sluggish since the lines are stored in the memory. Cloud Shell uses Tmux, which has a scroll back buffer of 2000 lines by default.
To store your future commands and their outputs, there are few options:
Using screen
Start a screen session by entering screen. Once you are inside ‘screen’, press Ctrl-a, then :, then enter log. All the I/O will be captured in screenlog files in the directory where you started the screen command.
Using script
You can start by typing script. A script session will start that will capture all the I/O to a file named typescript. You can exit the script session by Ctrl-d and view the logs in the typescript file.
Using tee
tee is a handy tool. You can do something like this:
$ tmux | tee log.txt
This will open a new bash shell inside the one you are already running. When you exit out of this, you can see the outputs in the file called log.txt
Other ways
As Dustin Kirkland suggested in this post, you can also use byobu. Although, I have never used terminal screencasting tools such as Shelr also sounds like an option.
Other ways
Cloud Shell commands to run and a link that explains more. This will exit the terminal and thus delete all the scroll back buffer, resetting it to empty, but in the future it will save 5000 lines rather than 2000.
$ tmux show-options -g | grep history
history-limit 2000
$ echo "set -g history-limit 5000" >> ~/.tmux.conf
$ exit
$ tmux show-options -g | grep history
history-limit 5000
If you type…
$ man tmux
… you can find the documentation for this setting (search by typing '/history-limit' + (enter)).
‘history-limit lines’ set the maximum number of lines held in window history. This setting applies only to new windows - existing window histories are not resized and retain the limit at the point they were created.
Related
So I was installing node and somehow I ended up in the /user/local/bin folder checking what was there.
I wanted to so a ls | grep node but did a ls | cat node. The node directory then started to show itself in all its glory. I chuckled, laughed, then stopped the cat but that left my terminal looking something like this:
It is easily fixable by exiting the window.
I don't recommend you try it but i've managed to recreate it reliably. Just cat the node directory leave it for a few seconds then cancel it.
My question is what on earth is going on here? AFAIK using cat shouldn't be able to make this stuff happen.
Terminals interpret certain combinations of bytes as commands. This is how command line programs can output colors, or change the cursor position. What you're seeing is the output after one of these commands activated a box drawing character set by accident. You can activate it yourself with echo or printf:
my cool prompt$ printf '\033(0'
└≤ ␌⎺⎺┌ ⎻⎼⎺└⎻├$
To get out of this mess, type reset and press Enter - it will clear the screen and set all settings back to default.
└≤ ␌⎺⎺┌ ⎻⎼⎺└⎻├$ ⎼␊⎽␊├
(..screen clears..)
my cool prompt$
You managed to output the contents of the node executable to the terminal. What happens when you output random octets to the terminal depends on what those characters are and on the terminal. It often leaves the terminal in a state that the user did not really expect.
We have the following use case:
Run a command (third party, no control over the source code) that starts a development server with an integrated "file watcher" that recompiles the source files and restarts the server when it detects file changes (and publishes the output to a /dist folder only in the very last seconds of the ~30 second process; the /dist folder is created as a last step of the publishing process).
Run a secondary "post-processing" command that should only execute when the previous command has successfully started the server and published the files to the /dist folder (this command publishes some additional static files to the /dist folder, so it's dependant on the existence of the folder).
There are several issues with this approach:
The command from step 1 "steals" the terminal, meaning that it never terminates (due to the file watcher). So executing the two commands in sequence is not an option.
The second command should wait for Terminal 1 to output a certain string (e.g. "Server Started"), which means the /dist folder is now ready. Only then it should come in effect.
As of this moment we have put a reasonable "sleep" in the beginning of the second terminal, just so it waits for the first command to do the publishing and the /dist folder exists. The issue is that on slower computers this sleep period is not enough (the second command starts executing before the first one had enough time to create the /dist folder). On fast computers, the first command finishes rather quickly and there is a rather awkward waiting time before the second command starts. For development purposes, this is very annoying.
Is there a way to automate this two step process?
To rephrase:
Is there a way to make a terminal X, start a secondary Terminal Y and wait for Terminal Y to output a certain string before doing some action. And preferrably doing this same action when Terminal Y outputs the said string over and over.
We prefer a Windows solution if possible, but Linux is also an option if no solution is found.
This Answer is for a Linux solution;
So, Part One: Starting two terminals automatically.
Do the terminals, once automated, need to be actually seen by anyone? If not, I'd run them in screens. The screen command allows you to make virtual terminals, which can be attached and detached as needed. To autostart a screen with a command running, use
screen -S meaningful_service_name -d -m ./ ProcessA
Here, the "-S" sets the screen name to something human-readable that can be referenced later, and the "-d -m" mean start the screen in detached mode (ideal for startup scripts), and run the following command inside it. These screens will be running in the background (until the programs exit or something kills them), and can be attached from the terminal by a user with screen -r meaningful_service_nameThe user can then disconnect by pressing Ctrl-A and then D. This also allows you to monitor the processes remotely via SSH.
--
Which leads to Part Two: Starting ProcessB only after A prints to screen.
Screen allows us to take so-called "screenshots" of its current output. This is saved as a text file, since the (virtual) terminal is text-based.
screen -S meaningful_service_name -p 0 -X hardcopy /some/file/location.txt
Here, the "-p" indicates what is essentially the current window (which should usually be zero), and "-X" means execute the following command. Now that you have a text file with ProcessA's output, you can search it like any other text file.
#!/bin/bash
while true; do
screen -S meaningful_service_name -p 0 -X hardcopy /some/file/location.txt
if [[ $(cat /some/file/location.txt | grep "ProcessA's Output" | wc -l) -ge 1 ]]
then
break
fi
sleep 2
done
./ ProcessB
I need an example of gnome-terminal command to read lines of text from a file and executes them one by one in different terminal or a tab.
So this would be the process. I would run gnome terminal command and it would read 10 commands from a file. Then it would execute those 10 commands in 10 different tabs/terminals. And of course those tabs/terminals would remain opened. I found this question Avoid gnome-terminal close after script execution?
The third answer from the top is very helpful. I managed to open 1 command from a file. But I need 1 file with 10 command lines to be opened like I wrote above.
Thanks.
I recommend to use screen for this, if that can be acceptable to you.
You could create a commands.screenrc file like this:
screen bash -c 'command1; echo press any key; read'
screen bash -c 'command2; bash'
screen mutt
screen emacs
screen
You can define as many programs as you want. Start screen with:
screen -c commands.screenrc
I don't know what kind of commands you want to run. If you want to see their output, then write like the first example above: execute the command in a bash shell, which will "pause" after the command was executed. Or the second line, which, after running the command will start another bash shell. Otherwise the screen window would exit automatically.
If you are not familiar with screen, you will need to learn some basic key strokes to get around, and to be able to switch between windows. The first few pages of this presentation should be enough to get you started.
At any given time I have 3 logins to the same server. Sure, I often use screen, but assume this purpose allows me to have:
1 session running something
1 session looking at output
1 session shuffling files to/from various places
If at any point I lose all three connections, I lose 2/3 of my history, as when I log back in, I get the history from a random 1 of my three connections.
Is there a way to stop this and combine all three history files into 1?
Alternatively, is there a way to declare each login as "ttyN" thus keeping each with its separate history separate, but retrievable / re-connectable?
Thanks!
Possible solution?
After you have opened your Terminal /Screen
start your shell with a History-File setting:
HISTFILE=$HOME/session1-history bash
and continue to work with this bash.
To run a different session history
HISTFILE=$HOME/session2-history bash
etc.
Just add this in your .bashrc file.
# Avoid duplicates..
export HISTCONTROL=ignoredups:erasedups
# Append history entries..
shopt -s histappend
# After each command, save and reload history
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Found this answer at this Unix Stackexchange post.
I tried this and it seems to work on multiple terminals simultaneously, only catch is you've to execute a command for the terminal to fetch the latest history from .bash_history.
So for example, if I open the first terminal and type echo check 1 and then open a second terminal and type echo check 2. Now if I go back to the first terminal and press the up key, I won't get echo check 2, since the last time the history was fetched from the history file was when I executed the previous command. So I can just press Enter without specifying a command and it will fetch the last history entries. Now if I press the up key, it will show up echo check 2, which is the expected behavior.
There is an open source shell history logger for bash and zsh which would solve your problem (disclaimer: I wrote and maintain it).
https://github.com/barabo/advanced-shell-history
The idea is that your commands are written into a sqlite3 database using a builtin bash hook. If you really needed to go back and figure out what commands you entered / how long they ran / what their exit codes were - you should give it a try.
It's saved me many times.
There are numerous options you can set to prevent Bash instances from overwriting each others history. See this FAQ for a full explanation:
In your .bashrc, add
HISTFILESIZE=400000000
HISTSIZE=10000
PROMPT_COMMAND="history -a"
export HISTSIZE PROMPT_COMMAND
shopt -s histappend
If I've understood your requirements right you have multiple terminal sessions open and want commands entered in one session to be available via history in other sessions.
You need to put these lines on top of your ~/.bashrc:
export HISTFILESIZE=100000
export HISTSIZE=100000
# avoid & erase dups
export HISTCONTROL=ignoredups:erasedups
shopt -s histappend
# save & reload history after each command enter in shell
export PROMPT_COMMAND="\history -a; \history -c; \history -r; $PROMPT_COMMAND"
Most important is histappend which makes sure that new history lines are appended to the history file each time.
PS: You need to press enter to see most recently added history in each session.
For more robust solution see: http://ptspts.blogspot.in/2011/03/how-to-automatically-synchronize-shell.html
Sometimes I have to run a command many times in succession, for example to see if a service has started, and it becomes tedious to move my hands away from my normal typing position to press the Up Arrow and Enter keys repeatedly. Is there a way to run the previous command without the Up Arrow and Enter keys, perhaps with an elaborate shell script?
I've tried the following, but it is unsatisfactory because it cannot execute aliases, and it is a little slow.
history | tail -2 | head -1 | cut -d' ' -f4- | cat > prev_command.txt
sleep .01
chmod 777 prev_command.txt
eval prev_command.txt
rm prev_command.txt
Ideally I'd have an alias to this script so I can type in something like "prev" in the command line and hit Enter to run the previous command again.
In bash, you can press ctrlp to go to the previous command -- that's a lot better than having to move to the arrow keys.
See also: https://github.com/fliptheweb/bash-shortcuts-cheat-sheet/
Use
!!
to run your previous command.
sudo !!
also works , for the record.
Instead of running the same command many times in succession, why not watch it instead? watch will run a specified command repeatedly and display the output in stdout so you can see it change over time.
watchcommand
I often use the "history expansion" feature in bash (usually activated with cntlR) -- it interactively searches through your history for the previous closest match.
See the bash manual section Searching for Commands in the History, and also Using History Interactively.
Are you an emacs or vi user? You can use
set -o vi
set -o emacs
to set emacs or vi keybindings. You can then use the emacs or vi key bindings in bash. I don't know if this should work for other shells. I believe the vi mode starts in insert mode, so you need to hit esc to enter command mode. In emacs mode (the default), you can use ctrl+p and then ctrl+j to move to the previous line and do a carriage return.
Otherwise, you can use !! as someone else suggested.
In bash:
$ help fc
fc: fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
Display or execute commands from the history list.
fc is used to list or edit and re-execute commands from the history list.
FIRST and LAST can be numbers specifying the range, or FIRST can be a
string, which means the most recent command beginning with that
string.
Options:
-e ENAME select which editor to use. Default is FCEDIT, then EDITOR,
then vi
-l list lines instead of editing
-n omit line numbers when listing
-r reverse the order of the lines (newest listed first)
With the `fc -s [pat=rep ...] [command]' format, COMMAND is
re-executed after the substitution OLD=NEW is performed.
A useful alias to use with this is r='fc -s', so that typing `r cc'
runs the last command beginning with `cc' and typing `r' re-executes
the last command.
Exit Status:
Returns success or status of executed command; non-zero if an error occurs.
Note the suggestion for alias r; I use this frequently.
Depending on what terminal you're using, I know a lot used to have F3 as an option for repeating, but that's still outside the normal range for typing as well unless you have a special keyboard with more accessible function keys.
My keyboard makes the function keys easily accessible, but I don't do much command line work in unix any more, so I wouldn't be able to tell you for sure whether or not this is still possible.