All Projects → pawamoy → shell-history

pawamoy / shell-history

Licence: ISC license
Visualize your shell usage with Highcharts!

Programming Languages

python
139335 projects - #7 most used programming language
javascript
184084 projects - #8 most used programming language
HTML
75241 projects
shell
77523 projects
CSS
56736 projects
Makefile
30231 projects

Projects that are alternatives of or similar to shell-history

fornalder
Visualize long-term trends in collections of Git repositories.
Stars: ✭ 80 (-20%)
Mutual labels:  analysis, history
webextensions-history-browser
🕘 Browse your firefox history like a boss.
Stars: ✭ 19 (-81%)
Mutual labels:  history
Highcharts Chart
Polymer Element wrapper for highcharts library. Seamlessly create various types of charts from one element.
Stars: ✭ 97 (-3%)
Mutual labels:  highcharts
Angular Highcharts
Highcharts directive for Angular
Stars: ✭ 202 (+102%)
Mutual labels:  highcharts
Vue Highcharts
The Component of Vue 2.x for highcharts
Stars: ✭ 112 (+12%)
Mutual labels:  highcharts
React Native Highcharts
📈 Add Highcharts charts to react-native app for IOS and Android
Stars: ✭ 247 (+147%)
Mutual labels:  highcharts
React Highcharts
React wrapper for Highcharts library
Stars: ✭ 1,247 (+1147%)
Mutual labels:  highcharts
J2N
Java-like Components for .NET
Stars: ✭ 37 (-63%)
Mutual labels:  analysis
ioBroker.influxdb
Store history data in InfluxDB (not for Windows)
Stars: ✭ 33 (-67%)
Mutual labels:  history
Highcharts Editor
Stars: ✭ 204 (+104%)
Mutual labels:  highcharts
Yuqing Monitor Electron
Electron+Node+Socket.io+Vue+ElementUI+Highcharts开发的PC端舆情监控客户端,支持windows、mac、Linux多平台
Stars: ✭ 157 (+57%)
Mutual labels:  highcharts
React Antd Admin
后台前端管理系统,基于react、typescript、antd、dva及一些特别优秀的开源库实现
Stars: ✭ 117 (+17%)
Mutual labels:  highcharts
rhino
Agile Sandbox for analyzing Windows, Linux and macOS malware and execution behaviors
Stars: ✭ 49 (-51%)
Mutual labels:  analysis
Splits Io
a speedrunning data store, analysis engine, and racing platform
Stars: ✭ 99 (-1%)
Mutual labels:  highcharts
codacy-scalameta
Codacy tool for Scalameta
Stars: ✭ 35 (-65%)
Mutual labels:  analysis
Pokegraphs
Pokemon pixel color graphs in javascript.
Stars: ✭ 87 (-13%)
Mutual labels:  highcharts
Highcharts Ng
AngularJS directive for Highcharts
Stars: ✭ 1,741 (+1641%)
Mutual labels:  highcharts
Angular Material Dashboard
Angular Material Dasshboard using Angular Material, highcharts and flexbox
Stars: ✭ 227 (+127%)
Mutual labels:  highcharts
seo-audits-toolkit
SEO & Security Audit for Websites. Lighthouse & Security Headers crawler, Sitemap/Keywords/Images Extractor, Summarizer, etc ...
Stars: ✭ 311 (+211%)
Mutual labels:  analysis
leveldb-cli
CLI for LevelDB
Stars: ✭ 86 (-14%)
Mutual labels:  analysis

Shell History

ci documentation pypi version

Inspired by bamos/zsh-history-analysis.

Visualize your usage of Bash/Zsh through a web app thanks to Flask and Highcharts!

Durationduration chart Lengthlength chart Typetype chart
Exit codeexit code chart Hourlyhourly chart Dailydaily chart
Over timeover time chart Markov chainmarkov chart Top commandstop chart

Post your charts ideas in this issue!

Requirements

Shell History requires Python 3.6 or above.

To install Python 3.6, I recommend using pyenv.
# install pyenv
git clone https://github.com/pyenv/pyenv ~/.pyenv

# setup pyenv (you should also put these three lines in .bashrc or similar)
export PATH="${HOME}/.pyenv/bin:${PATH}"
export PYENV_ROOT="${HOME}/.pyenv"
eval "$(pyenv init -)"

# install Python 3.6
pyenv install 3.6.12

# make it available globally
pyenv global system 3.6.12

Installation

With pip:

python3.6 -m pip install shellhistory

With pipx:

python3.6 -m pip install --user pipx

pipx install --python python3.6 shellhistory

Setup

shellhistory needs a lot of info to be able to display various charts. The basic shell history is not enough. In order to generate the necessary information, you have to enable the shell extension.

At shell startup, in .bashrc or .zshrc, put the following:

# only load it for interactive shells
if [[ $- == *i* ]] && command -v shellhistory-location &>/dev/null; then
    . $(shellhistory-location)
    shellhistory enable
fi

... and now use your shell normally!

If you want to stop shellhistory, simply run shellhistory disable.

Note: for performance reasons, you can also use the static, absolute path to the source file. Indeed, calling shellhistory-location spawns a Python process which can slow down your shell startup. Get the path once with shellhistory-location, and use . <ABS_PATH>. In my case it's . ~/.local/pipx/venvs/shellhistory/lib/python3.6/site-packages/shellhistory/shellhistory.sh.

Usage

Launch the web app with shellhistory-web. Now go to http://localhost:5000/ and enjoy!

You will need Internet connection since assets are not bundled.

Some technical info

How it works

When you enter a command, shellhistory will compute values before and after the command execution. In Bash, it uses a trap on DEBUG and the PROMPT_COMMAND variable (man bash for more information). For Zsh, it uses the preexec_functions and precmd_functions arrays (anyone knows where to find the official documentation for these? Some information in man zshmisc).

Before the command is executed, we start a timer, compute the command type, and store the current working directory and the command itself.

After the command has finished, we store the return code, and stop the timer.

History file format

Fields saved along commands are start and stop timestamps, hostname, username, uuid (generated), tty, process' parents, shell, shell level, command type, return code, and working directory (path), in the following format: :start:stop:uuid:parents:host:user:tty:path:shell:level:type:code:command.

  • multi-line commands are prepended with a semi-colon ; instead of a colon :, starting at second line
  • start and stop timestamps are in microseconds since epoch
  • process' parents and working directory are encoded in base64 to avoid delimiter corruption.

Example (multi-line command):

:1510588139930150:1510588139936608:40701d9b-1807-4a3e-994b-dde68692aa14:L2Jpbi9iYXNoCi91c3IvYmluL3B5dGhvbiAvdXNyL2Jpbi94LXRlcm1pbmFsLWVtdWxhdG9yCi91c3IvYmluL29wZW5ib3ggLS1zdGFydHVwIC91c3IvbGliL3g4Nl82NC1saW51eC1nbnUvb3BlbmJveC1hdXRvc3RhcnQgT1BFTkJPWApsaWdodGRtIC0tc2Vzc2lvbi1jaGlsZCAxMiAyMQovdXNyL3NiaW4vbGlnaHRkbQovc2Jpbi9pbml0Cg==:myhost:pawamoy:/dev/pts/1:L21lZGlhL3Bhd2Ftb3kvRGF0YS9naXQvc2hlbGxoaXN0Cg==:/bin/bash:1:builtin:0:echo "a
;b
;c" | wc -c

Note: later we could use CSV formatting, quoting strings and doubling double-quotes in those if any. It would make the file more readable for humans, and easily importable in other programs. See issue 26.

The previous example would look like this:

1510588139930150,1510588139936608,40701d9b-1807-4a3e-994b-dde68692aa14,"/bin/bash
/usr/bin/python /usr/bin/x-terminal-emulator
/usr/bin/openbox --startup /usr/lib/x86_64-linux-gnu/openbox-autostart OPENBOX
lightdm --session-child 12 21
/usr/sbin/lightdm
/sbin/init",myhost,pawamoy,/dev/pts/1,"/media/pawamoy/Data/git/shellhist",/bin/bash,1,builtin,0,"echo ""a
b
c"" | wc -c"

How we get the values

Start and stop time are obtained with date '+%s%N', return code is passed directly with $?, working directory is obtained with $PWD and command type with type for Bash and whence for Zsh.

Values for UUID, parents, hostname, and TTY are computed only once, when shellhistory.sh is sourced. Indeed they do not change during usage of the current shell process. Hostname and TTY are obtained through commands hostname and tty. UUID is generated with command uuidgen. Also note that UUID is exported in subshells so we know which shell is a subprocess of another, and so we are able to group shell processes by "sessions", a session being an opened terminal (be it a tab, window, pane or else). Parents are obtained with a function that iteratively greps ps result with PIDs (see shellhistory.sh).

Values for user, shell, and level are simply obtained through environment variables: $USER, $SHELL (though its use here is incorrect: see issue 24), and $SHLVL (also see issue 25).

The last command is obtained with the command fc. Using fc allows shellhistory to have the same behavior as your history:

  • if commands starting with spaces are ignored, they will be ignored in shellhistory as well.
  • same for duplicates (entering ls two or more times saves only the first instance). Note however that if you type the same command as the previous one in an other terminal, it will still be appended, unless you manage to synchronize your history between terminals, which is another story.

Additionally, if you enter an empty line, or hit Control-C before enter, nothing will be appended either. The trick behind this is to check the command number in the current history (see shellhistory.sh for technical details).

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].