├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── bin └── eg ├── eg-demo.gif ├── eg ├── __init__.py ├── __main__.py ├── color.py ├── config.py ├── core.py ├── eg_exec.py ├── examples │ ├── adb.md │ ├── aliases.json │ ├── awk.md │ ├── brctl.md │ ├── brew.md │ ├── cat.md │ ├── cd.md │ ├── chmod.md │ ├── chown.md │ ├── clip-view.md │ ├── cp.md │ ├── curl.md │ ├── cut.md │ ├── date.md │ ├── dd.md │ ├── df.md │ ├── diff.md │ ├── dig.md │ ├── du.md │ ├── echo.md │ ├── eg.md │ ├── expand.md │ ├── file.md │ ├── find.md │ ├── free.md │ ├── gcc.md │ ├── git.md │ ├── grep.md │ ├── gzip.md │ ├── head.md │ ├── hexdump.md │ ├── ifconfig.md │ ├── ip.md │ ├── keytool.md │ ├── kill.md │ ├── less.md │ ├── ln.md │ ├── locate.md │ ├── ls.md │ ├── mkdir.md │ ├── more.md │ ├── mv.md │ ├── nc.md │ ├── nice.md │ ├── od.md │ ├── patch.md │ ├── ping.md │ ├── prqlc.md │ ├── ps.md │ ├── pwd.md │ ├── renice.md │ ├── rm.md │ ├── rsync.md │ ├── scp.md │ ├── set.md │ ├── sort.md │ ├── strace.md │ ├── su.md │ ├── sudo.md │ ├── tail.md │ ├── tar.md │ ├── time.md │ ├── top.md │ ├── touch.md │ ├── tr.md │ ├── uniq.md │ ├── unzip.md │ ├── virtualenv.md │ ├── wc.md │ ├── wget.md │ ├── whatis.md │ ├── whereis.md │ ├── which.md │ ├── xargs.md │ └── zip.md ├── substitute.py └── util.py ├── eg_exec.py ├── setup.py ├── squeezed_output.png └── test ├── __init__.py ├── assets ├── egrc_nodata ├── egrc_single_substitution ├── egrc_withdata ├── find_example_substitute.md ├── pwd_squeezed.md └── pwd_unsqueezed.md ├── color_test.py ├── config_test.py ├── core_test.py ├── substitute_test.py └── util_test.py /.gitignore: -------------------------------------------------------------------------------- 1 | # use glob syntax 2 | syntax: glob 3 | 4 | # mac 5 | .DS_STORE 6 | 7 | # python 8 | *.pyc 9 | .ropeproject/** 10 | *.egg-info 11 | dist 12 | build 13 | 14 | .pytest_cache/ 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.4" 5 | - "3.5" 6 | - "3.6" 7 | - "3.7" 8 | 9 | # Command to run tests 10 | script: py.test 11 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Sam Sudar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eg 2 | 3 | > Useful examples at the command line. 4 | 5 | [![Build Status](https://travis-ci.org/srsudar/eg.svg?branch=master)](https://travis-ci.org/srsudar/eg) 6 | 7 | ## Overview 8 | 9 | `eg` provides examples of common uses of command line tools. 10 | 11 | Man pages are great. How does `find` work, again? `man find` will tell you, but 12 | you'll have to pore through all the flags and options just to figure out a 13 | basic usage. And what about using `tar`? Even with the man pages `tar` is 14 | [famously inscrutable without the googling for examples](http://xkcd.com/1168/). 15 | 16 | No more! 17 | 18 | `eg` will give you useful examples right at the command line. Think of it as a 19 | companion tool for `man`. 20 | 21 | > `eg` comes from _exempli gratia_, and is pronounced like the letters: "ee 22 | gee". 23 | 24 | ![eg Demo](./eg-demo.gif) 25 | 26 | 27 | ## Installation 28 | 29 | ### With `pip` 30 | 31 | ```shell 32 | pip install eg 33 | ``` 34 | 35 | ### With `brew` 36 | 37 | ```shell 38 | brew install eg-examples 39 | ``` 40 | 41 | ### Run from source 42 | 43 | Clone the repo and create a symlink to `eg_exec.py`. Make sure the location you 44 | choose for the symlink is on your path: 45 | 46 | 47 | ```shell 48 | git clone https://github.com/srsudar/eg ./ 49 | ln -s /absolute/path/to/eg-repo/eg_exec.py /usr/local/bin/eg 50 | ``` 51 | 52 | > Note that the location of `eg_exec.py` changed in version 0.1.x in order to 53 | support Python 3 as well as 2. Old symlinks will print a message explaining the 54 | change, but you'll have to update your links to point at the new location. Or 55 | you can install with `pip` or `brew`. 56 | 57 | `eg` doesn't ship with a binary. Dependencies are very modest and should not 58 | require you to install anything (other than [pytest](https://docs.pytest.org) if 59 | you want to run the tests). If you find otherwise, open an issue. 60 | 61 | 62 | ## Usage 63 | 64 | `eg ` 65 | 66 | `eg` takes an argument that is the name of a program for which it contains 67 | examples. 68 | 69 | `eg find` will provide examples for the `find` command. 70 | 71 | `eg --list` will show all the commands for which `eg` has examples. 72 | 73 | The complete usage statement, as shown by `eg --help`, is: 74 | 75 | ``` 76 | eg [-h] [-v] [-f CONFIG_FILE] [-e EXAMPLES_DIR] [-c CUSTOM_DIR] [-p PAGER_CMD] 77 | [-l] [--color] [-s] [--no-color] [program] 78 | ``` 79 | 80 | 81 | ## How it Works 82 | 83 | Files full of examples live in `examples/`. A naming convention is followed 84 | such that the file is the name of the tool with `.md`. E.g. the examples for 85 | `find` are in `find.md`. 86 | 87 | `eg find` will pipe the contents of `find.md` through `less` (although it tries 88 | to respect the `PAGER` environment variable). 89 | 90 | 91 | ## Configuration and Extension 92 | 93 | `eg` works out of the box, no configuration required. 94 | 95 | If you want to get fancy, however, `eg` can be fancy. 96 | 97 | For example, maybe a team member always sends you bzipped tarballs and you can 98 | never remember the flag for bzipping--why can't that guy just use gzip 99 | like everybody else? You can create an example for untarring and unzipping 100 | bzipped tarballs, stick it in a file called `tar.md`, and tell `eg` where to 101 | find it. 102 | 103 | The way to think about what `eg` does is that it takes a program name, for 104 | example `find`, and looks for files named `find.md` in the default and custom 105 | directories (including subdirectories). If it finds them, it pipes them through 106 | `less`, with the custom files at the top. Easy. 107 | 108 | The default and custom directories can be specified at the command line like 109 | so: 110 | 111 | ```shell 112 | eg --examples-dir='the/default/dir' --custom-dir='my/fancy/dir' find 113 | ``` 114 | 115 | Instead of doing this every time, you can define a configuration file. It must 116 | begin with a section called `eg-config` and can contain two keys: `custom-dir` 117 | and `examples-dir`. Here is an example of a valid config file: 118 | 119 | [eg-config] 120 | examples-dir = ~/examples-dir 121 | custom-dir = ~/my/fancy/custom/dir 122 | 123 | The config file is looked for first at `${XDG_CONFIG_HOME}/eg/egrc` and then at 124 | `~/.egrc`. You can also specify a different location at the command line like 125 | so: 126 | 127 | ```shell 128 | eg --config-file=myfile find 129 | ``` 130 | 131 | ## Editing Your Custom Examples 132 | 133 | If you want to edit one of your custom examples, you can edit the file directly 134 | or you can just use the `-e` or `--edit` flag. 135 | 136 | To edit your `find` examples, for example, you could say: 137 | 138 | ```shell 139 | eg -e find 140 | ``` 141 | 142 | This will dump you into an editor. The contents will be piped before the default 143 | examples the next time you run `eg find`. 144 | 145 | ## Formatting Output 146 | 147 | `eg` is highly customizable when it comes to output. You have three ways to try 148 | and customize what is piped out the pager, applied in this order: 149 | 150 | 1. Color 151 | 1. Squeezing out excess blank lines 152 | 1. Regex-based substitutions 153 | 154 | ### Color 155 | 156 | `eg` is colorful. The default colors were chosen to be pretty-ish while boring 157 | enough to not create problems for basic terminals. If you want to override 158 | these colors, you can do so in the egrc in a `color` section. 159 | 160 | Things that can be colored are: 161 | 162 | * `pound`: pound sign before headings 163 | * `heading`: the text of headings 164 | * `code`: anything indented four spaces other than a leading `$` 165 | * `prompt`: a `$` that is indented four spaces 166 | * `backticks`: anything between two backticks 167 | 168 | Values passed to these options must be string literals. This allows escape 169 | characters to be inserted as needed. An egrc with heading text a nice burnt 170 | orange might look like this: 171 | 172 | [eg-config] 173 | custom-dir = ~/my/fancy/custom/dir 174 | 175 | [color] 176 | heading = '\x1b[38;5;172m' 177 | 178 | To remove color altogether, for example if the color formatting is messing up 179 | your output somehow, you can either pass the `--no-color` flag to `eg`, or you 180 | can add an option to your egrc under the `eg-config` section like so: 181 | 182 | [eg-config] 183 | color = false 184 | 185 | 186 | ### Squeezing Blank Lines 187 | 188 | The example files use a lot of blank lines to try and be readable at a glance. 189 | Not everyone likes this many blank lines. If you hate all duplicate lines, you 190 | can use your favorite pager to remove all duplicate commands, like: 191 | 192 | ``` 193 | eg --pager-cmd 'less -sR' find 194 | ``` 195 | 196 | This will use `less -sR` to page, which will format color correctly (`-R`) and 197 | remove all duplicate blank lines (`-s`). 198 | 199 | `eg` also provides its own custom squeezed output format, removing all blank 200 | lines within a single example and only putting duplicate blank lines between 201 | sections. This can be configured at the command line with `--squeeze` or in 202 | the egrc with the `squeeze` option, like: 203 | 204 | [eg-config] 205 | squeeze = true 206 | 207 | Running `eg --squeeze find` removes excess newlines like so: 208 | 209 | ![Squeezed Output](./squeezed_output.png) 210 | 211 | 212 | ### Regex Substitutions 213 | 214 | Additional changes to the output can be accomplished with regular expressions 215 | and the egrc. Patterns and replacements are applied using Python's `re` module, 216 | so look to the [documentation](https://docs.python.org/2/library/re.html) for 217 | specifics. Substitutions should be specified in the egrc as a list with the 218 | syntax: `[pattern, replacement, compile_as_multiline]`. If 219 | `compile_as_multiline` is absent or `False`, the pattern will not be compiled 220 | as multiline, which affects the syntax expected by `re`. The `re.sub` method is 221 | called with the compiled pattern and `replacement`. 222 | 223 | Substitutions must be named and must be in the `[substitutions]` section of the 224 | egrc. For example, this would remove all the four-space indents beginning 225 | lines: 226 | 227 | [substitutions] 228 | remove-indents = ['^ ', '', True] 229 | 230 | This powerful feature can be used to perform complex transformations, including 231 | support additional coloring of output beyond what is supported natively by 232 | `eg`. If you wish there was an option to remove or add blank lines, color 233 | something new, remove section symbols, etc, this is a good place to start. 234 | 235 | If multiple substitutions are present, they are sorted by alphabetically by 236 | name before being applied. 237 | 238 | 239 | ## Paging 240 | 241 | By default, `eg` pages using `less -RMFXK`. The `-R` switch tells `less` to 242 | interpret ANSI escape sequences like color rather than showing them raw. `-M` 243 | tells it to show line number information in the bottom of the screen. `-F` to 244 | automatically quit if the entire example fits on the screen. `-X` tells it not 245 | to clear the screen. Finally, `-K` makes `less` exit in response to `Ctrl-C`. 246 | 247 | You can specify a different pager using the `--pager-cmd` option at the command 248 | line or the `pager-cmd` option in the egrc. If specified in the egrc, the value 249 | must be a string literal. For example, this egrc would use `cat` to page: 250 | 251 | [eg-config] 252 | pager-cmd = 'cat' 253 | 254 | `pydoc.pager()` does a lot of friendly error checking, so it might still be 255 | useful in some situations. If you want to use `pydoc.pager()` to page, you can 256 | pass the `pydoc.pager` as the `pager-cmd`. 257 | 258 | 259 | 260 | 261 | ## Format and Content of Examples 262 | 263 | Example documents are written in [markdown](http://daringfireball.net/projects/markdown/syntax). 264 | Documents in markdown are easily read at the command line as well as online. 265 | They all follow the same basic format. 266 | 267 | This section explains the format so that you better understand how to quickly 268 | grok the examples. 269 | 270 | Contributors should also pay close attention to these guidelines to keep 271 | examples consistent. 272 | 273 | 274 | ## Overview 275 | 276 | Anything indented four spaces or surrounded by backticks \`like this\` are 277 | meant to be input or output at the command line. A single line indented four 278 | spaces is a user-entered command. If a block is indented four spaces, only the 279 | lines beginning with `$` are user-entered--anything else is output. 280 | 281 | 282 | ### Name of the Command 283 | 284 | The first section heading should be simply the name of the tool. It should be 285 | followed by the most rudimentary examples. Users that are familiar with the 286 | command but just forget the precise syntax should be able to see what they need 287 | without scrolling. Example commands should be as real-world as possible, with 288 | file names and arguments as illustrative as possible. Examples for the `cp` 289 | command, for instance, might be: 290 | 291 | cp original.txt copy.txt 292 | 293 | Here the `.txt` extensions indicate that these are file names, while the names 294 | themselves make clear which is the already existing file and which will be the 295 | newly created copy. 296 | 297 | This section shouldn't show output and should not include the `$` to indicate 298 | that we are at the command line. 299 | 300 | **This section should be a quick glance for users that know what the tool does, 301 | know a basic usage is what they are trying to do, and are just looking for a 302 | reminder.** 303 | 304 | 305 | ### Basic Usage 306 | 307 | Next a Basic Usage section explains the most basic usage without using real 308 | file names. This section gives users that might not know the usual syntax a 309 | more abstract example than the first section. It is intended to provide a more 310 | useful explanation than the first entry in the man page, which typically shows 311 | all possible flags and arguments in a way that is not immediately obvious to 312 | new users of the command. The SYNOPSIS section of the man page for `cp`, for 313 | example, shows: 314 | 315 | cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory 316 | 317 | **The Basic Usage is intended to provide less verbose, more immediately 318 | practical versions of the man page's SYNOPSIS section.** 319 | 320 | Commands and flags that will affect the behavior are shown as would be entered 321 | in the command line, while user-entered filenames and arguments that do not 322 | alter the command's behaviors are shown in `< >`. Examples in the Basic Usage 323 | section for the `cp` command, for instance, might be: 324 | 325 | cp -R 326 | 327 | In this command the `cp -R` indicate the command and behavior and thus are not 328 | given in `< >`. Case-dependent components of the command, in this case the 329 | directory to be copied and the name of the copy, are surrounded with `< >`. 330 | Each is wrapped in separate `< >` to make clear that it is in fact two 331 | distinct arguments. 332 | 333 | ### Additional Sections 334 | 335 | Subsequent subsections can be added for common uses of the tools, as 336 | appropriate. 337 | 338 | ### Formatting 339 | 340 | Although markdown is readable, it can still be tricky without syntax 341 | highlighting. We use spacing to help the eye. 342 | 343 | 1. All code snippets are followed by at two blank lines, unless overruled by 2. 344 | 345 | 2. Each line beginning a section (i.e. the first character on the line is `#`) 346 | should be preceded by exactly three lines. 347 | 348 | 3. Files should end with two blank lines. 349 | 350 | 4. Lines should not exceed 80 characters, unless to accommodate a necessarily 351 | long command or long output. 352 | 353 | 354 | ## Contributing 355 | 356 | Additions of new tools and new or more useful examples are welcome. `eg` should 357 | be something that people want to have on their machines. If it has a man page, 358 | it should be included in `eg`. 359 | 360 | Please read the Format of Examples section and review existing example files to 361 | get a feel for how `eg` pages should be structured. 362 | 363 | If you find yourself turning to the internet for the same command again and 364 | again, consider adding it to the examples. 365 | 366 | `eg` examples do not intend to replace man pages! `man` is useful in its own 367 | right. `eg` should provide quick examples in practice. Do not list all the 368 | flags for the sake of listing them. Assume that users will have `man` 369 | available. 370 | 371 | 372 | ### Building and Running Tests 373 | 374 | `eg` depends only on standard libraries and Python 2.x/3.x, so building should 375 | be a simple matter of cloning the repo and running the executable `eg/eg.py`. 376 | 377 | `eg` uses pytest for testing, so you'll have to have it installed to run tests. 378 | Once you have it, run `py.test` from **the root directory of the repo**. 379 | 380 | Tests should always be expected to pass. If they fail, please open an issue, 381 | even if only so that we can better elucidate `eg`'s dependencies. 382 | 383 | 384 | ## Grace Hopper Approves 385 | 386 | Alias `eg` to `woman` for something that is like `man` but a little more 387 | practical: 388 | 389 | ```shell 390 | $ alias woman=eg 391 | $ man find 392 | $ woman find 393 | ``` 394 | -------------------------------------------------------------------------------- /bin/eg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from eg import core 4 | 5 | 6 | if __name__ == '__main__': 7 | core.run_eg() 8 | -------------------------------------------------------------------------------- /eg-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srsudar/eg/83e069c9e4f99b1052b69546726919a884138715/eg-demo.gif -------------------------------------------------------------------------------- /eg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srsudar/eg/83e069c9e4f99b1052b69546726919a884138715/eg/__init__.py -------------------------------------------------------------------------------- /eg/__main__.py: -------------------------------------------------------------------------------- 1 | from eg import core 2 | 3 | 4 | core.run_eg() 5 | -------------------------------------------------------------------------------- /eg/color.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | 4 | 5 | class EgColorizer(): 6 | 7 | def __init__(self, color_config): 8 | self.color_config = color_config 9 | 10 | def colorize_heading(self, text): 11 | return self._color_helper( 12 | text, 13 | '(^#+)(.*)$', 14 | ( 15 | self.color_config.pound + 16 | r'\1' + 17 | self.color_config.pound_reset + 18 | self.color_config.heading + 19 | r'\2' + 20 | self.color_config.heading_reset 21 | ) 22 | ) 23 | 24 | def colorize_block_indent(self, text): 25 | return self._color_helper( 26 | text, 27 | '^ (\$?)(.*)$', 28 | ( 29 | ' ' + 30 | self.color_config.prompt + 31 | r'\1' + 32 | self.color_config.prompt_reset + 33 | self.color_config.code + 34 | r'\2' + 35 | self.color_config.code_reset 36 | ) 37 | ) 38 | 39 | def colorize_backticks(self, text): 40 | # In this case we are going to go line by line, as we need to handle 41 | # the somewhat special case to avoid backticks in block indents. 42 | lines = text.split('\n') 43 | output = [] 44 | 45 | for line in lines: 46 | if (line.startswith(' ')): 47 | # We are in a block indent. In this special case we do not want 48 | # to colorize backticks, as we are using backticks in a piece 49 | # of example code that should not be colorized. 50 | output.append(line) 51 | else: 52 | colorized = self._color_helper( 53 | line, 54 | '`([^`]+)`', 55 | ( 56 | '`' + 57 | self.color_config.backticks + 58 | r'\1' + 59 | self.color_config.backticks_reset + 60 | '`' 61 | ) 62 | ) 63 | output.append(colorized) 64 | 65 | return '\n'.join(output) 66 | 67 | def colorize_text(self, text): 68 | """Colorize the text.""" 69 | # As originally implemented, this method acts upon all the contents of 70 | # the file as a single string using the MULTILINE option of the re 71 | # package. I believe this was ostensibly for performance reasons, but 72 | # it has a few side effects that are less than ideal. It's non-trivial 73 | # to avoid some substitutions based on other matches using this 74 | # technique, for example. In the case of block indents, e.g., backticks 75 | # that occur in the example ($ pwd is `pwd`) should not be escaped. 76 | # With the MULTILINE flag that is not simple. colorize_backticks() is 77 | # currently operating on a line by line basis and special casing for 78 | # this scenario. If these special cases proliferate, the line breaking 79 | # should occur here in order to minimize the number of iterations. 80 | 81 | result = text 82 | result = self.colorize_heading(result) 83 | result = self.colorize_block_indent(result) 84 | result = self.colorize_backticks(result) 85 | return result 86 | 87 | def _color_helper(self, text, pattern, repl): 88 | # < 2.7 didn't have the flags named argument. 89 | if sys.version_info < (2, 7): 90 | compiled_pattern = re.compile(pattern, re.MULTILINE) 91 | return re.sub( 92 | compiled_pattern, 93 | repl, 94 | text 95 | ) 96 | else: 97 | return re.sub( 98 | pattern, 99 | repl, 100 | text, 101 | flags=re.MULTILINE 102 | ) 103 | -------------------------------------------------------------------------------- /eg/config.py: -------------------------------------------------------------------------------- 1 | import ast 2 | import os 3 | 4 | from collections import namedtuple 5 | from eg import substitute 6 | 7 | # Support Python 2 and 3. 8 | try: 9 | import ConfigParser 10 | except: 11 | from configparser import ConfigParser 12 | 13 | 14 | # Environment variables to try for accessing an editor. 15 | ENV_VISUAL = 'VISUAL' 16 | ENV_EDITOR = 'EDITOR' 17 | 18 | # The directory containing example files, relative to the eg executable. The 19 | # directory structure is assumed to be: 20 | # eg.py* 21 | # eg_util.py 22 | # examples/ 23 | # |- cp.md, etc 24 | DEFAULT_EXAMPLES_DIR = os.path.join(os.path.dirname(__file__), 'examples') 25 | DEFAULT_CUSTOM_DIR = None 26 | DEFAULT_EGRC_PATH = os.path.join('~', '.egrc') 27 | DEFAULT_USE_COLOR = True 28 | 29 | # We're using less -R to support color on Unix machines, which by default don't 30 | # let their output from less be colorized. Other options: 31 | # -M: show line number information in the bottom of screen (current/pages X%) 32 | # -F: automatically quit less if the entire example fits on the first screen 33 | # -X: do not use init/deinit strings; in other words: do not clear the screen 34 | # -K: exit less in response to Ctrl-C 35 | DEFAULT_PAGER_CMD = 'less -RMFXK' 36 | 37 | DEFAULT_SQUEEZE = False 38 | DEFAULT_EDITOR_CMD = None 39 | 40 | # We need this just because the ConfigParser library requires it. 41 | DEFAULT_SECTION = 'eg-config' 42 | 43 | # Properties in the rc file. 44 | EG_EXAMPLES_DIR = 'examples-dir' 45 | CUSTOM_EXAMPLES_DIR = 'custom-dir' 46 | USE_COLOR = 'color' 47 | PAGER_CMD = 'pager-cmd' 48 | SQUEEZE = 'squeeze' 49 | EDITOR_CMD = 'editor-cmd' 50 | 51 | # A basic struct containing configuration values. 52 | # examples_dir: path to the directory of examples that ship with eg 53 | # custom_dir: path to the directory where custom examples are found 54 | # use_color: True if we should colorize output, else False 55 | # color_config: the config object specifying which colors to use 56 | # pager_cmd: the command to use to page output 57 | # squeeze: True if we should remove blank lines, else false 58 | # subs: a list of Substitution objects to apply to the output 59 | Config = namedtuple( 60 | 'Config', 61 | [ 62 | 'examples_dir', 63 | 'custom_dir', 64 | 'use_color', 65 | 'color_config', 66 | 'pager_cmd', 67 | 'squeeze', 68 | 'subs', 69 | 'editor_cmd', 70 | ] 71 | ) 72 | 73 | # A struct with color values 74 | ColorConfig = namedtuple( 75 | 'ColorConfig', 76 | [ 77 | 'pound', 78 | 'heading', 79 | 'code', 80 | 'backticks', 81 | 'prompt', 82 | 'pound_reset', 83 | 'heading_reset', 84 | 'code_reset', 85 | 'backticks_reset', 86 | 'prompt_reset' 87 | ] 88 | ) 89 | 90 | # Default colors. These are intentionally simple to try and accomodate more 91 | # terminals. This is mostly envisioned as a unix tool, so we're not going to 92 | # worry about windows output. 93 | _BRIGHT = '\x1b[1m' 94 | _BLACK = '\x1b[30m' 95 | _RED = '\x1b[31m' 96 | _CYAN = '\x1b[36m' 97 | _GREEN = '\x1b[32m' 98 | _BLUE = '\x1b[34m' 99 | _RESET_ALL = '\x1b[0m' 100 | DEFAULT_COLOR_POUND = _BLACK + _BRIGHT 101 | DEFAULT_COLOR_HEADING = _RED + _BRIGHT 102 | DEFAULT_COLOR_PROMPT = _CYAN + _BRIGHT 103 | DEFAULT_COLOR_CODE = _GREEN + _BRIGHT 104 | DEFAULT_COLOR_BACKTICKS = _BLUE + _BRIGHT 105 | DEFAULT_COLOR_POUND_RESET = _RESET_ALL 106 | DEFAULT_COLOR_HEADING_RESET = _RESET_ALL 107 | DEFAULT_COLOR_PROMPT_RESET = _RESET_ALL 108 | DEFAULT_COLOR_CODE_RESET = _RESET_ALL 109 | DEFAULT_COLOR_BACKTICKS_RESET = _RESET_ALL 110 | 111 | CONFIG_NAMES = ColorConfig( 112 | pound='pound', 113 | heading='heading', 114 | code='code', 115 | backticks='backticks', 116 | prompt='prompt', 117 | pound_reset='pound_reset', 118 | heading_reset='heading_reset', 119 | code_reset='code_reset', 120 | backticks_reset='backticks_reset', 121 | prompt_reset='prompt_reset' 122 | ) 123 | 124 | # The name of the section in the config file containing colors. 125 | COLOR_SECTION = 'color' 126 | 127 | # The name of the section in the config file containing substitutions. 128 | SUBSTITUTION_SECTION = 'substitutions' 129 | 130 | 131 | def inform_if_paths_invalid(egrc_path, examples_dir, custom_dir, debug=True): 132 | """ 133 | If egrc_path, examples_dir, or custom_dir is truthy and debug is True, 134 | informs the user that a path is not set. 135 | 136 | This should be used to verify input arguments from the command line. 137 | """ 138 | if (not debug): 139 | return 140 | 141 | if (egrc_path): 142 | _inform_if_path_does_not_exist(egrc_path) 143 | 144 | if (examples_dir): 145 | _inform_if_path_does_not_exist(examples_dir) 146 | 147 | if (custom_dir): 148 | _inform_if_path_does_not_exist(custom_dir) 149 | 150 | 151 | def get_egrc_config(cli_egrc_path): 152 | """ 153 | Return a Config namedtuple based on the contents of the egrc. 154 | 155 | If the egrc is not present, it returns an empty default Config. 156 | 157 | This method tries to use the egrc at cli_egrc_path, then XDG_CONFIG_HOME, 158 | and then the default path. 159 | 160 | cli_egrc_path: the path to the egrc as given on the command line via 161 | --config-file 162 | """ 163 | # We have to be a little crafty here, because we want to support people 164 | # having an XDG_CONFIG_HOME dir that doesn't contain the config file. This 165 | # will allow a smooth transition for XDG users that started using eg when we 166 | # only supported `~/.egrc`. We don't want to suddenly break for them when we 167 | # add new support. 168 | config_path = '' 169 | 170 | if cli_egrc_path: 171 | # cli values always win 172 | config_path = get_expanded_path(cli_egrc_path) 173 | 174 | if config_path == '': 175 | # Try for the xdg config. 176 | # The freedesktop.org spec says '$HOME/.config' should be used if the 177 | # environment variable is not set or is empty. os.getenv() will be falsey 178 | # if it is either not set (None) or an empty string. 179 | default_xdg_dir = os.path.join('~', '.config') 180 | xdg_home_dir = os.getenv('XDG_CONFIG_HOME') or default_xdg_dir 181 | 182 | xdg_config_path = os.path.join(xdg_home_dir, 'eg', 'egrc') 183 | xdg_config_path = get_expanded_path(xdg_config_path) 184 | if os.path.isfile(xdg_config_path): 185 | config_path = xdg_config_path 186 | 187 | if config_path == '': 188 | # Fall back to our home directory. 189 | config_path = get_expanded_path(DEFAULT_EGRC_PATH) 190 | 191 | 192 | # Start as if nothing was defined in the egrc. 193 | egrc_config = get_empty_config() 194 | 195 | if os.path.isfile(config_path): 196 | egrc_config = get_config_tuple_from_egrc(config_path) 197 | 198 | return egrc_config 199 | 200 | 201 | def get_resolved_config( 202 | egrc_path, 203 | examples_dir, 204 | custom_dir, 205 | use_color, 206 | pager_cmd, 207 | squeeze, 208 | debug=True, 209 | ): 210 | """ 211 | Create a Config namedtuple. Passed in values will override defaults. 212 | 213 | This function is responsible for producing a Config that is correct for the 214 | passed in arguments. In general, it prefers first command line options, 215 | then values from the egrc, and finally defaults. 216 | 217 | examples_dir and custom_dir when returned from this function are fully 218 | expanded. 219 | """ 220 | # Call this with the passed in values, NOT the resolved values. We are 221 | # informing the caller only if values passed in at the command line are 222 | # invalid. If you pass a path to a nonexistent egrc, for example, it's 223 | # helpful to know. If you don't have an egrc, and thus one isn't found 224 | # later at the default location, we don't want to notify them. 225 | inform_if_paths_invalid(egrc_path, examples_dir, custom_dir) 226 | 227 | # Expand the paths so we can use them with impunity later. 228 | examples_dir = get_expanded_path(examples_dir) 229 | custom_dir = get_expanded_path(custom_dir) 230 | 231 | # The general rule is: caller-defined, egrc-defined, defaults. We'll try 232 | # and get all three then use get_priority to choose the right one. 233 | 234 | egrc_config = get_egrc_config(egrc_path) 235 | 236 | resolved_examples_dir = get_priority( 237 | examples_dir, 238 | egrc_config.examples_dir, 239 | DEFAULT_EXAMPLES_DIR 240 | ) 241 | resolved_examples_dir = get_expanded_path(resolved_examples_dir) 242 | 243 | resolved_custom_dir = get_priority( 244 | custom_dir, 245 | egrc_config.custom_dir, 246 | DEFAULT_CUSTOM_DIR 247 | ) 248 | resolved_custom_dir = get_expanded_path(resolved_custom_dir) 249 | 250 | resolved_use_color = get_priority( 251 | use_color, 252 | egrc_config.use_color, 253 | DEFAULT_USE_COLOR 254 | ) 255 | 256 | resolved_pager_cmd = get_priority( 257 | pager_cmd, 258 | egrc_config.pager_cmd, 259 | DEFAULT_PAGER_CMD 260 | ) 261 | 262 | # There is no command line option for this, so in this case we will use the 263 | # priority: egrc, environment, DEFAULT. 264 | environment_editor_cmd = get_editor_cmd_from_environment() 265 | resolved_editor_cmd = get_priority( 266 | egrc_config.editor_cmd, 267 | environment_editor_cmd, 268 | DEFAULT_EDITOR_CMD 269 | ) 270 | 271 | color_config = None 272 | if resolved_use_color: 273 | default_color_config = get_default_color_config() 274 | color_config = merge_color_configs( 275 | egrc_config.color_config, 276 | default_color_config 277 | ) 278 | 279 | resolved_squeeze = get_priority( 280 | squeeze, 281 | egrc_config.squeeze, 282 | DEFAULT_SQUEEZE 283 | ) 284 | 285 | # Pass in None, as subs can't be specified at the command line. 286 | resolved_subs = get_priority( 287 | None, 288 | egrc_config.subs, 289 | get_default_subs() 290 | ) 291 | 292 | result = Config( 293 | examples_dir=resolved_examples_dir, 294 | custom_dir=resolved_custom_dir, 295 | color_config=color_config, 296 | use_color=resolved_use_color, 297 | pager_cmd=resolved_pager_cmd, 298 | editor_cmd=resolved_editor_cmd, 299 | squeeze=resolved_squeeze, 300 | subs=resolved_subs, 301 | ) 302 | 303 | return result 304 | 305 | 306 | def get_config_tuple_from_egrc(egrc_path): 307 | """ 308 | Create a Config named tuple from the values specified in the .egrc. Expands 309 | any paths as necessary. 310 | 311 | egrc_path must exist and point a file. 312 | 313 | If not present in the .egrc, properties of the Config are returned as None. 314 | """ 315 | with open(egrc_path, 'r') as egrc: 316 | try: 317 | config = ConfigParser.RawConfigParser() 318 | except AttributeError: 319 | config = ConfigParser() 320 | # Support Python 3.12 and above. 321 | try: 322 | config.readfp(egrc) 323 | except AttributeError: 324 | config.read_file(egrc) 325 | 326 | # default to None 327 | examples_dir = None 328 | custom_dir = None 329 | use_color = None 330 | pager_cmd = None 331 | squeeze = None 332 | subs = None 333 | editor_cmd = None 334 | 335 | if config.has_option(DEFAULT_SECTION, EG_EXAMPLES_DIR): 336 | examples_dir = config.get(DEFAULT_SECTION, EG_EXAMPLES_DIR) 337 | examples_dir = get_expanded_path(examples_dir) 338 | 339 | if config.has_option(DEFAULT_SECTION, CUSTOM_EXAMPLES_DIR): 340 | custom_dir = config.get(DEFAULT_SECTION, CUSTOM_EXAMPLES_DIR) 341 | custom_dir = get_expanded_path(custom_dir) 342 | 343 | if config.has_option(DEFAULT_SECTION, USE_COLOR): 344 | use_color_raw = config.get(DEFAULT_SECTION, USE_COLOR) 345 | use_color = _parse_bool_from_raw_egrc_value(use_color_raw) 346 | 347 | if config.has_option(DEFAULT_SECTION, PAGER_CMD): 348 | pager_cmd_raw = config.get(DEFAULT_SECTION, PAGER_CMD) 349 | pager_cmd = ast.literal_eval(pager_cmd_raw) 350 | 351 | if config.has_option(DEFAULT_SECTION, EDITOR_CMD): 352 | editor_cmd_raw = config.get(DEFAULT_SECTION, EDITOR_CMD) 353 | editor_cmd = ast.literal_eval(editor_cmd_raw) 354 | 355 | color_config = get_custom_color_config_from_egrc(config) 356 | 357 | if config.has_option(DEFAULT_SECTION, SQUEEZE): 358 | squeeze_raw = config.get(DEFAULT_SECTION, SQUEEZE) 359 | squeeze = _parse_bool_from_raw_egrc_value(squeeze_raw) 360 | 361 | if config.has_section(SUBSTITUTION_SECTION): 362 | subs = get_substitutions_from_config(config) 363 | 364 | return Config( 365 | examples_dir=examples_dir, 366 | custom_dir=custom_dir, 367 | color_config=color_config, 368 | use_color=use_color, 369 | pager_cmd=pager_cmd, 370 | editor_cmd=editor_cmd, 371 | squeeze=squeeze, 372 | subs=subs, 373 | ) 374 | 375 | 376 | def get_expanded_path(path): 377 | """Expand ~ and variables in a path. If path is not truthy, return None.""" 378 | if path: 379 | result = path 380 | result = os.path.expanduser(result) 381 | result = os.path.expandvars(result) 382 | return result 383 | else: 384 | return None 385 | 386 | 387 | def get_editor_cmd_from_environment(): 388 | """ 389 | Gets and editor command from environment variables. 390 | 391 | It first tries $VISUAL, then $EDITOR, following the same order git uses 392 | when it looks up edits. If neither is available, it returns None. 393 | """ 394 | result = os.getenv(ENV_VISUAL) 395 | if (not result): 396 | result = os.getenv(ENV_EDITOR) 397 | return result 398 | 399 | 400 | def get_priority(first, second, third): 401 | """ 402 | Return the items based on priority and their truthiness. If first is 403 | present, it will be returned. If only second and third, second will be 404 | returned. If all three are absent, will return None. 405 | """ 406 | if first is not None: 407 | return first 408 | elif second is not None: 409 | return second 410 | else: 411 | return third 412 | 413 | 414 | def _inform_if_path_does_not_exist(path): 415 | """ 416 | If the path does not exist, print a message saying so. This is intended to 417 | be helpful to users if they specify a custom path that eg cannot find. 418 | """ 419 | expanded_path = get_expanded_path(path) 420 | if not os.path.exists(expanded_path): 421 | print('Could not find custom path at: {}'.format(expanded_path)) 422 | 423 | 424 | def get_custom_color_config_from_egrc(config): 425 | """ 426 | Get the ColorConfig from the egrc config object. Any colors not defined 427 | will be None. 428 | """ 429 | pound = _get_color_from_config(config, CONFIG_NAMES.pound) 430 | heading = _get_color_from_config(config, CONFIG_NAMES.heading) 431 | code = _get_color_from_config(config, CONFIG_NAMES.code) 432 | backticks = _get_color_from_config(config, CONFIG_NAMES.backticks) 433 | prompt = _get_color_from_config(config, CONFIG_NAMES.prompt) 434 | pound_reset = _get_color_from_config(config, CONFIG_NAMES.pound_reset) 435 | heading_reset = _get_color_from_config( 436 | config, 437 | CONFIG_NAMES.heading_reset 438 | ) 439 | code_reset = _get_color_from_config(config, CONFIG_NAMES.code_reset) 440 | backticks_reset = _get_color_from_config( 441 | config, 442 | CONFIG_NAMES.backticks_reset 443 | ) 444 | prompt_reset = _get_color_from_config(config, CONFIG_NAMES.prompt_reset) 445 | 446 | result = ColorConfig( 447 | pound=pound, 448 | heading=heading, 449 | code=code, 450 | backticks=backticks, 451 | prompt=prompt, 452 | pound_reset=pound_reset, 453 | heading_reset=heading_reset, 454 | code_reset=code_reset, 455 | backticks_reset=backticks_reset, 456 | prompt_reset=prompt_reset 457 | ) 458 | 459 | return result 460 | 461 | 462 | def _get_color_from_config(config, option): 463 | """ 464 | Helper method to uet an option from the COLOR_SECTION of the config. 465 | 466 | Returns None if the value is not present. If the value is present, it tries 467 | to parse the value as a raw string literal, allowing escape sequences in 468 | the egrc. 469 | """ 470 | if not config.has_option(COLOR_SECTION, option): 471 | return None 472 | else: 473 | return ast.literal_eval(config.get(COLOR_SECTION, option)) 474 | 475 | 476 | def parse_substitution_from_list(list_rep): 477 | """ 478 | Parse a substitution from the list representation in the config file. 479 | """ 480 | # We are expecting [pattern, replacement [, is_multiline]] 481 | if type(list_rep) is not list: 482 | raise SyntaxError('Substitution must be a list') 483 | if len(list_rep) < 2: 484 | raise SyntaxError('Substitution must be a list of size 2') 485 | 486 | pattern = list_rep[0] 487 | replacement = list_rep[1] 488 | 489 | # By default, substitutions are not multiline. 490 | is_multiline = False 491 | if (len(list_rep) > 2): 492 | is_multiline = list_rep[2] 493 | if type(is_multiline) is not bool: 494 | raise SyntaxError('is_multiline must be a boolean') 495 | 496 | result = substitute.Substitution(pattern, replacement, is_multiline) 497 | return result 498 | 499 | 500 | def get_substitutions_from_config(config): 501 | """ 502 | Return a list of Substitution objects from the config, sorted 503 | alphabetically by pattern name. Returns an empty list if no Substitutions 504 | are specified. If there are problems parsing the values, a help message 505 | will be printed and an error will be thrown. 506 | """ 507 | result = [] 508 | pattern_names = config.options(SUBSTITUTION_SECTION) 509 | pattern_names.sort() 510 | for name in pattern_names: 511 | pattern_val = config.get(SUBSTITUTION_SECTION, name) 512 | list_rep = ast.literal_eval(pattern_val) 513 | substitution = parse_substitution_from_list(list_rep) 514 | result.append(substitution) 515 | return result 516 | 517 | 518 | def get_default_color_config(): 519 | """Get a color config object with all the defaults.""" 520 | result = ColorConfig( 521 | pound=DEFAULT_COLOR_POUND, 522 | heading=DEFAULT_COLOR_HEADING, 523 | code=DEFAULT_COLOR_CODE, 524 | backticks=DEFAULT_COLOR_BACKTICKS, 525 | prompt=DEFAULT_COLOR_PROMPT, 526 | pound_reset=DEFAULT_COLOR_POUND_RESET, 527 | heading_reset=DEFAULT_COLOR_HEADING_RESET, 528 | code_reset=DEFAULT_COLOR_CODE_RESET, 529 | backticks_reset=DEFAULT_COLOR_BACKTICKS_RESET, 530 | prompt_reset=DEFAULT_COLOR_PROMPT_RESET 531 | ) 532 | return result 533 | 534 | 535 | def get_empty_config(): 536 | """ 537 | Return an empty Config object with no options set. 538 | """ 539 | empty_color_config = get_empty_color_config() 540 | result = Config( 541 | examples_dir=None, 542 | custom_dir=None, 543 | color_config=empty_color_config, 544 | use_color=None, 545 | pager_cmd=None, 546 | editor_cmd=None, 547 | squeeze=None, 548 | subs=None 549 | ) 550 | return result 551 | 552 | 553 | def get_empty_color_config(): 554 | """Return a color_config with all values set to None.""" 555 | empty_color_config = ColorConfig( 556 | pound=None, 557 | heading=None, 558 | code=None, 559 | backticks=None, 560 | prompt=None, 561 | pound_reset=None, 562 | heading_reset=None, 563 | code_reset=None, 564 | backticks_reset=None, 565 | prompt_reset=None 566 | ) 567 | return empty_color_config 568 | 569 | 570 | def merge_color_configs(first, second): 571 | """ 572 | Merge the color configs. 573 | 574 | Values in the first will overwrite non-None values in the second. 575 | """ 576 | # We have to get the desired values first and simultaneously, as nametuple 577 | # is immutable. 578 | pound = get_priority(first.pound, second.pound, None) 579 | heading = get_priority(first.heading, second.heading, None) 580 | code = get_priority(first.code, second.code, None) 581 | backticks = get_priority(first.backticks, second.backticks, None) 582 | prompt = get_priority(first.prompt, second.prompt, None) 583 | pound_reset = get_priority( 584 | first.pound_reset, 585 | second.pound_reset, 586 | None 587 | ) 588 | heading_reset = get_priority( 589 | first.heading_reset, 590 | second.heading_reset, 591 | None 592 | ) 593 | code_reset = get_priority( 594 | first.code_reset, 595 | second.code_reset, 596 | None 597 | ) 598 | backticks_reset = get_priority( 599 | first.backticks_reset, 600 | second.backticks_reset, 601 | None 602 | ) 603 | prompt_reset = get_priority( 604 | first.prompt_reset, 605 | second.prompt_reset, 606 | None 607 | ) 608 | 609 | result = ColorConfig( 610 | pound=pound, 611 | heading=heading, 612 | code=code, 613 | backticks=backticks, 614 | prompt=prompt, 615 | pound_reset=pound_reset, 616 | heading_reset=heading_reset, 617 | code_reset=code_reset, 618 | backticks_reset=backticks_reset, 619 | prompt_reset=prompt_reset 620 | ) 621 | 622 | return result 623 | 624 | 625 | def _parse_bool_from_raw_egrc_value(raw_value): 626 | """ 627 | Parse the value from an egrc into a boolean. 628 | """ 629 | truthy_values = ['True', 'true'] 630 | return raw_value in truthy_values 631 | 632 | 633 | def get_default_subs(): 634 | """ 635 | Get the list of default substitutions. We're not storing this as a module 636 | level object like the other DEFAULT values, as lists are mutable, and we 637 | could get into trouble by modifying that list and not having it remain 638 | empty as might be expected. 639 | """ 640 | return [] 641 | -------------------------------------------------------------------------------- /eg/core.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import pydoc 3 | import sys 4 | 5 | from eg import config 6 | from eg import util 7 | 8 | 9 | _MSG_BAD_ARGS = 'specify a program or pass the --list or --version flags' 10 | 11 | 12 | def _show_version(): 13 | """Show the version string.""" 14 | print(util.VERSION) 15 | 16 | 17 | def _show_list_message(resolved_config): 18 | """ 19 | Show the message for when a user has passed in --list. 20 | """ 21 | # Show what's available. 22 | supported_programs = util.get_list_of_all_supported_commands( 23 | resolved_config 24 | ) 25 | msg_line_1 = 'Legend: ' 26 | msg_line_2 = ( 27 | ' ' + 28 | util.FLAG_ONLY_CUSTOM + 29 | ' only custom files' 30 | ) 31 | msg_line_3 = ( 32 | ' ' + 33 | util.FLAG_CUSTOM_AND_DEFAULT + 34 | ' custom and default files' 35 | ) 36 | msg_line_4 = ' ' + ' only default files (no symbol)' 37 | msg_line_5 = '' 38 | msg_line_6 = 'Programs supported by eg: ' 39 | 40 | preamble = [ 41 | msg_line_1, 42 | msg_line_2, 43 | msg_line_3, 44 | msg_line_4, 45 | msg_line_5, 46 | msg_line_6 47 | ] 48 | 49 | complete_message = '\n'.join(preamble) 50 | complete_message += '\n' + '\n'.join(supported_programs) 51 | 52 | pydoc.pager(complete_message) 53 | 54 | 55 | def _handle_no_editor(): 56 | """ 57 | Handles the case where a user has requested to edit a file the custom 58 | examples for a command but we haven't been able to resolve a command to 59 | open an editor. 60 | """ 61 | print( 62 | 'could not find editor: set $VISUAL, $EDITOR, or specify in .egrc' 63 | ) 64 | 65 | 66 | def _parse_arguments(): 67 | """ 68 | Constructs and parses the command line arguments for eg. Returns an args 69 | object as returned by parser.parse_args(). 70 | """ 71 | parser = argparse.ArgumentParser( 72 | description='eg provides examples of common command usage.' 73 | ) 74 | 75 | parser.add_argument( 76 | '-v', 77 | '--version', 78 | action='store_true', 79 | help='Display version information about eg' 80 | ) 81 | 82 | parser.add_argument( 83 | '-f', 84 | '--config-file', 85 | help='Path to the .egrc file, if it is not in the default location.' 86 | ) 87 | 88 | parser.add_argument( 89 | '-e', 90 | '--edit', 91 | action='store_true', 92 | help="""Edit the custom examples for the given command. If editor-cmd 93 | is not set in your .egrc and $VISUAL and $EDITOR are not set, prints a 94 | message and does nothing.""" 95 | ) 96 | 97 | parser.add_argument( 98 | '--examples-dir', 99 | help='The location to the examples/ dir that ships with eg' 100 | ) 101 | 102 | parser.add_argument( 103 | '-c', 104 | '--custom-dir', 105 | help='Path to a directory containing user-defined examples.' 106 | ) 107 | 108 | parser.add_argument( 109 | '-p', 110 | '--pager-cmd', 111 | help='String literal that will be invoked to page output.' 112 | ) 113 | 114 | parser.add_argument( 115 | '-l', 116 | '--list', 117 | action='store_true', 118 | help='Show all the programs with eg entries.' 119 | ) 120 | 121 | parser.add_argument( 122 | '--color', 123 | action='store_true', 124 | dest='use_color', 125 | default=None, 126 | help='Colorize output.' 127 | ) 128 | 129 | parser.add_argument( 130 | '-s', 131 | '--squeeze', 132 | action='store_true', 133 | default=None, 134 | help='Show fewer blank lines in output.' 135 | ) 136 | 137 | parser.add_argument( 138 | '--no-color', 139 | action='store_false', 140 | dest='use_color', 141 | help='Do not colorize output.' 142 | ) 143 | 144 | parser.add_argument( 145 | 'program', 146 | nargs='?', 147 | help='The program for which to display examples.' 148 | ) 149 | 150 | args = parser.parse_args() 151 | 152 | if len(sys.argv) < 2: 153 | # Too few arguments. We can't specify this using argparse alone, so we 154 | # have to manually check. 155 | parser.print_help() 156 | parser.exit() 157 | elif not args.version and not args.list and not args.program: 158 | parser.error(_MSG_BAD_ARGS) 159 | else: 160 | return args 161 | 162 | 163 | def run_eg(): 164 | args = _parse_arguments() 165 | 166 | resolved_config = config.get_resolved_config( 167 | egrc_path=args.config_file, 168 | examples_dir=args.examples_dir, 169 | custom_dir=args.custom_dir, 170 | use_color=args.use_color, 171 | pager_cmd=args.pager_cmd, 172 | squeeze=args.squeeze 173 | ) 174 | 175 | if args.list: 176 | _show_list_message(resolved_config) 177 | elif args.version: 178 | _show_version() 179 | elif args.edit: 180 | if not resolved_config.editor_cmd: 181 | _handle_no_editor() 182 | else: 183 | util.edit_custom_examples(args.program, resolved_config) 184 | else: 185 | util.handle_program(args.program, resolved_config) 186 | 187 | 188 | # We want people to be able to use eg without pip, by so we'll allow this to be 189 | # invoked directly. 190 | if __name__ == '__main__': 191 | run_eg() 192 | -------------------------------------------------------------------------------- /eg/eg_exec.py: -------------------------------------------------------------------------------- 1 | # In eg 0.0.x, this file could be used to invoke eg directly, without installing 2 | # via pip. Eg 0.1.x switched to also support python 3. This meant changing the 3 | # way imports were working, which meant this script had to move up a level to be 4 | # a sibling of the eg module directory. This file will exist for a time in order 5 | # to try and give a more friendly error for people that are using the symlink 6 | # approach. This warning will eventually disappear in a future version of eg. 7 | 8 | DEPRECATION_WARNING = """ 9 | You are invoking eg via the script at /eg/eg_exec.py. This file has 10 | been deprecated in order to work with both python 2 and 3. 11 | 12 | Please instead invoke /eg_exec.py, or install with pip. 13 | 14 | If you're using a symlink and need to update it, try something like the 15 | following: 16 | 17 | rm `which eg` 18 | ln -s /eg_exec.py /usr/local/bin/eg 19 | 20 | 21 | Or, simply install with pip: 22 | 23 | sudo pip install eg 24 | 25 | """ 26 | 27 | print(DEPRECATION_WARNING) 28 | -------------------------------------------------------------------------------- /eg/examples/adb.md: -------------------------------------------------------------------------------- 1 | # adb 2 | 3 | start a shell on the device 4 | 5 | adb shell 6 | 7 | 8 | copy a local file onto the remote device 9 | 10 | adb push local.txt /sdcard/remote.txt 11 | 12 | 13 | copy a remote file off the device 14 | 15 | adb pull /sdcard/remote.txt local.txt 16 | 17 | 18 | install an apk onto the device 19 | 20 | adb install app.apk 21 | 22 | 23 | list all attached devices 24 | 25 | adb devices 26 | 27 | 28 | run ls /sdcard in a shell on the device and return 29 | 30 | adb shell ls /sdcard/ 31 | 32 | 33 | print the complete adb help 34 | 35 | adb help 36 | 37 | 38 | 39 | # Basic Usage 40 | 41 | Run one of a huge number of adb commands: 42 | 43 | adb 44 | 45 | 46 | Copy a local file onto the remote device: 47 | 48 | adb push 49 | 50 | 51 | Copy a remote file from the device to the local machine: 52 | 53 | adb pull 54 | 55 | 56 | Run a shell command on the device: 57 | 58 | adb shell 59 | 60 | 61 | 62 | # Installing and Uninstalling apk Files 63 | 64 | Install an apk whose package does not yet exist on the device: 65 | 66 | adb install app.apk 67 | 68 | 69 | If a previous version of the app already exists, use the `-r` argument to 70 | perform an upgrade. This will keep existing data and go through the upgrade 71 | procedures as if you were updating the app from the app store: 72 | 73 | adb install -r app.apk 74 | 75 | 76 | Uninstall the app associated with the package `org.package.app`: 77 | 78 | adb uninstall org.package.app 79 | 80 | 81 | 82 | # Logging 83 | 84 | The device's log can be dumped and searched using `adb logcat`. 85 | 86 | Dump all of the device's log and continue monitoring until `-c` is 87 | pressed: 88 | 89 | adb logcat 90 | 91 | 92 | Dump all the of the device's log and disconnect (`-d`): 93 | 94 | adb logcat -d 95 | 96 | 97 | Log messages are printed with a tag. This command will dump only those log 98 | messages that have the tag ConnectivityService (`-s ConnectivityService`): 99 | 100 | adb logcat -s ConnectivityService 101 | 102 | 103 | Log messages are printed with a priority level. Requesting a priority level 104 | will return all messages at that level and higher. From low to high, the order 105 | is Verbose (`V`), Debug (`D`), Info (`I`), Warn (`W`), Error (`E`), and Fatal 106 | (`F`). Levels must be passed using a particular tag, with `*` representing all 107 | tags. This will print messages from all tags (`*`) at level Error and higher 108 | (`:E`): 109 | 110 | adb logcat '*:E' 111 | 112 | 113 | This will print all messages with the tag ConnectivityService at level Debug 114 | and higher: 115 | 116 | adb logcat 'ConnectivityService:D' 117 | 118 | 119 | Clear the log on the device (`-c`): 120 | 121 | adb logcat -c 122 | 123 | 124 | Print the help information for `adb logcat` by passing any parameter that 125 | cannot be interpreted as valid command (`:W`): 126 | 127 | adb logcat `:W` 128 | 129 | 130 | 131 | # The Power of `shell` 132 | 133 | The `adb shell` command can make use of a number of programs running on Android 134 | devices to provide in-depth information about the system, installed packages, 135 | and more. 136 | 137 | 138 | 139 | # Activity Manager 140 | 141 | The `am` command stands for Activity Manager and can be used with `adb shell` 142 | to perform various Activity-related tasks. 143 | 144 | This will start an activity named `ExampleActivity` in the `org.package.app` 145 | package. The activity name must be relative, so in this case the fully 146 | qualified name of `ExampleActivity` is `org.package.app.ExampleActivity`: 147 | 148 | adb shell am start org.package.app/.ExampleActivity 149 | 150 | 151 | Force stop everything associated with the package `org.package.app`: 152 | 153 | adb shell am force-stop org.package.app 154 | 155 | 156 | Intents can be broadcast to apps using the `broadcast` argument. This will send 157 | the `android.os.action.DISCHARGING` intent to all apps: 158 | 159 | adb shell am broadcast -a android.os.action.DISCHARGING 160 | 161 | 162 | Print the complete `am` help by passing no arguments: 163 | 164 | adb shell am 165 | 166 | 167 | 168 | # Getting System Information 169 | 170 | The `service` and `dumpsys` commands can be combined with `adb shell` to print 171 | status information about the device. 172 | 173 | Print a huge amount of system information about all running services: 174 | 175 | adb shell dumpsys 176 | 177 | 178 | Print current cpu state: 179 | 180 | adb shell dumpsys cpuinfo 181 | 182 | 183 | List all services running on the device (`list`): 184 | 185 | adb shell service list 186 | 187 | 188 | See if the wifi service exists on a device (`check wifi`): 189 | 190 | adb shell service check wifi 191 | 192 | 193 | Information about particular services can be dumped using `dumpsys` to obtain 194 | specific system information. 195 | 196 | List information about only the wifi service (`dumpsys wifi`): 197 | 198 | adb shell dumpsys wifi 199 | 200 | 201 | Show memory information as returned by the `meminfo` service: 202 | 203 | adb shell dumpsys meminfo 204 | 205 | 206 | Show the memory information of a particular package: 207 | 208 | adb shell dumpsys meminfo org.package.app 209 | 210 | 211 | Use the `package` service to provide information about specific applications. 212 | This command will show MIME types associated with the application, exported 213 | content resolvers, authorities, permissions, etc: 214 | 215 | adb shell dumpsys package org.package.app 216 | 217 | 218 | 219 | ## Advanced Dump Options 220 | 221 | Some arguments to `dumpsys` can take the flag `-h` to print additional 222 | help about that particular command. An incomplete but useful list of these 223 | commands is: `activity`, `window`, `meminfo`, `package`, and `batteryinfo`. 224 | 225 | This will print all the help for the `activity` argument: 226 | 227 | adb shell dumpsys activity -h 228 | 229 | 230 | 231 | # Package Manager 232 | 233 | The `pm` command stands for Package Manager can be used to display information 234 | about packages installed on the device. 235 | 236 | To see a list of all installed packages, run: 237 | 238 | adb shell pm list packages 239 | 240 | 241 | See the installed packages and their associated files: 242 | 243 | adb shell pm list packages -f 244 | 245 | 246 | List all the permissions known to the device: 247 | 248 | adb shell pm list permissions -d -g 249 | 250 | 251 | Permissions that have been requested by an applications can be granted 252 | (`grant`) or revoked (`revoke`) by specifying their package name. This will 253 | only work for apps that have requested a particular permission in their 254 | manifest. This command refers to the package `org.package.app` and will revoke 255 | the record audio permission: 256 | 257 | adb shell pm revoke org.package.app android.permission.RECORD_AUDIO 258 | 259 | 260 | See detailed information about a particular package: 261 | 262 | adb shell pm dump org.package.app 263 | 264 | 265 | Print the complete `pm` help by passing no arguments: 266 | 267 | adb shell pm 268 | 269 | 270 | 271 | ## Pull an apk Off a Device 272 | 273 | The `path` command can be used with `pm` to get the path to the package's apk 274 | file. This can be used with `adb pull` to pull a package's apk off of the 275 | device. This sequence of commands discovers the apk path for the 276 | `com.google.android.calendar` package and pulls the apk to the current 277 | directory: 278 | 279 | $ adb shell pm path com.google.android.calendar 280 | /data/app/com.google.android.calendar-1/base.apk 281 | $ adb pull /data/app/com.google.android.calendar-1/base.apk 282 | 283 | 284 | 285 | # Inspecting Protected Storage 286 | 287 | By default, most apps store their data in protected storage that cannot be 288 | easily accessed without rooting the device. This complicates debugging, as you 289 | can't get access to your app's database. Fortunately this can be circumvented 290 | using the `adb backup` command. 291 | 292 | This sequence of commands will create a backup of all app data in protected 293 | storage as specified by the `org.package.app` package name and store it as 294 | `backup.ab`. The backup file format begins with human-readable text to display 295 | the file type and the file version, followed by a compressed tar file. Assuming 296 | a version number of a single byte, the compressed backup content starts after 297 | 24 bytes. 298 | 299 | We use `dd` to extract only the compressed part of the file and use python to 300 | decompress the content and save it as a tar file. Finally we'll extract the 301 | contents of the file using `tar`, creating the app's directory as it existed on 302 | the phone. Note that the backup will have to be manually approved on the device 303 | after running `adb backup`, and that the `\` characters are line continuations 304 | for use in the shell: 305 | 306 | $ adb backup -f ./backup.ab org.package.app 307 | $ dd if=./backup.ab bs=1 skip=24 \ 308 | | python -c "import zlib,sys;sys.stdout.write(\ 309 | zlib.decompress(sys.stdin.read()))" >backup.tar 310 | $ tar vfx backup.tar 311 | 312 | 313 | -------------------------------------------------------------------------------- /eg/examples/aliases.json: -------------------------------------------------------------------------------- 1 | { 2 | "link": "ln", 3 | "netcat": "nc", 4 | "g++": "gcc", 5 | "clang": "gcc", 6 | "clang++": "gcc", 7 | "egrep": "grep", 8 | "fgrep": "grep", 9 | "zgrep": "grep", 10 | "zegrep": "grep", 11 | "zfgrep": "grep" 12 | } 13 | -------------------------------------------------------------------------------- /eg/examples/awk.md: -------------------------------------------------------------------------------- 1 | # awk 2 | 3 | print lines matching `foo` 4 | 5 | awk '/foo/' input.txt 6 | 7 | 8 | match foo, split on whitespace, and print the first element in the split array 9 | 10 | awk '/foo/ { print $1 }' input.txt 11 | 12 | 13 | use `:` as the field delimiter 14 | 15 | awk -F: 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Print a subset of lines from a file: 22 | 23 | awk '//' 24 | 25 | 26 | The forward slashes around `` are required for POSIX-style regular 27 | expressions. 28 | 29 | Wrap everything going to `awk` in single quotes and give it the name of an 30 | input file. 31 | 32 | More complicated processing of matching lines can go in curly braces. For 33 | example, this command will print each line that matches foo: 34 | 35 | awk '/foo/ { print }' input.txt 36 | 37 | 38 | 39 | # Print Matching Lines 40 | 41 | `awk` prints lines by default, so no command prints the whole matching line. 42 | `$0` is special and means the whole matching line. The following three commands 43 | are all equivalent. Each will print every line from a file matching `foo` 44 | (`/foo/`) (output is not shown): 45 | 46 | $ awk '/foo/' input.txt 47 | $ awk '/foo/ { print }' input.txt 48 | $ awk '/foo/ { print $0 }' input.txt 49 | 50 | 51 | 52 | # Columns and Fields 53 | 54 | `awk` divides each lines into an array of "fields", much like `split`. By 55 | default it splits on whitespace. 56 | 57 | Fields are referred to by a `$` and an index. `$2` means the second field in 58 | the line. 59 | 60 | Fields are 1-indexed--i.e. `$2` would refer to the second column in a file. 61 | 62 | `thrones.txt`: 63 | 64 | Tyrion Lannister 555.360.1234 65 | Jamie Lannister 555.360.9876 66 | Jon Snow 555.206.4444 67 | Arya Stark 555.206.1111 68 | 69 | 70 | Match lines containing `Lannister`, print the first field (split on 71 | whitespace): 72 | 73 | $ awk '/Lannister/ { print $1 }' thrones.txt 74 | Tyrion 75 | Jamie 76 | 77 | 78 | 79 | # For Loops 80 | 81 | For loops can be used to do things like print all the fields in a line. Here 82 | `NF` is the number of fields on every line in the file `input.txt`. We match 83 | all lines (by not giving a pattern) and print all fields, splitting on 84 | whitespace by default: 85 | 86 | awk '{ for (i = 1; i < NF; i++) print $i }' input.txt 87 | 88 | 89 | -------------------------------------------------------------------------------- /eg/examples/brctl.md: -------------------------------------------------------------------------------- 1 | # brctl 2 | 3 | list all bridges: 4 | 5 | brctl show 6 | 7 | 8 | create bridge `br1`: 9 | 10 | brctl addbr br1 11 | 12 | 13 | add interface `eth0` to bridge `br1`: 14 | 15 | brctl addif br1 eth0 16 | 17 | 18 | delete interface `eth0` from bridge `br1`: 19 | 20 | brctl delif br1 eth0 21 | 22 | 23 | delete bridge `br1`: 24 | 25 | brctl delbr br1 26 | 27 | 28 | 29 | # Advanced usage 30 | 31 | Show MAC addresses learned by bridge `br1` and the port from which they were 32 | learned: 33 | 34 | brctl showmacs br1 35 | 36 | 37 | Turn on STP on bridge `br1`: 38 | 39 | brctl stp br1 on 40 | 41 | 42 | Set ageing of MAC addresses on bridge `br1` to 0 seconds. This will cause 43 | bridge to not learn MAC addresses: 44 | 45 | brctl setageing br1 0 46 | 47 | 48 | Show details about bridge `br1`: 49 | 50 | brctl showstp br1 51 | 52 | 53 | -------------------------------------------------------------------------------- /eg/examples/brew.md: -------------------------------------------------------------------------------- 1 | # brew 2 | 3 | see all homebrew-installed packages 4 | 5 | brew list 6 | 7 | 8 | search for an installable package containing the string ack 9 | 10 | brew search ack 11 | 12 | 13 | install the ack package 14 | 15 | brew install ack 16 | 17 | 18 | upgrade an installed node to the most recent version 19 | 20 | brew upgrade node 21 | 22 | 23 | see all installed versions of node 24 | 25 | brew info node 26 | 27 | 28 | use the installed version 0.10.20 of node instead of the current version 29 | 30 | brew switch node 0.10.20 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | `brew` is the command for Homebrew, a package manager for OSX. It is most 37 | commonly used to install a package or utility: 38 | 39 | brew install 40 | 41 | 42 | Search for a formula containing a string: 43 | 44 | brew search 45 | 46 | 47 | 48 | # Installing Things 49 | 50 | The people maintaining Homebrew curate a list of software that can be installed 51 | using `brew`. The instructions for installing a particular package are called a 52 | formula. Before installing things, it is good practice to make sure you have 53 | the most up to date version of all formulae by running `update`: 54 | 55 | brew update 56 | 57 | 58 | Once you are dealing with the most recent formulae, install things by giving 59 | `brew` the `install` command and a package name. To see if `node` can be 60 | installed using `brew`, first search all formulae to see if Homebrew offers an 61 | install of `node`: 62 | 63 | brew search node 64 | 65 | 66 | Homebrew will print all matching formulae. `node` is among them, so install it: 67 | 68 | brew install node 69 | 70 | 71 | After a package is installed, watch the output for any printed caveats. These 72 | are formula-dependent. Homebrew is good about taking care of things for you, 73 | but sometimes you'll still have to handle something yourself. 74 | 75 | 76 | 77 | ## What Does Install Do? 78 | 79 | `brew install` does two things. First, it somehow gets an executable onto your 80 | machine. It might download an executable directly (which is referred to as a 81 | "bottle"), or it might build from source. Second, it adds symlinks to these 82 | executables so that they will be on your path. 83 | 84 | By default, `brew` installs things into your Cellar. The location of your 85 | Cellar can be found by: 86 | 87 | brew --cellar 88 | 89 | 90 | Inside your Cellar, programs are stored according to their package name and 91 | version. This will show where Homebrew installs `node` inside your Cellar: 92 | 93 | $ brew --cellar node 94 | /usr/local/Cellar/node 95 | 96 | 97 | Inside that directory are other directories with all the versions of the `node` 98 | package installed on your machine: 99 | 100 | $ ls /usr/local/Cellar/node 101 | 0.10.20/ 0.10.36/ 0.12.2_1/ 102 | 103 | 104 | After the executable is available, it lives in the Cellar in one of the above 105 | directories. Homebrew then creates symlinks to the executable as well as other 106 | relevant files like man pages in a place that is on your path. Exactly where 107 | these symlinks live varies depending on the formula, but they usually live at 108 | `$(brew --prefix)/bin`. 109 | 110 | 111 | 112 | # Linking 113 | 114 | A keg can be installed without being symlinked on your path. This gives you 115 | more flexibility, as you can essentially deactivate a formula without having to 116 | manually curate your path or delete the installed the executable. 117 | 118 | This will remove the symlinks to `node`: 119 | 120 | brew unlink node 121 | 122 | 123 | An installed, unlinked formula is referred to as "keg only". To create symlinks 124 | to the formula, run the `link` command. This will create symlinks to `node`: 125 | 126 | brew link node 127 | 128 | 129 | 130 | # Taps 131 | 132 | A tap is a list of formulae that extends the default list provided by Homebrew. 133 | All taps are described as a two part name containing a single slash. For 134 | example, `homebrew/versions` is a list of formulae that allow installation of 135 | specific versions of software. 136 | 137 | This naming convention refers to a repository on Github and is of the format: 138 | `/hombrew-`. `homebrew/versions` is therefore shorthand for 139 | `homebrew/homebrew-versions` and the source for the tap can be found on Github 140 | at `https://github.com/homebrew/homebrew-versions`. 141 | 142 | See your active taps: 143 | 144 | brew tap 145 | 146 | 147 | Activate the `homebrew/versions` tap: 148 | 149 | brew tap homebrew/versions 150 | 151 | 152 | Deactivate the `homebrew/versions` tap: 153 | 154 | brew untap homebrew/versions 155 | 156 | 157 | 158 | # Versions 159 | 160 | Kegs for multiple versions of a single formula can exist simultaneously in the 161 | Cellar. 162 | 163 | See all installed versions of the node formula: 164 | 165 | brew info node 166 | 167 | 168 | Switch to a different installed version of a node: 169 | 170 | brew switch node 0.12.20 171 | 172 | 173 | If you want to install an older version of a tool you'll likely need the 174 | `homebrew/versions` tap. If you have previously installed a newer version of 175 | the tool, you'll need to first unlink that version. This sequence of commands 176 | assumes that you have installed `node` greater than version `010` but want to 177 | install `010`: 178 | 179 | $ brew tap homebrew/versions 180 | $ brew unlink node 181 | $ brew search node 182 | homebrew/versions/node010 homebrew/versions/node08 nodebrew 183 | hombrew/versions/node04 leafnode modenv 184 | homebrew/versions/node06 node 185 | $ brew install homebrew/versions/node010 186 | 187 | 188 | 189 | # Casks 190 | 191 | A Cask is a `.app` style application that can be installed using Homebrew. This 192 | is an alternative to downloading a `.dmg` file and dragging an icon into your 193 | `Applications/` directory. 194 | 195 | Install the `cask` command: 196 | 197 | brew install caskroom/cask/brew-cask 198 | 199 | 200 | Search for casks containing the string `chrome`: 201 | 202 | brew cask search chrome 203 | 204 | 205 | Install the `google-chrome` cask: 206 | 207 | brew cask install google-chrome 208 | 209 | 210 | Print the `cask` help: 211 | 212 | brew cask help 213 | 214 | 215 | 216 | # Terminology 217 | 218 | Homebrew's strict adherence to beer-related terms can lead to some confusion. 219 | 220 | 221 | 222 | ## Formula 223 | 224 | The definition of a package. This is a ruby file that lives at 225 | `/usr/local/Libary/Formula`. 226 | 227 | See the formula for `node`: 228 | 229 | less /usr/local/Library/Formula/node.rb 230 | 231 | 232 | 233 | ## Keg 234 | 235 | The installation prefix of a formula. This can also be thought of as a 236 | particular version of a package. A `node` keg for version `0.10.20` might be 237 | `/usr/local/Cellar/node/0.10.20`. 238 | 239 | This indicates there are three `node` kegs on the machine: 240 | 241 | $ ls /usr/local/Cellar/node 242 | 0.10.20/ 0.10.36/ 0.12.2_1/ 243 | 244 | 245 | 246 | ## Cellar 247 | 248 | Where kegs are installed. Find the location with: 249 | 250 | brew --cellar 251 | 252 | 253 | 254 | ## Bottle 255 | 256 | A binary keg that can be unpacked. These frequently end in `.tar.gz` and are 257 | referred to as "poured from bottle" or "bottled" when running `brew info` about 258 | a particular package: 259 | 260 | brew info node 261 | 262 | 263 | 264 | ## Tap 265 | 266 | A list of additional optional formulae that can be used to extend Homebrew's 267 | default list. 268 | 269 | 270 | 271 | ## Cask 272 | 273 | A `.app` style program that can be installed using Homebrew. 274 | 275 | 276 | -------------------------------------------------------------------------------- /eg/examples/cat.md: -------------------------------------------------------------------------------- 1 | # cat 2 | 3 | show file.txt 4 | 5 | cat file.txt 6 | 7 | 8 | show file.txt with line numbers 9 | 10 | cat -n file.txt 11 | 12 | 13 | show file with blank lines squeezed to single space 14 | 15 | cat -s double_spaced.txt 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Show the input file on `stdout`: 22 | 23 | cat 24 | 25 | 26 | -------------------------------------------------------------------------------- /eg/examples/cd.md: -------------------------------------------------------------------------------- 1 | # cd 2 | 3 | change do target-directory 4 | 5 | cd target-directory 6 | 7 | 8 | change to home directory 9 | 10 | cd ~ 11 | 12 | 13 | change to previous directory 14 | 15 | cd - 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Change your current working directory to the target directory: 22 | 23 | $ cd 24 | $ pwd 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /eg/examples/chmod.md: -------------------------------------------------------------------------------- 1 | # chmod 2 | 3 | give read, write, and execute permissions to everyone 4 | 5 | chmod a+rwx file.txt 6 | 7 | 8 | remove group write and execute permissions 9 | 10 | chmod g-wx file.txt 11 | 12 | 13 | give execute permission to the owning user 14 | 15 | chmod u+x file.txt 16 | 17 | 18 | remove all permissions from non-owning user and non-group members 19 | 20 | chmod o-rwx file.txt 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | Add (`+`) permissions to a file: 27 | 28 | chmod + 29 | 30 | 31 | Remove (`-`) permissions from a file: 32 | 33 | chmod - 34 | 35 | 36 | 37 | # Flags 38 | 39 | Permissions can belong to the owning user (`u`), the group (`g`), and other 40 | people in the world (`o`). All of these at once can be referred to as (`a`). 41 | `ugo` is equivalent to `a`. 42 | 43 | Permissions can be read (`r`), write (`w`), and execute (`x`). 44 | 45 | Permissions are added with `+` and removed with `-`. 46 | 47 | 48 | 49 | ## Bit Representation 50 | 51 | Permissions can also be specified with numbers acting as bit masks. `7` is 52 | `111`, which turns on `rwx`. `777` translates to `111111111`, which turns on 53 | `rwx` for all three permissions holders. `chmod 777` is thus equivalent to 54 | `chmod a+rwx`: 55 | 56 | $ chmod 777 file.txt 57 | $ ls -l 58 | total 0 59 | -rwxrwxrwx 1 tyrion group 0 Feb 5 11:40 file.txt 60 | 61 | 62 | `4` is `100`, which corresponds to the read permission. This command will give 63 | read, write, and execute permissions to the owning user, and read permission to 64 | the group and others in the world: 65 | 66 | $ chmod 744 file.txt 67 | $ ls -l 68 | total 0 69 | -rwxr--r-- 1 tyrion group 0 Feb 5 11:40 file.txt 70 | 71 | 72 | 73 | # Adding Permissions 74 | 75 | Add execute (`+x`) permissions to the owning user (`u`): 76 | 77 | $ ls -l 78 | total 0 79 | -rw-r--r-- 1 tyrion group 0 Feb 5 11:40 file.txt 80 | $ chmod u+x file.txt 81 | $ ls -l 82 | total 0 83 | -rwxr--r-- 1 tyrion group 0 Feb 5 11:40 file.txt 84 | 85 | 86 | 87 | # Removing Permissions 88 | 89 | Remove read (`-r`) from all permissions holders (`a`). `a-r` is equivalent to 90 | `ugo`: 91 | 92 | $ ls -l 93 | total 0 94 | -rw-r--r-- 1 tyrion group 0 Feb 5 11:40 file.txt 95 | $ chmod a-r file.txt 96 | $ ls -l 97 | total 0 98 | --w------- 1 tyrion group 0 Feb 5 11:40 file.txt 99 | 100 | 101 | -------------------------------------------------------------------------------- /eg/examples/chown.md: -------------------------------------------------------------------------------- 1 | # chown 2 | 3 | change user 4 | 5 | sudo chown username file.txt 6 | 7 | 8 | change user recursively for all files 9 | 10 | sudo chown -R username directory 11 | 12 | 13 | change user and group 14 | 15 | sudo chown username:groupname file.txt 16 | 17 | 18 | change group 19 | 20 | sudo chown :groupname file.txt 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | The caller needs to be a super-user to perform `chown`. Examples are shown 27 | using `sudo`, which is not required if the user is a super-user. 28 | 29 | Change the ownership of a file: 30 | 31 | sudo chown 32 | 33 | 34 | -------------------------------------------------------------------------------- /eg/examples/clip-view.md: -------------------------------------------------------------------------------- 1 | # clip-view 2 | 3 | render a specific local page 4 | 5 | clip-view cat 6 | 7 | 8 | render a specific local page 9 | 10 | clip-view path/to/cat.clip 11 | 12 | 13 | render a page by a specific render 14 | 15 | clip-view --render tldr cat 16 | 17 | 18 | render a page with a specific color theme 19 | 20 | clip-view --theme awesome cat 21 | 22 | 23 | render a page in a specific platform 24 | 25 | clip-view --operating-system windows dir 26 | 27 | 28 | clear a page cache 29 | 30 | clip-view --clear-page-cache 31 | 32 | 33 | clear a theme cache 34 | 35 | clip-view --clear-theme-cache 36 | 37 | 38 | display help 39 | 40 | clip-view --help 41 | 42 | 43 | display version 44 | 45 | clip-view --version 46 | 47 | 48 | -------------------------------------------------------------------------------- /eg/examples/cp.md: -------------------------------------------------------------------------------- 1 | # cp 2 | 3 | copy a file 4 | 5 | cp original.txt copy.txt 6 | 7 | 8 | copy a directory 9 | 10 | cp -R directory directory_copy 11 | 12 | 13 | prompt if will overwrite existing file 14 | 15 | cp -i foo.txt directoryWithFoo/ 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Copy a file: 22 | 23 | cp 24 | 25 | 26 | Copy a directory using the recursive (`-R`) flag: 27 | 28 | cp -R 29 | 30 | 31 | 32 | # Directories 33 | 34 | Behavior differs if the argument that is the directory being copied ends with a 35 | `/`. If it does end with a `/` the contents are copied as opposed to the 36 | directory itself. For example, `cp -R foo/ bar` will take the contents of the 37 | `foo` directory and copy them into `bar`, while `cp -R foo bar` will copy `foo` 38 | itself and put it into `bar`. 39 | 40 | 41 | -------------------------------------------------------------------------------- /eg/examples/curl.md: -------------------------------------------------------------------------------- 1 | # curl 2 | 3 | issue a GET request to a URL 4 | 5 | curl http://www.example.com 6 | 7 | 8 | issue a PUT request with a JSON payload 9 | 10 | curl -X PUT http://www.example.com -d '{"key": "value"}' 11 | 12 | 13 | POST data.txt to a URL 14 | 15 | curl -X POST http://www.example.com --data-binary @data.txt 16 | 17 | 18 | issue a GET request with a header Key paired to Value 19 | 20 | curl -X PUT http://www.example.com -H "Key:Value" 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | Issue an HTTP request of a particular method type to a URL. By default `curl` 27 | issues a GET request. The `-X` flag lets you specify other methods, like PUT 28 | and POST: 29 | 30 | curl -X 31 | 32 | 33 | 34 | # Cookies 35 | 36 | `curl` can use cookies. The `--cookie` flag allows you to set name=value pairs 37 | at the command line. This command will issue a GET request, print verbose 38 | output (`-v`), and pass a cookie where TOKEN is set to data 39 | (`--cookie "TOKEN=data"`): 40 | 41 | curl -v --cookie "TOKEN=data" http://www.example.com 42 | 43 | 44 | # Querying Sets and Ranges 45 | 46 | `curl` can be used to issue requests to numerous URLs simultaneously, issued in 47 | sequential order. This command will issue requests to both the www and admin 48 | subdomains (`{www,admin}`) of example.com: 49 | 50 | curl http://{www,admin}.example.com 51 | 52 | 53 | It can also query sequential ranges by placing numbers in square brackets. This 54 | will issue requests for resources 1.txt, 2.txt, 3.txt, and 4.txt (`[1:4]`) from 55 | example.com: 56 | 57 | curl http://www.example.com/[1:4].txt 58 | 59 | 60 | You can also specify a step. This will query letters of the alphabet (`a-z`), 61 | but only every second letter (`:2`): 62 | 63 | curl http://www.example.com?letter=[a-z:2] 64 | 65 | 66 | -------------------------------------------------------------------------------- /eg/examples/cut.md: -------------------------------------------------------------------------------- 1 | # cut 2 | 3 | split lines on ':' and show second column 4 | 5 | cut -d ':' -f2 input.txt 6 | 7 | 8 | split on tab and show columns 2-8 9 | 10 | cut -f 2-8 input.txt 11 | 12 | 13 | show 2nd character of every line 14 | 15 | cut -c 2 characters.txt 16 | 17 | show characters 1-10 of every line 18 | 19 | cut -c 1-10 characters.txt 20 | 21 | 22 | 23 | # Basic Usage 24 | 25 | Split on a delimiter and print certain fields: 26 | 27 | cut -d '' -f 28 | 29 | 30 | 31 | # Specifying the Delimiter and Fields 32 | 33 | Fields are specified by a number, starting at 1. Fields can be separated by a 34 | `,` and provided a range with (`-`). 35 | 36 | The following file is used in these examples: 37 | 38 | $ cat cut.txt 39 | a b:foo:c d 40 | bar:baz 2:last 41 | 42 | 43 | Split on spaces (`-d ' '`) and show every column from 2 onward (`-f 2-`): 44 | 45 | $ cut -d ' ' -f 2- cut.txt 46 | b:foo:c d 47 | 2:last 48 | 49 | 50 | Split on colons (`-d ':'`) and show the first and third columns (`-f 1,3`): 51 | 52 | $ cut -d ':' -f 1,3 cut.txt 53 | a b:c d 54 | bar:last 55 | 56 | 57 | Split on `a` (`-d 'a'`) and show the first through third columns (`-f 1-3`): 58 | 59 | $ cut -d 'a' -f 1-3 cut.txt 60 | a b:foo:c d 61 | bar:baz 2:l 62 | 63 | 64 | -------------------------------------------------------------------------------- /eg/examples/date.md: -------------------------------------------------------------------------------- 1 | # date 2 | 3 | display current date and time 4 | 5 | date 6 | 7 | 8 | display current date and time in UTC 9 | 10 | date -u 11 | 12 | 13 | display current date and time with custom format 14 | 15 | date +'%Y-%m-%d %H:%M:%S' 16 | 17 | 18 | display current date for a given timezone (find timezone name with `tzselect`) 19 | 20 | TZ='Europe/Paris' date 21 | 22 | 23 | convert seconds since the epoch (1970-01-01 UTC) to a date 24 | 25 | date -d @2147483647 26 | 27 | 28 | 29 | # Basic Usage 30 | 31 | Display the current date and time in a particular format: 32 | 33 | date +'' 34 | 35 | 36 | The format argument can be omitted to display the current date and time in the 37 | default format. For detailed descriptions of the arguments, see the Common Date 38 | Formats section below. 39 | 40 | 41 | 42 | # Set the System Clock 43 | 44 | The `date` command also lets you set the system clock. Syntax for this varies 45 | across operating systems. Only the superuser can set the date, so all examples 46 | begin with `sudo`. The format of the string is `mmddHHMMccyy.ss` To refer to 47 | the date December 24th, 2014 at 2:45 in the afternoon you would use the string 48 | `122414452014`. 49 | 50 | 51 | ## Linux 52 | 53 | Set the system clock to December 24th, 2014 at 2:45 in the afternoon: 54 | 55 | sudo date --set='122414452014' 56 | 57 | 58 | ## OSX 59 | 60 | Set the system clock to 5:15 in the afternoon on the current day: 61 | 62 | sudo date 1715 63 | 64 | 65 | 66 | # A Note on Versions 67 | 68 | The Linux version of `date` supports more functionality than the OSX version. 69 | Similar functionality can be obtained on OSX by installing `coreutils` (install 70 | with `brew install coreutils`) and then using `gdate`. 71 | 72 | 73 | 74 | # Manipulate Dates and Times 75 | 76 | `date` can be used to change the formats of dates and times. Reformat the human 77 | readable date (`--date='Mar 27, 2016 2:45PM'`) to a conventional mm-dd-yy HH:MM 78 | machine readable format (`+'%y-%m-%d %H:%M'`): 79 | 80 | date --date='' +'' 81 | 82 | 83 | 84 | # Common Date Formats 85 | 86 | Valid arguments in format strings passed to `date` are summarized here. 87 | 88 | 89 | ## Date 90 | 91 | `%Y`: year (e.g., 2015) 92 | `%m`: month (01..12) 93 | `%d`: day of month (01..31) 94 | `%F`: full date; same as %Y-%m-%d 95 | 96 | 97 | ## Time 98 | 99 | `%H`: hour (00..23) 100 | `%M`: minute (00..59) 101 | `%S`: second (00..60) 102 | `%T`: time, same as %H:%M:%S 103 | `%I`: hour (01..12) 104 | `%p`: locale's equivalent of either AM or PM; blank if not known 105 | `%r`: locale's 12-hour clock time (e.g., 11:11:04 PM) 106 | 107 | 108 | ## Timestamp 109 | 110 | `%s`: seconds since 1970-01-01 00:00:00 UTC 111 | 112 | 113 | 114 | # Advanced examples 115 | 116 | Show the current date and time using built-in standards: 117 | 118 | date --iso-8601 119 | date --rfc-2822 120 | date --rfc-3339=seconds 121 | date --utc 122 | 123 | 124 | Print the local time for 9PM next Friday on the west coast of the US: 125 | 126 | date --date='TZ="America/Los_Angeles" 09:00 PM next Friday' 127 | 128 | 129 | Convert a date string into timestamp: 130 | 131 | date --date='Tue, 23 Jun 2015 11:21:42 +0200' +%s 132 | 133 | 134 | Print the date of the day three months and one day in the future: 135 | 136 | date --date='3 months 1 day' 137 | 138 | 139 | Print the day of the week of Christmas in the current year: 140 | 141 | date --date='25 Dec' +%A 142 | 143 | 144 | Set the system clock forward by two minutes: 145 | 146 | date --set='+2 minutes' 147 | 148 | 149 | A very complete documentation with a lot of examples is available at 150 | http://www.gnu.org/software/coreutils/date or with the command 151 | `info coreutils 'date invocation'`. 152 | 153 | 154 | -------------------------------------------------------------------------------- /eg/examples/dd.md: -------------------------------------------------------------------------------- 1 | # dd 2 | 3 | copy original.txt to copy.txt 4 | 5 | dd if=./original.txt of=copy.txt 6 | 7 | 8 | skip the first five bytes of original.txt and print the rest to stdout 9 | 10 | dd bs=1 skip=5 if=./original.txt 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | `dd` is a powerful tool. If used incorrectly it can destroy a disk, so be very 17 | careful with the input and output files you specify. 18 | 19 | Copy what is read on stdin to stdout: 20 | 21 | dd 22 | 23 | 24 | Copy an input file to an output file: 25 | 26 | dd if= of= 27 | 28 | 29 | 30 | # Skipping Leading Bytes 31 | 32 | `dd` can be used to skip the beginning bytes of a file, which can be useful 33 | when manually interacting with file formats that include a compressed file 34 | after some human readable bytes. 35 | 36 | This command will set the input and output block size to 1 byte (`bs=1`) and 37 | will skip the first 24 blocks (`skip=24`), printing file from 25 bytes onward 38 | to stdout: 39 | 40 | dd if=inFile.txt bs=1 skip=24 41 | 42 | 43 | This command also prints the file from 25 bytes onwards, but does so using a 24 44 | byte block size (`bs=24`) and skipping one block (`skip=1`): 45 | 46 | dd if=inFile.txt bs=24 skip=1 47 | 48 | 49 | -------------------------------------------------------------------------------- /eg/examples/df.md: -------------------------------------------------------------------------------- 1 | # df 2 | 3 | display free disk space in human-readable format 4 | 5 | df -h 6 | 7 | 8 | display human-readable free disk space of file system where foo.txt is stored 9 | 10 | df -h foo.txt 11 | 12 | 13 | display free disk space of all file systems 14 | 15 | df -a 16 | 17 | 18 | display free disk space of locally mounted file systems 19 | 20 | df -l 21 | 22 | 23 | display human-readable free disk space of nfs-type file systems 24 | 25 | df -hT nfs 26 | 27 | 28 | 29 | # Basic Usage 30 | 31 | Show the free disk space of a file system in human-readable (`-h`) format: 32 | 33 | df -h 34 | 35 | 36 | -------------------------------------------------------------------------------- /eg/examples/diff.md: -------------------------------------------------------------------------------- 1 | # diff 2 | 3 | output the differences between two files 4 | 5 | diff a.txt b.txt 6 | 7 | 8 | show differences with unified context (like git) 9 | 10 | diff -u a.txt b.txt 11 | 12 | 13 | show differences between two directories 14 | 15 | diff -r dir1/ dir2/ 16 | 17 | 18 | save a diff to a patch file called diff.patch 19 | 20 | diff -u a.txt b.txt >diff.patch 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | Show the differences between two files: 27 | 28 | diff 29 | 30 | 31 | Output generated with unified context (`-u`) is simpler to understand for many 32 | users. It is also the output used by many version control systems. This will 33 | output changes with surrounding unchanged lines for context, as well as show 34 | additions with `+` and subtractions with `-`: 35 | 36 | diff -u 37 | 38 | 39 | More precisely, `diff` tries to output the minimal number of line insertions 40 | and line deletions that would transform one file into another. 41 | 42 | 43 | 44 | # Basic Output 45 | 46 | By default, output from the `diff` command consists of an action (either an 47 | addition `a`, a change `c`, or a deletion `d`), the contents of the original 48 | file, and the contents of the modified file. 49 | 50 | The action is shown as the line number in the original file followed by an `a`, 51 | `c`, or `d`, and followed by the line number in the modified file. Output of 52 | the two files is separated by `---`. 53 | 54 | For example, this output means that line five was `line five` in the original 55 | file, and has been changed to `line five modified` in the modified file: 56 | 57 | 5c5 58 | < line five 59 | --- 60 | > line five modified 61 | 62 | 63 | For additions and deletions, only output from the modified or original file is 64 | shown. 65 | 66 | 67 | 68 | # Unified Context 69 | 70 | Unified context is the format commonly used for creating patch files that can 71 | then be applied using the `patch` command. It is also the output format used by 72 | many version control systems, including git. Unified context means that `diff` 73 | will show changes surrounded by three unchanged lines to show context. This 74 | output from the file is called a hunk. The output will also show the file names 75 | of the two files being compared as well as where in the file the displayed hunk 76 | comes from. Consider the following files. 77 | 78 | The original file, `a.txt`: 79 | 80 | this is line one 81 | and line two 82 | here is line three 83 | line four 84 | fifth is line five 85 | line six 86 | line seven is heaven 87 | line eight 88 | line nine is fine 89 | finally, line ten 90 | 91 | 92 | And a modified version called `b.txt`: 93 | 94 | this is line one 95 | and line two 96 | here is line three 97 | line four 98 | line five in b.txt 99 | line six 100 | line seven is heaven 101 | line eight 102 | line nine is fine 103 | 104 | 105 | In `b.txt` the 5th line is modified and the 10th line is deleted. Observe how 106 | `diff` generates unified context with the `-u` option: 107 | 108 | $ diff -u a.txt b.txt 109 | --- a.txt 2015-05-30 17:29:57.000000000 -0700 110 | +++ b.txt 2015-05-30 17:30:31.000000000 -0700 111 | @@ -2,9 +2,8 @@ 112 | and line two 113 | here is line three 114 | line four 115 | -fifth is line five 116 | +line five in b.txt 117 | line six 118 | line seven is heaven 119 | line eight 120 | line nine is fine 121 | -finally, line ten 122 | 123 | 124 | Lines beginning with a space are present in both files. Lines beginning with 125 | a single `-` occur only in the original file, while those beginning with a 126 | single `+` occur only in the modified file. In other words, lines beginning 127 | with a single `-` have been deleted while those beginning with a single `+` 128 | have been added. 129 | 130 | The line beginning with `---` shows the name of the original file to which we 131 | are comparing, while the line beginning with `+++` shows the name of the 132 | modified file. 133 | 134 | The line beginning with `@@` shows the ranges of the hunks being displayed. The 135 | range beginning with `-` is the range in the original file (`-2,9`) while the 136 | address beginning with `+` shows the range in the modified file (`+2,8`). 137 | 138 | The first number of the range shows where the given hunk begins in the file. 139 | `-2` means that the hunk shown begins at line 2 in the original file, while 140 | `+2` means the hunk begins at line two in the modified file. 141 | 142 | The second number of the range shows how many total lines of the output are 143 | from the file. In `-2,9`, the 9 means that of all the lines of the hunk shown, 144 | 9 are from the original file. In other words, the number of lines beginning 145 | with a space or a single `-` sum to 9. In `+2,8`, meanwhile, the 8 means that 146 | the lines beginning with a space or a single `+` total to 8. 147 | 148 | 149 | -------------------------------------------------------------------------------- /eg/examples/dig.md: -------------------------------------------------------------------------------- 1 | # dig 2 | 3 | query a DNS server for the A record of example.com 4 | 5 | dig example.com 6 | 7 | 8 | display only the answer section containing the IPv4 address of example.com 9 | 10 | dig example.com +noall +answer 11 | 12 | 13 | display only the IPv4 address of example.com 14 | 15 | dig example.com +short 16 | 17 | 18 | display only Name Server records belonging to example.com 19 | 20 | dig example.com NS 21 | 22 | 23 | display the 128-bit IPv6 address of example.com using the AAAA record 24 | 25 | dig example.com AAAA +short 26 | 27 | 28 | display all DNS records for example.com 29 | 30 | dig example.com ANY 31 | 32 | 33 | perform a reverse DNS lookup on IP address 192.168.1.42 34 | 35 | dig -x 192.168.1.42 36 | 37 | 38 | use sns.dns.icann.org as the DNS server instead of the default 39 | 40 | dig @sns.dns.icann.org www.example.com 41 | 42 | 43 | 44 | # Basic Usage 45 | 46 | Interrogate a DNS server for all records about a domain: 47 | 48 | dig ANY 49 | 50 | 51 | Interrogate a DNS server for a particular type of record about a domain: 52 | 53 | dig 54 | 55 | 56 | Interrogate a specific DNS server about a domain: 57 | 58 | dig @ 59 | 60 | 61 | Return the most concise result of a query: 62 | 63 | dig +short 64 | 65 | 66 | 67 | # Using Google's Public DNS Servers 68 | 69 | Google maintains public DNS servers that form the largest public DNS service in 70 | the world. Like other servers, they can be accessed using the `@` syntax. Their 71 | IPv4 addresses are `8.8.8.8` and `8.8.4.4`. Their two IPv6 addresses are 72 | `2001:4860:4860::8888` and `2001:4860:4860::8844`. If a device cannot accept 73 | the `::` syntax, replace it with `:0:0:0:0:`. These can further be expanded to 74 | four zeros each. The following three commands are equivalent, but not all 75 | devices can recognize all forms: 76 | 77 | $ dig @2001:4860:4860::8888 example.com 78 | $ dig @2001:4860:4860:0:0:0:0:8888 example.com 79 | $ dig @2001:4860:4860:0000:0000:0000:0000:8888 example.com 80 | 81 | 82 | -------------------------------------------------------------------------------- /eg/examples/du.md: -------------------------------------------------------------------------------- 1 | # du 2 | 3 | show size of foo.txt in human readable units 4 | 5 | du -h foo.txt 6 | 7 | 8 | show size of directory in human readable units without listing contents 9 | 10 | du -sh directory 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Show the size on disk in human readable units, as opposed to blocks: 17 | 18 | du -h 19 | 20 | 21 | 22 | ## Sort by Human-Readable Size on Disk 23 | 24 | By default `du` displays file size in blocks. This allows easy sorting by 25 | piping to `sort`: 26 | 27 | du | sort 28 | 29 | 30 | However, this will fail when the `-h` flag is used to show disk usage in 31 | human-readable units, as 1G is lexicographically before 1M, even though 1M is 32 | smaller than 1G. This can be overcome by system-dependent usage of the `sort` 33 | command. 34 | 35 | 36 | 37 | ### Linux 38 | 39 | Sort by size on disk in human readable units (`-h`): 40 | 41 | du -h | sort -h 42 | 43 | 44 | 45 | ### OSX 46 | 47 | On OSX, the `coreutils` package will be necessary. Install it with: 48 | 49 | brew install coreutils 50 | 51 | 52 | After having it installed, the `gsort` command will be available, which can 53 | sort by human readable units (`-h`): 54 | 55 | du -h | gsort -h 56 | 57 | 58 | -------------------------------------------------------------------------------- /eg/examples/echo.md: -------------------------------------------------------------------------------- 1 | # echo 2 | 3 | print hello to stdout 4 | 5 | echo hello 6 | 7 | 8 | print hello without a trailing newline 9 | 10 | echo -n hello 11 | 12 | 13 | print multiple words to stdout 14 | 15 | echo hello world 16 | 17 | 18 | print the value of the EDITOR environment variable 19 | 20 | echo ${EDITOR} 21 | 22 | 23 | ignore special characters using single quotes 24 | 25 | echo 'hello \ there?' 26 | 27 | 28 | print without variable substitution 29 | 30 | echo 'print ${EDITOR} exactly' 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | Print a string to standard out, followed by a new line: 37 | 38 | echo 39 | 40 | 41 | `echo` obeys shell quoting. Single quotes are strong quotes. They prevent all 42 | characters from being interpreted as control characters and prevent variables 43 | from being substituted. Double quotes allow variable and command substitution 44 | but otherwise ignore control characters: 45 | 46 | $ echo 'What is your ${EDITOR}?' 47 | What is your ${EDITOR}? 48 | $ echo "What is your ${EDITOR}?" 49 | What is your vi -e? 50 | $ echo 'Your current directory is `pwd`' 51 | Your current directory is `pwd` 52 | $ echo "Your current directory is `pwd`" 53 | Your current directory is /Users/tyrion 54 | 55 | 56 | 57 | # Note on Referencing Variables 58 | 59 | In these examples, when the environment variable `EDITOR` is referenced it is 60 | surrounded by curly braces: `${EDITOR}`. In the examples shown above, `$EDITOR` 61 | would accomplish the same thing. Since variable substitution is performed using 62 | a mechanism like string search and replace, not using braces to refer to 63 | variables can be more error prone. Curly braces are shown for robustness as in 64 | general they should be preferred. 65 | -------------------------------------------------------------------------------- /eg/examples/eg.md: -------------------------------------------------------------------------------- 1 | # eg 2 | 3 | see example usage for the find command 4 | 5 | eg find 6 | 7 | 8 | turn off colorized output 9 | 10 | eg --no-color find 11 | 12 | 13 | list all available commands 14 | 15 | eg --list 16 | 17 | 18 | specify and egrc file to use when showing examples 19 | 20 | eg -f=/path/to/egrc find 21 | 22 | 23 | specify alternate directory for custom examples 24 | 25 | eg -c=/path/to/custom/examples_dir find 26 | 27 | 28 | use less with the -R flag to page output 29 | 30 | eg --pager-cmd='less -R' find 31 | 32 | 33 | # Basic Usage 34 | 35 | Show examples for a command: 36 | 37 | eg 38 | 39 | 40 | 41 | # Configuration File 42 | 43 | `eg` can be configured using an rc file. By convention, this is expected to be 44 | found at `~/.egrc`. The supported sections are `eg-config`, `color`, and 45 | `substitutions`. 46 | 47 | `examples-dir` is the directory where `eg` looks for default examples. Under 48 | normal circumstances this is provided by the installation and does not require 49 | configuration. `custom-dir` is where use-specified examples be be found. A file 50 | named `awk.md` and located in the directory specified by `custom-dir` will be 51 | paged before the default examples when `eg awk` is invoked. 52 | 53 | Custom colors can be specified in the `color` section. The reset family of 54 | options are used to terminate a region of colorized output. Normal users will 55 | have no reason to change them from their default values of `\x1b[0m`, which 56 | removes all formatting. 57 | 58 | Regex-based substitutions can be specified in the `[substitutions]` section. 59 | They must be named and follow the a list-based syntax that will be applied 60 | using Python's `re` module: `[pattern, replacement, is_multiline]`. 61 | 62 | The three types of formatting are applied in the order: color, squeeze, 63 | substitutions. 64 | 65 | Below is a valid egrc with every option specified: 66 | 67 | [eg-config] 68 | # Lines starting with # are treated as comments 69 | examples-dir = /path/to/examples/dir 70 | custom-dir = /path/to/custom/dir 71 | color = true 72 | squeeze = true 73 | pager-cmd = 'less -R' 74 | 75 | [color] 76 | pound = '\x1b[30m\x1b[1m' 77 | heading = '\x1b[38;5;172m' 78 | code = '\x1b[32m\x1b[1m' 79 | prompt = '\x1b[36m\x1b[1m' 80 | backticks = '\x1b[34m\x1b[1m' 81 | pound_reset = '\x1b[0m' 82 | heading_reset = '\x1b[0m' 83 | code_reset = '\x1b[0m' 84 | prompt_reset = '\x1b[0m' 85 | backticks_reset = '\x1b[0m' 86 | 87 | [substitutions] 88 | # This will remove all four-space indents. 89 | remove-indents = ['^ ', '', True] 90 | 91 | 92 | -------------------------------------------------------------------------------- /eg/examples/expand.md: -------------------------------------------------------------------------------- 1 | # expand 2 | 3 | replace tabs with four spaces 4 | 5 | expand -t 4 removeTabs.txt 6 | 7 | 8 | 9 | # Basic Usage 10 | 11 | Replace tabs with a given number of spaces: 12 | 13 | expand -t 14 | 15 | 16 | -------------------------------------------------------------------------------- /eg/examples/file.md: -------------------------------------------------------------------------------- 1 | # file 2 | 3 | determine the file type of foo.txt 4 | 5 | file foo.txt 6 | 7 | 8 | keep going and show all the matching file types, not just the first 9 | 10 | file -k index.html 11 | 12 | 13 | show type by looking inside compressed files 14 | 15 | file -z compressed.gzip 16 | 17 | 18 | try to classify special files like disk partitions 19 | 20 | file -s /dev/disk0 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | Determine the type of a file: 27 | 28 | file 29 | 30 | 31 | -------------------------------------------------------------------------------- /eg/examples/find.md: -------------------------------------------------------------------------------- 1 | # find 2 | 3 | files in searchdir named file.txt 4 | 5 | find ./searchdir -name file.txt 6 | 7 | 8 | only directories in searchdir 9 | 10 | find ./searchdir -type d 11 | 12 | 13 | show more info 14 | 15 | find ./searchdir -name 'file.txt' -ls 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Find files and directories matching a given name: 22 | 23 | find -name 24 | 25 | 26 | 27 | # By Name 28 | 29 | Search `/searchdir` for files and directories named `file.txt`: 30 | 31 | find ./searchdir -name file.txt 32 | 33 | 34 | 35 | ## Case Insensitive 36 | 37 | Use `-iname` for case insensitive name searching: 38 | 39 | $ find ./searchdir -iname file.txt 40 | ./searchdir/file.txt 41 | ./searchdir/bar/FiLe.TxT 42 | 43 | 44 | 45 | ## Wildcards 46 | 47 | Wildcards are supported with quotes. 48 | 49 | Find files starting with `prefix`: 50 | 51 | $ find ./searchdir -name "prefix*" 52 | ./searchdir/prefix.txt 53 | ./searchdir/prefixAndMore.txt 54 | 55 | 56 | 57 | # By Type 58 | 59 | ## Files only 60 | 61 | Will find files (`-type f`) but not directories named `foo`: 62 | 63 | find ./searchdir -type f foo 64 | 65 | 66 | 67 | ## Directories and Folders 68 | 69 | List only directories by specifying `-type d`: 70 | 71 | $ find ./searchdir -type d -name 'directory' 72 | ./searchdir/directory 73 | 74 | 75 | 76 | # Size 77 | 78 | Use the `-size` flag followed by a number and a unit. Without a unit it matches 79 | blocks. 80 | 81 | Find entries exactly two bytes (`-size 2c`). `c` stands for character: 82 | 83 | find ./searchdir -size 2c 84 | 85 | 86 | Find files exactly 2 kilobytes (`-size 2k`): 87 | 88 | find ./searchdir -size 2k 89 | 90 | 91 | Find files exactly 2 megabytes (`-size 2M`): 92 | 93 | find ./searchdir -size 2M 94 | 95 | 96 | 97 | ## Ranges 98 | 99 | Prefix a size with `+` for >= that value and `-` for <= that value. 100 | 101 | Find files greater than 5k (`-size +5k`): 102 | 103 | find /dir/to/search +5k 104 | 105 | 106 | Find files less than 5k (`-size -5k`): 107 | 108 | find /dir/to/search -5k 109 | 110 | 111 | 112 | # Time 113 | 114 | Files can also be filtered based on the last time they were changed, modified, 115 | and accessed. 116 | 117 | `-ctime` refers to the last time the inode or file was changed, which includes 118 | updating file attributes like owner or permissions as well as file 119 | modifications. 120 | 121 | `-mtime` refers to the last time a file was modified. 122 | 123 | `-atime` refers to the last time a file was accessed, including by other 124 | command line tools. 125 | 126 | Arguments to these flags can be in seconds (`s`), minutes (`m`), hours (`h`), 127 | days (`d`), or weeks (`w`). Preceding an argument with `+` will return files 128 | greater than the condition, while `-` will return files less than the 129 | condition. 130 | 131 | Find files modified (`-mtime`) less than 20 minutes (`-20m`) ago: 132 | 133 | find /searchdir -mtime -20m 134 | 135 | 136 | Find files last accessed (`-atime`) more than 2 weeks (`+2w`) ago: 137 | 138 | find /searchdir -atime -w2 139 | 140 | 141 | Alternatively, you can return files that have been modified more recently than 142 | another file with `-newer`: 143 | 144 | find /searchdir -newer other.txt 145 | 146 | 147 | 148 | # Depth 149 | 150 | Find files and directories only two levels deep (`-depth 2` or `-d 2`): 151 | 152 | $ find ./one -depth 2 153 | ./one/two 154 | ./one/foo.txt 155 | 156 | 157 | Find only files (`-type f`) >= two levels (`-mindepth 2`) and <= three levels 158 | (`-maxdepth 3`) deep: 159 | 160 | $ find ./one -type f -mindepth 2 -maxdepth 3 161 | ./one/twoLevels.txt 162 | ./one/two/threeLevels.txt 163 | 164 | 165 | 166 | # Boolean Operators 167 | 168 | Flags are ANDed by default, but can also achieve OR and NOT functionality. 169 | 170 | 171 | ## AND 172 | 173 | List files greater bigger than 500k (`+500k`) and named `bigFile.txt` 174 | (`-name bigFile.txt`). These two commands are equivalent: 175 | 176 | $ find ./searchdir -size +500k -name bigFile.txt 177 | $ find ./searchdir -size +500k -and -name bigFile.txt 178 | 179 | 180 | ## OR 181 | 182 | List files bigger than 500k (`+500k`) or those that are named `smallFile.txt` 183 | (`-or -name smallFile.txt`): 184 | 185 | find ./searchdir -size +500k -or -name smallFile.txt 186 | 187 | 188 | ## NOT 189 | 190 | List files bigger than 50 megabytes (`-size +50M`) that are not named 191 | `unwanted.txt` (`-not -name unwanted.txt`): 192 | 193 | find ./searchdir -size +50M ! -name unwanted.txt 194 | 195 | 196 | 197 | # Execute Commands on Results 198 | 199 | You can execute a command on all matched files using the `-exec` option. The 200 | string `{}` will be replaced with the name of the matched file, and the command 201 | must be terminated with an escaped semicolon (`\;`). 202 | 203 | 204 | ## Change Permissions 205 | 206 | Give all files (`-type f`) 755 permissions (`-exec chmod 755 '{}' \;`): 207 | 208 | find ./searchdir -type f -exec chmod 755 '{}' \; 209 | 210 | 211 | ## Delete 212 | 213 | Deleting files has its own flag. Find all files (`-type f`) ending with a tilde 214 | (`-name '*~'`) and remove them (`-delete`): 215 | 216 | find ./searchdir -type f -name '*~' -delete 217 | 218 | 219 | -------------------------------------------------------------------------------- /eg/examples/free.md: -------------------------------------------------------------------------------- 1 | # free 2 | 3 | show memory usage 4 | 5 | free 6 | 7 | 8 | show memory usage in megabytes 9 | 10 | free -m 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Show the memory usage on the system: 17 | 18 | free 19 | 20 | 21 | -------------------------------------------------------------------------------- /eg/examples/gcc.md: -------------------------------------------------------------------------------- 1 | # gcc 2 | 3 | compile main.c (default executable output is a.out) 4 | 5 | gcc main.c 6 | 7 | 8 | compile main.c into an outfile file main.o 9 | 10 | gcc main.c -o main.o 11 | 12 | 13 | compile main.c and enable all warnings 14 | 15 | gcc -Wall main.c 16 | 17 | 18 | compile main.c but do not run the linker 19 | 20 | gcc -c main.c 21 | 22 | 23 | do not compile, only run the linker 24 | 25 | gcc main.o 26 | 27 | 28 | compile with maximum optimization level (O as in optimize) 29 | 30 | gcc -O3 main.c 31 | 32 | 33 | compile with size optimization enabled (O as in optimize) 34 | 35 | gcc -Os main.c 36 | 37 | 38 | assemble main.c (default output is main.s) 39 | 40 | gcc -S main.c 41 | 42 | 43 | 44 | # Basic Usage 45 | 46 | Compile a file using the GNU compiler: 47 | 48 | gcc 49 | 50 | 51 | 52 | # Note 53 | 54 | `gcc` can be replaced by `g++` to compile C++ files. It can also be replaced by 55 | `clang` and `clang++` to use the Clang compiler instead, which has the same 56 | command line interface. 57 | 58 | 59 | -------------------------------------------------------------------------------- /eg/examples/git.md: -------------------------------------------------------------------------------- 1 | # git 2 | 3 | pull changes into the local repository from the master branch at origin 4 | 5 | git pull origin master 6 | 7 | 8 | change the previous commit 9 | 10 | git commit --amend 11 | 12 | 13 | show all branches with the current indicated by an asterisk 14 | 15 | git branch 16 | 17 | 18 | discard all changes and return to the last commit 19 | 20 | git reset --hard HEAD 21 | 22 | 23 | unstage changes to foo.py that have been added 24 | 25 | git reset path/to/foo.py 26 | 27 | 28 | show the contents of bar.java at revision e8883f 29 | 30 | git show e8883f:path/to/bar.java 31 | 32 | 33 | show diff of baz.go between commits affbc and 6d680 34 | 35 | git diff affbc 6d680 -- path/to/baz.go 36 | 37 | 38 | push all branches to the origin 39 | 40 | git push origin --all 41 | 42 | 43 | show all remotes 44 | 45 | git remote -v 46 | 47 | 48 | switch to the branch named bugfix 49 | 50 | git checkout bugfix 51 | 52 | 53 | view the commit history 54 | 55 | git log 56 | 57 | 58 | 59 | # Basic Usage 60 | 61 | Execute a command: 62 | 63 | git 64 | 65 | 66 | View the manpages for a command: 67 | 68 | git help 69 | 70 | 71 | `git` is complex. It takes a number of verb-like commands that control `git` 72 | repositories and files. Examples are shown in sections for commands and for 73 | specific scenarios. 74 | 75 | 76 | 77 | # add 78 | 79 | `add` is used to make files and changes known to git. 80 | 81 | Add `foo.py`: 82 | 83 | git add foo.py 84 | 85 | 86 | Add all changes in the repository (`-A`), adding, modifying, and removing as 87 | necessary: 88 | 89 | git add -A 90 | 91 | 92 | 93 | # branch 94 | 95 | Display all local branches with the current branch indicated by `*`: 96 | 97 | git branch 98 | 99 | 100 | Display all remote (`-r`) branches: 101 | 102 | git branch -r 103 | 104 | 105 | Display all (`-a`) branches, including remote branches: 106 | 107 | git branch -a 108 | 109 | 110 | Delete (`-d`) the branch `dead`: 111 | 112 | git branch -d dead 113 | 114 | 115 | Display verbose (`-v`) information local branches: 116 | 117 | git branch -v 118 | 119 | 120 | Rename or move (`-m`) the current branch to be named `newname`: 121 | 122 | git branch -m newname 123 | 124 | 125 | Rename or move (`-m`) the branch `oldname` to be named `newname`: 126 | 127 | git branch -m oldname newname 128 | 129 | 130 | 131 | ## Remote Tracking Branches 132 | 133 | Tracking branches are those that are associated with a remote branch. 134 | Differences between remote and local branches are shown with commands similar 135 | to `git status` if the branch is tracking. A branch can be made to track a 136 | particular remote using the `-u` or equivalent `--set-upstream-to` flag. 137 | 138 | This command will cause the current branch to track the branch named `trackme` 139 | at the remote named `origin`: 140 | 141 | git branch -u origin/trackme 142 | 143 | 144 | 145 | # checkout 146 | 147 | `checkout` is used to switch between branches. 148 | 149 | Switch to the `master` branch: 150 | 151 | git checkout master 152 | 153 | 154 | Create a new branch (`-b`) called `bugfix` and switch to it: 155 | 156 | git checkout -b bugfix 157 | 158 | 159 | 160 | ## Checking Out a Remote Branch 161 | 162 | Checking out a remote branch is somewhat more complicated. First you must make 163 | sure your local repository has downloaded the remote branch using `git fetch`. 164 | At that point you can refer to the branch using `remote-name/branch-name` 165 | syntax. A full sequence of commands to create a new branch named `rem-feature` 166 | starting at a branch named `feature` from a remote named `origin` would be the 167 | following: 168 | 169 | git fetch 170 | git checkout -b rem-feature origin/feature 171 | 172 | 173 | 174 | # clean 175 | 176 | `clean` is used to delete or purge untracked files and directories from your 177 | repository. 178 | 179 | Show but do not delete (`--dry-run`) files that would be deleted with by 180 | calling the `clean` command: 181 | 182 | git clean -fd --dry-run 183 | 184 | 185 | The force (`-f`) flag is used to force files to be deleted, while `-d` 186 | indicates that directories should also be deleted. Note that this is 187 | irreversible and should be used carefully, generally after seeing what would 188 | happen by using the `--dry-run` flag: 189 | 190 | git clean -f -d 191 | 192 | 193 | 194 | # clone 195 | 196 | `clone` is used to copy a repository, especially from remote locations. 197 | 198 | Clone the `eg` repository into the current directory: 199 | 200 | git clone git@github.com:srsudar/eg.git 201 | 202 | 203 | Clone the `eg` repository into a new directory called `mydir`: 204 | 205 | git clone https://github.com/srsudar/eg.git mydir 206 | 207 | 208 | 209 | # commit 210 | 211 | Commit staged changes: 212 | 213 | git commit 214 | 215 | 216 | Commit staged changes with the message "Update readme" (`-m "Update readme"`): 217 | 218 | git commit -m "Update readme" 219 | 220 | 221 | Update the last commit (`--amend`). An editor will open giving you a chance to 222 | edit the commit message. Staged changes will be combined with the changes of 223 | the previous commit: 224 | 225 | git commit --amend 226 | 227 | 228 | 229 | # config 230 | 231 | `config` is used to display and set configuration variables. The `--global` 232 | command is used to refer to global variables, while `--local` refers to 233 | repository-specific versions. Without a final argument the variable is 234 | displayed. Adding a final argument sets the value to that variable. 235 | 236 | Display the global (`--global`) name of the user (`user.name`): 237 | 238 | git config --global user.name 239 | 240 | 241 | Set the global (`--global`) name of the user (`user.name`) to Tyrion Lannister: 242 | 243 | git config --global user.name "Tyrion Lannister" 244 | 245 | 246 | List (`--list`) all the global (`--global`) variables: 247 | 248 | git config --list --global 249 | 250 | 251 | 252 | # diff 253 | 254 | Show the differences in the working tree: 255 | 256 | git diff 257 | 258 | 259 | Show the differences that have been added to the index via `git add`: 260 | 261 | git diff --cached 262 | 263 | 264 | Show the differences in the file `baz.go` between commits `affbc` and `6d680`: 265 | 266 | git diff affbc 6d680 -- path/to/baz.go 267 | 268 | 269 | Show the differences between `foo.txt` on commit `6d680` and `bar.txt` on 270 | commit `af8cea`: 271 | 272 | git diff 6d680:path/to/foo.txt af8cea:path/to/bar.txt 273 | 274 | 275 | 276 | # pull 277 | 278 | `pull` is used to get and merge changes from a remote repository into a local 279 | repository. It is roughly equivalent to running `git fetch` to get changes 280 | followed by a `git merge` to merge those changes into the local commit history. 281 | 282 | Get and merge changes from the `mybranch` branch at `origin` into the current 283 | branch: 284 | 285 | git pull origin mybranch 286 | 287 | 288 | 289 | # push 290 | 291 | `push` is used to send changes to a remote location. In these examples the name 292 | of the remote is always `origin`. This will push changes from the local 293 | `master` branch to the `master` branch at `origin`: 294 | 295 | git push origin master 296 | 297 | 298 | All branches can be pushed using the `--all` flag: 299 | 300 | git push --all origin 301 | 302 | 303 | All tags can be pushed with the `--tags` flag: 304 | 305 | git push --tags origin 306 | 307 | 308 | Changes can also be pushed from one branch to a branch with a different name. 309 | This will push changes from the local `pushme` branch onto the remote `accept` 310 | branch at `origin`: 311 | 312 | git push origin pushme:accept 313 | 314 | 315 | Delete the remote branch `oldbranch` at the `origin`: 316 | 317 | git push --delete oldbranch 318 | 319 | 320 | Push a local branch named `feature` to `origin` for the first time, setting up 321 | tracking (`-u`) to ensure that differences are displayed with commands such as 322 | `git status`: 323 | 324 | git push -u origin feature 325 | 326 | 327 | 328 | # reset 329 | 330 | `reset` moves the `HEAD` to a different commit, effectively reverting or 331 | undoing commits. The commits themselves are left intact and can still be seen 332 | with `git reflog`. 333 | 334 | Restore the `HEAD` to the third most recent commit (`HEAD~2`), updating the 335 | working tree to be identical to that commit (`--hard`): 336 | 337 | git reset --hard HEAD~2 338 | 339 | 340 | Restore the `HEAD` to the third most recent commit (`HEAD~2`), leaving all 341 | changes until that point staged and in the working tree (`--soft`): 342 | 343 | git reset --soft HEAD~2 344 | 345 | 346 | 347 | # stash 348 | 349 | `stash` is used to remove but save changes to the working directory. Stashes 350 | are referred to using a `stash@{0}` syntax, where `stash@{0}` is the most 351 | recent stash. Note that some shells, including zsh, require that the stash be 352 | escaped to something like `stash\@\{0\}`. 353 | 354 | Show all stashes: 355 | 356 | git stash list 357 | 358 | 359 | Apply the most recent stash: 360 | 361 | git stash apply 362 | 363 | 364 | Apply the second to most recent stash (`stash@{1}`): 365 | 366 | git stash apply stash@{1} 367 | 368 | 369 | Delete (`drop`) the third most recent stash (`stash@{2}`): 370 | 371 | git stash drop stash@{2} 372 | 373 | 374 | 375 | # submodule 376 | 377 | Submodules are git repositories within a repository. They are frequently used 378 | if you need to include code from another git repository within your own 379 | repository. 380 | 381 | Adding a submodule for the first time is simple using the `git submodule add`. 382 | This example adds the `eg` repository as submodule in the current directory: 383 | 384 | git submodule add git@github.com:srsudar/eg.git 385 | 386 | 387 | If you are cloning a repository that contains submodules you will need to issue 388 | two commands to ensure that the submodules are up to date (`update`) and 389 | initialized (`--init`). The `--recursive` flag is also used to ensure that 390 | submodules at all levels are also initialized: 391 | 392 | git submodule update --init --recursive 393 | 394 | 395 | Deleting submodules is not so simple. Recent versions of git have a `deinit` 396 | command that can be passed to `submodule`, but unfortunately it leaves 397 | references to the submodule in git config files. To completely delete a 398 | submodule, run this sequence of commands to remove the submodule from most of 399 | the config files (`deinit`), delete the local directory (`git rm`), and remove 400 | the last references to the submodule (`rm -rf`). This assumes that a submodule 401 | named `eg` is at the top level of the repository and that the current working 402 | directory contains the `.git` directory: 403 | 404 | git submodule deinit eg 405 | git rm eg 406 | rm -rf .git/submodules/eg 407 | 408 | 409 | 410 | # tag 411 | 412 | `tag` is used to mark a specific commit. Unlike branches, tags do not move as 413 | additional commits are made. Tags come in two flavors, annotated or basic. In 414 | general annotated tags should be used, as they behave as full objects and can 415 | contain useful information like a message and the name of the committer. 416 | 417 | List (`--list`) all tags: 418 | 419 | git tag --list 420 | 421 | 422 | When an annotated tag is created an editor opens to compose a tag message. This 423 | command creates an annotated (`-a`) tag named `v1.0` pointing at the current 424 | commit: 425 | 426 | git tag -a v1.0 427 | 428 | 429 | Create an annotated (`-a`) tag named `v2.0` pointing at the commit with the 430 | hash `u76a7s`: 431 | 432 | git tag -a v2.0 u76a6s 433 | 434 | 435 | Delete (`-d`) the tag `badtag`: 436 | 437 | git tag -d badtag 438 | 439 | 440 | Tags must be pushed separately, using the `--tags` flag to `push`: 441 | 442 | git push origin --tags 443 | 444 | 445 | 446 | # Restoring Deleted Files 447 | 448 | Files that have been committed can be restored even if they are later deleted. 449 | This will restore a file that has been deleted locally but that was still 450 | present on the `HEAD` commit: 451 | 452 | git checkout HEAD path/to/file.txt 453 | 454 | 455 | This will checkout a file that was deleted an arbitrary number of commits 456 | previously but that was present at the commit with the hash `ef8bca`: 457 | 458 | git checkout ef8bca path/to/file.txt 459 | 460 | 461 | If the file was deleted at an unknown time, the commit when it was deleted must 462 | first be found. The first command (`git rev-list`) will output the hash of a 463 | single commit (`-n 1`), starting at the `HEAD`, that affected the file 464 | `path/to/file.txt`. In this example the hash is `af8abe`. Since this commit 465 | deleted the file, the parent comment (`af8abe^`) is the last commit where the 466 | file was intact. `checkout` is used to restore the file at that revision: 467 | 468 | $ git rev-list -n 1 HEAD -- path/to/file.txt 469 | af8abe 470 | $ git checkout af8abe^ -- path/to/file.txt 471 | 472 | 473 | 474 | # Combining Commits 475 | 476 | There are several ways to combine or squash commits together. The option using 477 | `git reset` is likely the simplest to understand, but each can be used to 478 | accomplish the same thing. 479 | 480 | All these examples show how to merge the previous three commits into a single 481 | commit. It is assumed that there are no changes shown by `git status`. Recall 482 | that `HEAD~3` refers to the fourth most recent commit, as `HEAD` is equivalent 483 | to `HEAD~0`. 484 | 485 | 486 | 487 | ## Using reset 488 | 489 | You can combine commits them simply by using `reset`. The first command will 490 | move the `HEAD` to the fourth most recent commit (`HEAD~3`), leaving all the 491 | changes that had been made intact (`--soft`). The working tree will not differ 492 | from before the `git reset` command, and all the changes will be staged as if 493 | they had been made at one time. `git commit` will commit these changes: 494 | 495 | git reset --soft HEAD~3 496 | git commit 497 | 498 | 499 | 500 | ## Using merge 501 | 502 | Commits can also be combined using `merge` with the `--squash` command. This 503 | command will merge the branch `squashme` into the current branch. However, no 504 | changes will be committed. Every change will be staged and ready to commit: 505 | 506 | git merge --squash mergeme 507 | 508 | 509 | At this point, calling `git commit` will prepare a detailed commit message with 510 | the hashes and messages of the previous commits. 511 | 512 | 513 | 514 | ## Using rebase 515 | 516 | Finally, you can also accomplish this using the `rebase` command and the `-i` 517 | or `--interactive` flag. This command will start an interactive (`-i`) rebase, 518 | starting with all commits more recent than the commit pointed to by `HEAD~4`. 519 | An editor will open with instructions of how to edit the rebase script. The 520 | order is oldest to newest, the opposite of `git log`, and should be thought of 521 | as being applied from top to bottom. As opened, saving the script will replay 522 | the commit history without changing. Changing `pick` to `squash` will combine 523 | the edits in the commit with the previous commit. 524 | 525 | This will start an interactive (`-i`) rebase starting at the fifth to last 526 | commit (`HEAD~4`): 527 | 528 | rebase -i HEAD~4 529 | 530 | 531 | Editing the script to look like the following and saving will cause the commits 532 | to be merged into the first commit. Note that the first command is a `pick`: 533 | 534 | pick hash1 535 | squash hash2 536 | squash hash3 537 | squash hash4 538 | 539 | 540 | 541 | # Undoing a Commit 542 | 543 | As with almost everything in git, there are several ways to undo a commit. 544 | 545 | If you need to make a change to only the commit message, you can use the commit 546 | command with the `--amend` flag: 547 | 548 | git commit --amend 549 | 550 | 551 | If you want to completely throw away a commit, reverting to the state of the 552 | previous commit, use `reset` with the `--hard` flag, which updates the working 553 | tree to the state at the target commit. In this case we use `HEAD~1` to 554 | indicate the second to last commit: 555 | 556 | git reset --hard HEAD~1 557 | 558 | 559 | If you want to keep most of the changes in the last commit and just make a few 560 | changes, use `reset` with the `--soft` flag, which keeps the changes staged: 561 | 562 | git reset --soft HEAD~1 563 | 564 | 565 | Simply calling `reset` without a flag will keep the changes in the working tree 566 | without staging them: 567 | 568 | git reset HEAD~1 569 | 570 | 571 | 572 | # Discarding Unstaged Changes 573 | 574 | If you have staged changes that you want to keep and want only to discard 575 | unstaged changes, you can't use `reset`. Instead you need two commands. The 576 | first will delete untracked files (`git clean -f`) and directories (`-d`). The 577 | second will checkout the current branch's version of all files in the current 578 | directory (`.`): 579 | 580 | git clean -d -f 581 | git checkout -- . 582 | 583 | 584 | Keep in mind that you should consider running `git clean` with the `--dry-run` 585 | flag first to make sure you don't irreversibly delete something you don't mean 586 | to. 587 | 588 | 589 | 590 | # Initializing a Repository 591 | 592 | `git init` is used to create a repository. This sequence of commands is common 593 | when initializing a repository for the first time. It initializes the 594 | repository (`git init`), adds an existing file (`git add`), commits this change 595 | (`git commit`), adds a remote repository (`git remote`), and pushes the 596 | `master` branch to this repository (`git push`): 597 | 598 | git init 599 | git add README.md 600 | git commit -m "first commit" 601 | git remote add origin https://github.com/me/myrepo.git 602 | git push -u origin master 603 | 604 | 605 | -------------------------------------------------------------------------------- /eg/examples/grep.md: -------------------------------------------------------------------------------- 1 | # grep 2 | 3 | print all lines containing foo in input.txt 4 | 5 | grep "foo" input.txt 6 | 7 | 8 | print all lines matching the regex "^start" in input.txt 9 | 10 | grep -e "^start" input.txt 11 | 12 | 13 | print all lines containing bar by recursively searching a directory 14 | 15 | grep -r "bar" directory 16 | 17 | 18 | print all lines containing bar ignoring case 19 | 20 | grep -i "bAr" input.txt 21 | 22 | 23 | print 3 lines of context before and after each line matching "foo" 24 | 25 | grep -C 3 "foo" input.txt 26 | 27 | 28 | 29 | # Basic Usage 30 | 31 | Search each line in `input_file` for a match against `pattern` and print 32 | matching lines: 33 | 34 | grep "" 35 | 36 | 37 | 38 | # Find Lines NOT Matching 39 | 40 | Print lines that do NOT match a pattern by using the `-v` flag. This will print 41 | all lines that do NOT contain a z (`-v "z"`): 42 | 43 | grep -v "z" input.txt 44 | 45 | 46 | 47 | # Print File Names 48 | 49 | Show only the file names containing matches, rather than the matching lines 50 | themselves, by using the `-l` flag: 51 | 52 | grep -r -l "target_pattern" directory 53 | 54 | 55 | Show only the file names that do NOT contain matches by using the `-L` flag: 56 | 57 | grep -r -L "unwanted_pattern" directory 58 | 59 | 60 | 61 | # Regular Expressions and `egrep` 62 | 63 | Regular expressions can be passed to `grep` using the `-e` flag. `egrep` is 64 | equivalent to using the `-e` flag. 65 | 66 | The following file is used in the examples: 67 | 68 | $ cat input.txt 69 | 1 2 3 70 | omega 71 | alpha foo 72 | alpha bar 73 | baz omega 74 | 4 5 6 75 | 76 | 77 | Match lines beginning (`^`) with `alpha` (`^alpha`): 78 | 79 | $ grep -e "^alpha" input.txt 80 | alpha foo 81 | alpha bar 82 | 83 | 84 | Match lines ending (`$`) with `omega` (`omega$`): 85 | 86 | $ grep -e "omega$" input.txt 87 | omega 88 | baz omega 89 | 90 | 91 | Match any line containing `a` and `o` separated by 0 or more characters (`.*`): 92 | 93 | $ grep -e "a.*o" input.txt 94 | alpha foo 95 | baz omega 96 | 97 | 98 | Match any line containing `z` or `f` (`[zf]`): 99 | 100 | $ grep -e "[zf]" input.txt 101 | alpha foo 102 | baz omega 103 | 104 | 105 | Match any line containing `hello` or `world`: 106 | 107 | $ grep "hello\|world" input.txt 108 | hello alpha 109 | omega world 110 | 111 | 112 | Match all lines with lower case or capital letters a through z (`[a-zA-Z]`): 113 | 114 | $ grep -e "[a-zA-Z]" input.txt 115 | omega 116 | alpha foo 117 | alpha bar 118 | baz omega 119 | 120 | 121 | Match all lines containing numbers (`[0-9]`): 122 | 123 | $ grep -e "[0-9]" input.txt 124 | 1 2 3 125 | 4 5 6 126 | 127 | 128 | Match all lines containing white space (`[[:space:]]`): 129 | 130 | $ grep -e "[[:space:]]" input.txt 131 | 1 2 3 132 | alpha foo 133 | alpha bar 134 | baz omega 135 | 4 5 6 136 | 137 | 138 | # Fixed Expressions and `fgrep` 139 | 140 | `fgrep` is faster than `grep` and `egrep` but only accepts fixed expressions. 141 | This will match lines containing the exact sequence `.*` (`'.*'`). Quoting is 142 | used to prevent shell expansion of the wildcard `*` character: 143 | 144 | fgrep '.*' input.txt 145 | 146 | 147 | 148 | # Searching Compressed Files 149 | 150 | `zgrep`, `zegrep`, and `zfgrep` act exactly like `grep`, `egrep`, and `fgrep`, 151 | but they operate on compressed and gzipped files. The same examples shown above 152 | will function with the `z*grep` utilities. 153 | 154 | 155 | -------------------------------------------------------------------------------- /eg/examples/gzip.md: -------------------------------------------------------------------------------- 1 | # gzip 2 | 3 | compress a file 4 | 5 | gzip file_to_compress 6 | 7 | 8 | decompress a file 9 | 10 | gzip -d file_to_decompress 11 | 12 | 13 | compress a file and keep original 14 | 15 | gzip --keep file_to_compress 16 | 17 | 18 | decompress a file and keep original 19 | 20 | gzip --keep -d file_to_decompress 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | `gzip` by default deletes the file that is being compressed or decompressed. To 27 | keep the original file use the `--keep` flag. 28 | 29 | 30 | -------------------------------------------------------------------------------- /eg/examples/head.md: -------------------------------------------------------------------------------- 1 | # head 2 | 3 | print the first 10 lines of a file to stdout 4 | 5 | head file.txt 6 | 7 | 8 | print the first 20 lines of file1.txt and file2.txt 9 | 10 | head -n 20 file1.txt file2.txt 11 | 12 | 13 | print the first 10 bytes of a file 14 | 15 | head -c 10 file.txt 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Print the first lines of a file: 22 | 23 | head 24 | 25 | 26 | -------------------------------------------------------------------------------- /eg/examples/hexdump.md: -------------------------------------------------------------------------------- 1 | # hexdump 2 | 3 | show file byte content in hex with hex offset 4 | 5 | hexdump in_hex.txt 6 | 7 | 8 | show file content in a more human readable manner 9 | 10 | hexdump -e '7/ "%5_ad:%-5_c" "\n"' human_readable.txt 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Show the byte content of a file in hex: 17 | 18 | hexdump 19 | 20 | 21 | 22 | # Advanced Formatting 23 | 24 | The output of `hexdump` can be highly customized with the `-e` flag. 25 | 26 | The following file is used in this example: 27 | 28 | $ cat abc.txt 29 | a b 30 | c 31 | 1 2 3 32 | 33 | 34 | This command prints seven bytes (`7/`) and delimits these bytes with a 35 | new line (`\n`). It shows the input offset of each byte in decimal (`_ad`) 36 | padded to five characters (`%5`). Then display a colon (`:`) and the character 37 | itself (`_c`) padded to five trailing characters (`%-5`): 38 | 39 | $ hexdump -e '7/ "%5_ad:%-5_c" "\n"' abc.txt 40 | 0:a 1: 2:b 3:\n 4:c 5:\n 6:1 41 | 7: 8:2 9: 10:3 11:\n : : 42 | 43 | 44 | -------------------------------------------------------------------------------- /eg/examples/ifconfig.md: -------------------------------------------------------------------------------- 1 | # ifconfig 2 | 3 | display information about network interfaces 4 | 5 | ifconfig 6 | 7 | 8 | display MAC addresses 9 | 10 | ifconfig | grep ether 11 | 12 | 13 | set a new MAC address to en0 14 | 15 | sudo ifconfig en0 ether aa:bb:cc:dd:ee:ff 16 | 17 | 18 | display local IP addresses 19 | 20 | ifconfig | grep 'inet ' | grep -v '127.0.0.1' | cut -d' ' -f2 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | Display basic information: 27 | 28 | ifconfig 29 | 30 | 31 | Set network parameters: 32 | 33 | sudo ifconfig 34 | 35 | 36 | -------------------------------------------------------------------------------- /eg/examples/ip.md: -------------------------------------------------------------------------------- 1 | # ip 2 | 3 | display device attributes 4 | 5 | ip link show 6 | 7 | 8 | enable a network interface 9 | 10 | ip link set eth0 up 11 | 12 | 13 | disable a network interface 14 | 15 | ip link set eth0 down 16 | 17 | 18 | assign an IP address to an interface 19 | 20 | ip addr add 10.0.0.2/24 dev eth0 21 | 22 | 23 | delete the IP address from an interface 24 | 25 | ip addr del 10.0.0.2/24 dev eth0 26 | 27 | 28 | view the routing table 29 | 30 | ip route show 31 | 32 | 33 | set a route to the locally connected network 34 | 35 | ip route add 10.0.0.0/24 dev eth0 36 | 37 | 38 | set a route to a different network 39 | 40 | ip route ass 192.168.1.0/24 via 10.0.0.100 41 | 42 | 43 | set a default route 44 | 45 | ip route add default via 10.0.0.254 46 | 47 | 48 | delete routes from the routing table 49 | 50 | ip route delete 192.168.1.0/24 dev eth0 51 | 52 | 53 | 54 | # Basic Usage 55 | 56 | Display info about all network interfaces: 57 | 58 | ip addr 59 | 60 | 61 | Use the `ip` command to display and configure the network parameters for host 62 | interfaces. The first argument after `ip` is referred to as the OBJECT. Type 63 | `ip` to see the list of valid OBJECT arguments on your machine. Typing `help` 64 | after the OBJECT will provide more detailed information. This will display 65 | information about the `addr` OBJECT: 66 | 67 | ip addr help 68 | 69 | 70 | 71 | # Address Resolution Protocol (ARP) 72 | 73 | Show ARP cache: 74 | 75 | ip neigh show 76 | 77 | 78 | Add a new ARP entry. Valid STATE arguments are `permanent`, `noarp`, `stale`, 79 | and `reachable`: 80 | 81 | ip neigh add lladdr dev nud 82 | 83 | 84 | Delete ARP entry: 85 | 86 | ip neigh del dev 87 | 88 | 89 | Flush ARP entry: 90 | 91 | ip -s -s n f 92 | 93 | 94 | 95 | # OSX 96 | 97 | `ip` is not available by default on OSX. Install `iproute2mac` to make `ip` 98 | available (`brew install iproute2mac`). This is a similar tool to `ip` on 99 | Linux, but it is not identical and some examples here may not work. 100 | 101 | 102 | -------------------------------------------------------------------------------- /eg/examples/keytool.md: -------------------------------------------------------------------------------- 1 | # keytool 2 | 3 | list detailed info about entries in keystore 4 | 5 | keytool -v -list -keystore keys.keystore 6 | 7 | 8 | list only info about release alias 9 | 10 | keytool -v -list -keystore keys.keystore -alias release 11 | 12 | 13 | view a certificate 14 | 15 | keytool -v -printcert -file certificate.crt 16 | 17 | 18 | delete the alias deleteme from the keystore 19 | 20 | keytool -delete -alias deleteme -keystore keys.keystore 21 | 22 | 23 | change the top level password of the keystore 24 | 25 | keytool -storepasswd -keystore keys.keystore 26 | 27 | 28 | change the password for the changeme alias 29 | 30 | keytool -keypasswd -alias changeme -keystore keys.keystore 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | List the contents of a keystore: 37 | 38 | keytool -v -list -keystore 39 | 40 | 41 | 42 | # Generate a Key Pair 43 | 44 | `keytool` can give rise to many long commands. This command generates a key 45 | pair (`-genkey`) inside `keys.keystore`, creating if it doesn't exist. It also 46 | generates an alias called `release` (`-alias release`) using the RSA algorithm 47 | (`-keyalg RSA`). The key will be of size 2048 (`-keysize 2048`) and be valid 48 | for 10,000 years (`-validity 10000`): 49 | 50 | keytool -genkey -v -keystore keys.keystore -alias release \ 51 | -keyalg RSA -keysize 2048 -validity 10000 52 | 53 | 54 | You will be prompted to enter a password for both the keystore itself (entering 55 | it twice if you are creating the keystore for the first time) a password for 56 | the alias, and information about your organization. This keystore can be used 57 | to sign JAR files and Android apk files. 58 | 59 | 60 | -------------------------------------------------------------------------------- /eg/examples/kill.md: -------------------------------------------------------------------------------- 1 | # kill 2 | 3 | politely kill process with id 25371 4 | 5 | kill 25371 6 | 7 | 8 | send non-catchable, non-ignorable kill to process with id 22204 9 | 10 | kill -9 22204 11 | 12 | 13 | list all signals 14 | 15 | kill -l 16 | 17 | 18 | kill background job with id 1 19 | 20 | kill %1 21 | 22 | 23 | kill most recent background job 24 | 25 | kill %% 26 | 27 | 28 | send an INT signal process 25929 29 | 30 | kill -s INT 25929 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | Stop a target process using a polite `TERM` signal that allows for resource 37 | cleanup: 38 | 39 | kill 40 | 41 | 42 | Stop a target processing impolitely using the `KILL` signal: 43 | 44 | kill -9 45 | 46 | 47 | 48 | # Specifying Targets 49 | 50 | By default `kill` expects a process id. This will kill the process with PID 51 | 25371: 52 | 53 | kill 25371 54 | 55 | 56 | Background jobs can be referred to by with a preceding `%`. This will kill the 57 | background job 1 (`%1`): 58 | 59 | $ jobs 60 | [1] + suspended node 61 | $ kill %1 62 | [1] + 25854 exit 143 node 63 | $ jobs 64 | $ 65 | 66 | 67 | 68 | # Sending Other Signals 69 | 70 | `kill` sends a software termination `TERM` signal by default. Other signals can 71 | be specified with the `-s` flag and their name. Signals can also be referred to 72 | by their numeric code. The complete list of signals can be seen with the `-l` 73 | flag: 74 | 75 | kill -l 76 | 77 | 78 | The `-l` flag can also be used to map between signal name and signal code: 79 | 80 | $ kill -l INT 81 | 2 82 | $ kill -l 2 83 | INT 84 | 85 | 86 | This will send (`-s`) an interrupt (`INT`) signal to process 26089: 87 | 88 | kill -s INT 26089 89 | 90 | 91 | The `INT` signal is code `2`, so this command is equivalent to the above: 92 | 93 | kill -2 26089 94 | 95 | 96 | The strongest signal is `KILL`, which has code `9`. This is non-catchable and 97 | non-ignorable. It may fail for a zombie process or under unusual circumstances, 98 | but in the vast majority of cases it will force stop a process. Processes 99 | won't be made aware of the kill request and won't have a chance to clean up 100 | resources. This will send a `KILL` signal (`-9`) to process 22604: 101 | 102 | kill -9 22604 103 | 104 | 105 | -------------------------------------------------------------------------------- /eg/examples/less.md: -------------------------------------------------------------------------------- 1 | # less 2 | 3 | page file to stdout 4 | 5 | less file.txt 6 | 7 | 8 | page file starting at line 25 9 | 10 | less +25 file.txt 11 | 12 | 13 | page file starting at first line containing "pattern" 14 | 15 | less +/"pattern" file.txt 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Show the file on `stdout`, paging the input: 22 | 23 | less 24 | 25 | 26 | Once in `less` use `j` to scroll down, `k` to scroll up, and `q` to quit. 27 | 28 | `gg` goes to the top of the file and `G` goes to the bottom. 29 | 30 | Press `h` to get help and see the full list of commands. 31 | 32 | 33 | -------------------------------------------------------------------------------- /eg/examples/ln.md: -------------------------------------------------------------------------------- 1 | # ln 2 | 3 | make a symlink to `foo.txt` 4 | 5 | ln -s foo.txt link-to-foo.txt 6 | 7 | 8 | 9 | # Basic Usage 10 | 11 | Make anchor a link to target: 12 | 13 | ln -s 14 | 15 | 16 | 17 | # Symbolic Links (symlinks) 18 | 19 | Make it symbolic with the `-s` flag: 20 | 21 | $ ln -s foo.txt link-to-foo.txt 22 | $ ls -lF 23 | total 8 24 | -rw-r--r-- 1 tyrion group 0 Feb 3 14:13 foo.txt 25 | lrwxr-xr-x 1 tyrion group 7 Feb 3 14:14 link-to-foo.txt@ -> foo.txt 26 | 27 | 28 | 29 | # Hard Links 30 | 31 | Omit the `-s` flag: 32 | 33 | $ ln foo.txt hard-link-to-foo.txt 34 | $ ls -lF 35 | total 0 36 | -rw-r--r-- 2 tyrion group 0B Feb 3 14:13 foo.txt 37 | -rw-r--r-- 2 tyrion group 0B Feb 3 14:13 hard-link-to-foo.txt 38 | 39 | 40 | -------------------------------------------------------------------------------- /eg/examples/locate.md: -------------------------------------------------------------------------------- 1 | # locate 2 | 3 | find a file where any part of path matches foo 4 | 5 | locate foo 6 | 7 | 8 | find a file where only the base file name itself, not the path, matches foo 9 | 10 | locate -b foo 11 | 12 | 13 | ignore case 14 | 15 | locate -i FoO 16 | 17 | 18 | count the number of files that match foo 19 | 20 | locate -c foo 21 | 22 | 23 | 24 | # Basic Usage 25 | 26 | `locate` uses a database to quickly find files matching a pattern: 27 | 28 | locate 29 | 30 | 31 | Not all files get included in the database used by `locate`. Only those that 32 | can be seen by the world (i.e. those files where every parent directory has the 33 | world permission set to readable). For this reason it is most reliably used to 34 | find system files. 35 | 36 | 37 | 38 | # Building the Database 39 | 40 | `locate` relies on a database. Usually the system builds automatically, but it 41 | may need to be initialized or updated manually. 42 | 43 | 44 | 45 | ## OSX 10.9 46 | 47 | Update the database: 48 | 49 | $ cd / 50 | $ sudo /usr/libexec/locate.updatedb 51 | 52 | 53 | 54 | ## Linux 55 | 56 | Update the database: 57 | 58 | sudo updatedb 59 | 60 | 61 | -------------------------------------------------------------------------------- /eg/examples/ls.md: -------------------------------------------------------------------------------- 1 | # ls 2 | 3 | show contents of current directory 4 | 5 | ls 6 | 7 | 8 | show contents of directory 9 | 10 | ls directory 11 | 12 | 13 | show contents, hidden files, and stats in human readable form 14 | 15 | ls -alh 16 | 17 | 18 | show extended time information 19 | 20 | ls -lT 21 | 22 | 23 | show with color and indicators of file type 24 | 25 | ls -FG 26 | 27 | 28 | 29 | # Basic Usage 30 | 31 | Display the contents of a directory: 32 | 33 | ls 34 | 35 | 36 | 37 | # Showing Hidden Files 38 | 39 | The `-a` flag will show all files, including those that are hidden, or begin 40 | with a dot. `.` means the current directory, and `..` means the parent 41 | directory: 42 | 43 | $ ls -a 44 | . .. .hidden.txt bar.txt 45 | 46 | 47 | 48 | # Showing More Information 49 | 50 | The `-l` flag will show extended information, including permissions, the number 51 | of hard links to the file, owner, group, size in bytes, and date modified: 52 | 53 | $ ls -l 54 | total 16 55 | drwxr-xr-x 4 tyrion group 136 Feb 7 12:09 directory 56 | -rwxr-xr-x 1 tyrion group 0 Feb 3 14:06 executable 57 | -rw-r--r-- 1 tyrion group 15 Feb 3 14:01 foo.txt 58 | lrwxr-xr-x 1 tyrion group 7 Feb 3 14:06 link-to-foo.txt -> foo.txt 59 | 60 | 61 | Human-readable size formats with units can be shown with the `-h` flag: 62 | 63 | $ ls -lh 64 | total 16 65 | drwxr-xr-x 4 tyrion group 136B Feb 7 12:09 directory 66 | -rwxr-xr-x 1 tyrion group 0B Feb 3 14:06 executable 67 | -rw-r--r-- 1 tyrion group 15B Feb 3 14:01 foo.txt 68 | lrwxr-xr-x 1 tyrion group 7B Feb 3 14:06 link-to-foo.txt -> foo.txt 69 | 70 | 71 | Indicators of file type can be included with the `-F` flag: 72 | 73 | $ ls -F 74 | directory/ executable* foo.txt link-to-foo.txt@ 75 | 76 | 77 | Extended time format can be shown with the `-T` flag: 78 | 79 | $ ls -lT 80 | total 16 81 | drwxr-xr-x 4 tyrion group 136 Feb 7 12:09:34 2015 directory 82 | -rwxr-xr-x 1 tyrion group 0 Feb 3 14:06:15 2015 executable 83 | -rw-r--r-- 1 tyrion group 15 Feb 3 14:01:12 2015 foo.txt 84 | lrwxr-xr-x 1 tyrion group 7 Feb 3 14:06:40 2015 link-to-foo.txt -> foo.txt 85 | 86 | 87 | 88 | # Useful Aliases 89 | 90 | `ls` is often aliased to make the defaults a bit more useful. Here are three 91 | basic aliases. The second two can be remembered by "list long" and "list all": 92 | 93 | $ alias ls='ls -FG' 94 | $ alias ll='ls -lhF' 95 | $ alias la='ll -A' 96 | 97 | 98 | -------------------------------------------------------------------------------- /eg/examples/mkdir.md: -------------------------------------------------------------------------------- 1 | # mkdir 2 | 3 | create a directory 4 | 5 | mkdir directory 6 | 7 | 8 | create a directory with all permissions enabled 9 | 10 | mkdir -m 777 unprotected_directory 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Create a directory: 17 | 18 | mkdir 19 | 20 | 21 | -------------------------------------------------------------------------------- /eg/examples/more.md: -------------------------------------------------------------------------------- 1 | # more 2 | 3 | page file to stdout 4 | 5 | more file.txt 6 | 7 | 8 | page file starting at line 25 9 | 10 | more +25 file.txt 11 | 12 | 13 | page file starting at first line containing "pattern" 14 | 15 | more +/"pattern" file.txt 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Show the file on `stdout`, paging the input: 22 | 23 | more 24 | 25 | 26 | Once in `more` use `j` to scroll down, `k` to scroll up, and `q` to quit. 27 | 28 | 29 | -------------------------------------------------------------------------------- /eg/examples/mv.md: -------------------------------------------------------------------------------- 1 | # mv 2 | 3 | rename a file 4 | 5 | mv old_name.txt new_name.txt 6 | 7 | 8 | move a file to a different directory 9 | 10 | mv foo.txt new_location/foo.txt 11 | 12 | 13 | move a file but prompt before overwriting 14 | 15 | mv -i foo.txt dirWithFoo/ 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | `mv` lets you rename and move files: 22 | 23 | mv 24 | 25 | 26 | -------------------------------------------------------------------------------- /eg/examples/nc.md: -------------------------------------------------------------------------------- 1 | # nc 2 | 3 | receive input on port 1337 4 | 5 | nc -l 1337 6 | 7 | 8 | receive input on port 1337 on GNU nc implementation 9 | 10 | nc -l -p 1337 11 | 12 | 13 | receive input on port 1337 without hanging up after a connection 14 | 15 | nc -k -l 1337 16 | 17 | 18 | send a file to the address 192.168.1.42 on port 1337 19 | 20 | cat file | nc 192.168.1.42 1337 21 | 22 | 23 | send a file to the address 192.168.1.42 on port 1337 with progress 24 | 25 | pv file | nc 192.168.1.42 1337 26 | 27 | 28 | check if 127.0.0.1 is listening on port 80 but do not connect 29 | 30 | nc -vz 127.0.0.1 80 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | Send what is read from stdin to an address and a port: 37 | 38 | nc
39 | 40 | 41 | Send what is read from stdin to an address and a port on the GNU implementation 42 | of `nc`: 43 | 44 | nc
-p 45 | 46 | 47 | Listen on a port and send it to stdout: 48 | 49 | nc -l 50 | 51 | 52 | Listen on a port and send it to stdout on the GNU implementation of `nc`: 53 | 54 | nc -l -p 55 | 56 | 57 | 58 | # Compatibility 59 | 60 | Usage for `nc`, or `netcat`, varies highly depending on your system. Some 61 | implementations require both the `-l` and `-p` flags to listen on a port, for 62 | instance, whereas others explicitly list using the `-l` and `-p` flags together 63 | is an error. Use these examples as a starting point, but turn to `man` for the 64 | specifics of your implementation. 65 | 66 | 67 | -------------------------------------------------------------------------------- /eg/examples/nice.md: -------------------------------------------------------------------------------- 1 | # nice 2 | 3 | set process priority to -15 (high) 4 | 5 | nice -n -15 bash urgentjob.sh 6 | 7 | 8 | set process priority to 15 (low) 9 | 10 | nice -n 15 bash lowpriorityjob.sh 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Set priority to a process at launching: 17 | 18 | nice -n 19 | 20 | 21 | Niceness values range from -20 (highest priority) to 19 (lowest priority). 22 | 23 | 24 | -------------------------------------------------------------------------------- /eg/examples/od.md: -------------------------------------------------------------------------------- 1 | # od 2 | 3 | show character with helpful names and offset in decimal 4 | 5 | od -a -Ad chars.txt 6 | 7 | 8 | show human readable 16 per line 9 | 10 | od -Ad -tc human_readable.txt 11 | 12 | 13 | show escaped characters (\n new line, \t tab, etc) 14 | 15 | od -i chars.txt 16 | 17 | 18 | show character with helpful names and no offset 19 | 20 | od -a -An chars.txt 21 | 22 | 23 | show as single hex characters 24 | 25 | od -t x1 single_hex.txt 26 | 27 | 28 | start after 500kb and only show 30 bytes 29 | 30 | od -j 500k -N 30 bigfile.txt 31 | 32 | 33 | 34 | # Basic Usage 35 | 36 | Show the byte contents of a file in octal with octal offsets: 37 | 38 | od 39 | 40 | 41 | 42 | # Showing Byte Contents of Files 43 | 44 | By default `od` displays the offset and values of files in octal. This can be 45 | modified with flags. The following file is used in these examples: 46 | 47 | $ cat abc.txt 48 | a b 49 | c 50 | 1 2 3 51 | 52 | 53 | Show the contents of the file with useful names (`-a`) and offset in decimal 54 | (`-Ad`): 55 | 56 | $ od -a -Ad abc.txt 57 | 0000000 a sp b nl c nl 1 sp 2 sp 3 nl 58 | 0000012 59 | 60 | 61 | Show the contents of the file with characters escaped in the C style(`-c`) and 62 | the offset in hex (`-Ax`): 63 | 64 | $ od -c -Ax abc.txt 65 | 0000000 a b \n c \n 1 2 3 \n 66 | 000000c 67 | 68 | 69 | -------------------------------------------------------------------------------- /eg/examples/patch.md: -------------------------------------------------------------------------------- 1 | # patch 2 | 3 | apply unified.patch containing unified context to the file specified therein 4 | 5 | patch 24 | 25 | 26 | Apply a patch file without unified context: 27 | 28 | patch file-to-patch.txt < 29 | 30 | 31 | See `eg diff` for more discussion on unified context. 32 | 33 | 34 | 35 | # Accounting for Patch File Location 36 | 37 | By default, the file specified by a unified context is assumed to be in the 38 | current directory. However, the file specified in unified context can include 39 | more specific path information. This can be taken into account by `patch` by 40 | using the `-p` command, which allows you to store the patch file at a different 41 | location. 42 | 43 | The `-p` command takes a numeric value. It modifies the search path of the file 44 | by stripping a leading string by consuming as many slashes as possible from the 45 | path in the patch file. A value of 0 will cause `patch` to take the entire path 46 | rather than look in the current directory. 47 | 48 | If the file name in the patch file is `/absolute/path/to/repo/file.txt`, this 49 | command will cause `patch` to look for the file using the entire path by 50 | stripping no prefix string (`-p0`): 51 | 52 | patch -p0 34 | 35 | 36 | By default `ping` sends 56 bytes in a packet plus 8 bytes of header, for a 37 | total of 64 bytes. This can be adjusted with the size (`-s`) option: 38 | 39 | ping -s 40 | 41 | 42 | Use `-c` to stop `ping`. 43 | 44 | 45 | -------------------------------------------------------------------------------- /eg/examples/prqlc.md: -------------------------------------------------------------------------------- 1 | # prqlc 2 | 3 | run the compiler interactively 4 | 5 | prqlc compile 6 | 7 | 8 | compile a .prql file standard output 9 | 10 | prqlc compile file.prql 11 | 12 | 13 | compile a .prql file to a .sql file 14 | 15 | prqlc compile source.prql target.sql 16 | 17 | 18 | compile a query 19 | 20 | echo "from employees | filter has_dog | select salary" | prqlc compile 21 | 22 | 23 | watch a directory and compile on file modification 24 | 25 | prqlc watch path/to/directory 26 | 27 | 28 | -------------------------------------------------------------------------------- /eg/examples/ps.md: -------------------------------------------------------------------------------- 1 | # ps 2 | 3 | show all processes 4 | 5 | ps -ef 6 | 7 | 8 | show process with id 37 9 | 10 | ps -p 37 11 | 12 | 13 | show all processes with verbose information, including memory and CPU usage 14 | 15 | ps -ev 16 | 17 | 18 | show processes belonging to user tyrion 19 | 20 | ps -u tyrion 21 | 22 | 23 | show all threads 24 | 25 | ps -efM 26 | 27 | 28 | 29 | # Basic Usage 30 | 31 | Print processes for all users (`-e`) with a more detailed format (`-f`): 32 | 33 | ps -ef 34 | 35 | 36 | `ps` can be more usable if you pipe it to `less`: 37 | 38 | ps -ef | less 39 | 40 | 41 | Print all processes belonging to a specific user (`-u`): 42 | 43 | ps -u 44 | 45 | 46 | 47 | # Showing Detailed Information 48 | 49 | Print verbose output for all (`-e`) processes with both memory and CPU usage 50 | (`-v`), as well as the extended information provided by `-f`: 51 | 52 | ps -evf 53 | 54 | 55 | 56 | # Finding by Process Name 57 | 58 | This command uses `ps` to show all processes (`-e`) that Google Chrome 59 | (`grep "Google Chrome"`) is running: 60 | 61 | ps -e | grep "Google Chrome" 62 | 63 | 64 | -------------------------------------------------------------------------------- /eg/examples/pwd.md: -------------------------------------------------------------------------------- 1 | # pwd 2 | 3 | print the current working directory 4 | 5 | pwd 6 | 7 | 8 | 9 | # Basic Usage 10 | 11 | Print the current working directory: 12 | 13 | pwd 14 | 15 | 16 | 17 | # Resolve Symbolic Links 18 | 19 | Show the physical location of the current working directory by using the `-P` 20 | flag: 21 | 22 | $ ls -aF 23 | total 8 24 | drwxr-xr-x 2 tyrion group 68 Feb 3 16:05 directory/ 25 | lrwxr-xr-x 1 tyrion group 9 Feb 3 16:05 link-to-directory@ -> directory 26 | $ cd /Users/tyrion/link-to-directory 27 | $ pwd 28 | /Users/tyrion/link-to-directory 29 | $ pwd -P 30 | /Users/tyrion/directory 31 | 32 | 33 | -------------------------------------------------------------------------------- /eg/examples/renice.md: -------------------------------------------------------------------------------- 1 | # renice 2 | 3 | change the priority of a running process with id 2230 4 | 5 | renice -n -15 -p 2230 6 | 7 | 8 | change priorities of all the process owned by user foo 9 | 10 | renice -n 5 -u foo 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Alter priority of a running process: 17 | 18 | renice -n -p 19 | 20 | 21 | Niceness values range from -20 (highest priority) to 19 (lowest priority). 22 | 23 | 24 | -------------------------------------------------------------------------------- /eg/examples/rm.md: -------------------------------------------------------------------------------- 1 | # rm 2 | 3 | delete a file 4 | 5 | rm file.txt 6 | 7 | 8 | delete a directory and its contents 9 | 10 | rm -r directory 11 | 12 | 13 | 14 | # Basic Usage 15 | 16 | Remove a file from the file system: 17 | 18 | rm 19 | 20 | 21 | Remove a directory with the recursive (`-r`) flag: 22 | 23 | rm -r 24 | 25 | 26 | -------------------------------------------------------------------------------- /eg/examples/rsync.md: -------------------------------------------------------------------------------- 1 | # rsync 2 | 3 | 4 | copy the folder source_dir and its content into destination_dir 5 | 6 | rsync -av source_dir destination_dir 7 | 8 | 9 | copy the contents of source_dir (trailing slash) into destination_dir 10 | 11 | rsync -av source_dir/ destination_dir 12 | 13 | 14 | copy source_dir into destination_dir converting symlinks to real files 15 | 16 | rsync -avL source_dir destination_dir 17 | 18 | 19 | copy multiple sources into destination_dir 20 | 21 | rsync -av source1 source2 source3 destination_dir 22 | 23 | 24 | copy multiple sources from a specific folder into destination_dir 25 | 26 | rsync -av source_dir/{source1,source2,source3} destination_dir 27 | 28 | 29 | move the contents of source_dir into destination_dir 30 | 31 | rsync -av --remove-source-files source_dir/ destination_dir 32 | 33 | 34 | update the contents of destination_dir to be the same as source_dir 35 | 36 | rsync -av --delete source_dir/ destination_dir 37 | 38 | 39 | copy the contents of source_dir to a remote machine 40 | 41 | rsync -av source_dir/ user@remote_machine:/path/to/destination_dir 42 | 43 | 44 | copy the contents of source_dir to a remote machine with non-default ssh port 45 | 46 | rsync -av -e "ssh -p 8888" source_dir/ user@remote:/path/to/destination_dir 47 | 48 | 49 | move the contents from remote machine to local machine 50 | 51 | rsync -av --remove-source-files user@remote:source_dir/ destination_dir 52 | 53 | 54 | see what actions would be performed without changing any files 55 | 56 | rsync -av --delete --dry-run source_dir/ destination_dir 57 | 58 | 59 | 60 | # Basic usage 61 | 62 | `rsync` can be used copy files and to make two directories identical. Most of 63 | the time you will want the `-a` flag, which stands for archive, and the `-v` 64 | flag to verbosely list what exactly it is doing. 65 | 66 | To copy contents of one directory to another run the command without the 67 | `--delete` flag. This can increase the number of files in the destination 68 | directory, but will never remove any files in the destination directory. A 69 | trailing slash when specifying the source directory indicates to copy the 70 | contents rather than the directory itself: 71 | 72 | rsync -av / 73 | 74 | 75 | To make the contents of the two directories identical, use the `--delete` flag. 76 | This will remove any files in the destination directory that are not present in 77 | the source directory: 78 | 79 | rsync -av / 80 | 81 | 82 | -------------------------------------------------------------------------------- /eg/examples/scp.md: -------------------------------------------------------------------------------- 1 | # scp 2 | 3 | copy a local file to another machine 4 | 5 | scp original.txt username@host:~/directory/copy.txt 6 | 7 | 8 | copy a remote file to the local directory 9 | 10 | scp username@host:~/original.txt ./copy.txt 11 | 12 | 13 | recursively copy a local directory to another machine 14 | 15 | scp -r directory username@host:~/directory_copy 16 | 17 | 18 | 19 | # Basic Usage 20 | 21 | Securely copy a file to another machine: 22 | 23 | scp @: 24 | 25 | 26 | 27 | # Copying to Another Machine 28 | 29 | Use `scp` to copy a file (`original.txt`) as user `tyrion` on machine 30 | `casterly_rock.com` (`tyrion@casterly_rock.com`). The file will be copied to 31 | `~/directory` as `copy.txt`: 32 | 33 | $ scp original.txt tyrion@casterly_rock.com:~/directory/copy.txt 34 | tyrion@casterly_rock.com's password: 35 | original.txt 36 | 37 | 38 | -------------------------------------------------------------------------------- /eg/examples/set.md: -------------------------------------------------------------------------------- 1 | # set 2 | 3 | display all variables set in the shell 4 | 5 | set 6 | 7 | enable command history 8 | 9 | set -o history 10 | 11 | disable command history 12 | 13 | set +o history 14 | 15 | 16 | 17 | # Basic Usage 18 | 19 | Enable a shell option: 20 | 21 | set -o