├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md ├── build.rb ├── design ├── Cover.png ├── Cover.svg ├── Merriweather │ ├── Merriweather-Black.ttf │ ├── Merriweather-Bold.ttf │ ├── Merriweather-BoldItalic.ttf │ ├── Merriweather-HeavyItalic.ttf │ ├── Merriweather-Italic.ttf │ ├── Merriweather-Light.ttf │ ├── Merriweather-LightItalic.ttf │ ├── Merriweather-Regular.ttf │ └── OFL.txt └── design.sketch ├── en-US ├── 01-errata.md ├── src │ ├── command-line-basics-part-one.md │ ├── command-line-basics-part-two.md │ ├── curl.md │ ├── finding-and-grepping.md │ ├── irb-and-bash.md │ ├── linking.md │ ├── path.md │ ├── redirection-and-pipes.md │ ├── scripting.md │ ├── sed-and-awk.md │ ├── ssh.md │ ├── summary.md │ ├── system-profiler-and-top.md │ ├── tips-and-tricks-part-one.md │ ├── tips-and-tricks-part-two.md │ └── xargs-and-cut.md ├── template.html └── title.txt └── output └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | output/* 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## creative commons 2 | 3 | # Attribution-NonCommercial-ShareAlike 4.0 International 4 | 5 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 6 | 7 | ### Using Creative Commons Public Licenses 8 | 9 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 10 | 11 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 12 | 13 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 14 | 15 | ## Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License 16 | 17 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 18 | 19 | ### Section 1 – Definitions. 20 | 21 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 22 | 23 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 24 | 25 | c. __BY-NC-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. 26 | 27 | d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 28 | 29 | e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 30 | 31 | f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 32 | 33 | g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike. 34 | 35 | h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 36 | 37 | i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 38 | 39 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 40 | 41 | i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. 42 | 43 | j. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 44 | 45 | k. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 46 | 47 | l. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. 48 | 49 | ### Section 2 – Scope. 50 | 51 | a. ___License grant.___ 52 | 53 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 54 | 55 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and 56 | 57 | B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. 58 | 59 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 60 | 61 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 62 | 63 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 64 | 65 | 5. __Downstream recipients.__ 66 | 67 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 68 | 69 | B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. 70 | 71 | C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 72 | 73 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 74 | 75 | b. ___Other rights.___ 76 | 77 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 78 | 79 | 2. Patent and trademark rights are not licensed under this Public License. 80 | 81 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. 82 | 83 | ### Section 3 – License Conditions. 84 | 85 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 86 | 87 | a. ___Attribution.___ 88 | 89 | 1. If You Share the Licensed Material (including in modified form), You must: 90 | 91 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 92 | 93 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 94 | 95 | ii. a copyright notice; 96 | 97 | iii. a notice that refers to this Public License; 98 | 99 | iv. a notice that refers to the disclaimer of warranties; 100 | 101 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 102 | 103 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 104 | 105 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 106 | 107 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 108 | 109 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 110 | 111 | b. ___ShareAlike.___ 112 | 113 | In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. 114 | 115 | 1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License. 116 | 117 | 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. 118 | 119 | 3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. 120 | 121 | ### Section 4 – Sui Generis Database Rights. 122 | 123 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 124 | 125 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only; 126 | 127 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and 128 | 129 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 130 | 131 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 132 | 133 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 134 | 135 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 136 | 137 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 138 | 139 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 140 | 141 | ### Section 6 – Term and Termination. 142 | 143 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 144 | 145 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 146 | 147 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 148 | 149 | 2. upon express reinstatement by the Licensor. 150 | 151 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 152 | 153 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 154 | 155 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 156 | 157 | ### Section 7 – Other Terms and Conditions. 158 | 159 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 160 | 161 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 162 | 163 | ### Section 8 – Interpretation. 164 | 165 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 166 | 167 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 168 | 169 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 170 | 171 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 172 | 173 | ``` 174 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 175 | 176 | Creative Commons may be contacted at creativecommons.org 177 | ``` 178 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | ruby build.rb 3 | 4 | open: 5 | open output/just-enough-command-line-en-us.epub 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Just Enough Unix Command Line 2 | A clear, well written, friendly book that guides novice and intermediate 3 | computer users alike become more comfortable with the powerful-yet-inscrutable 4 | Unix command line, 5 | 6 | This book collects Jessica Dillon's fantastic [blog 7 | series](https://quickleft.com/blog/command-line-tutorials-summary-what-s-next/) 8 | into an eBook and single page website. Here's our current [work in 9 | progress](https://waffle.io/zincmade/just-enough-unix-command-line). If you'd 10 | like, you can [pre-order the 11 | book](https://leanpub.com/just-enough-unix-command-line). 12 | -------------------------------------------------------------------------------- /build.rb: -------------------------------------------------------------------------------- 1 | chapter_name_order = ["command-line-basics-part-one", 2 | "command-line-basics-part-two", 3 | "finding-and-grepping", 4 | "redirection-and-pipes", 5 | "scripting", 6 | "system-profiler-and-top", 7 | "ssh", 8 | "irb-and-bash", 9 | "curl", 10 | "path", 11 | "linking", 12 | "sed-and-awk", 13 | "xargs-and-cut", 14 | "tips-and-tricks-part-one", 15 | "tips-and-tricks-part-two", 16 | "summary"] 17 | 18 | chapters = [] 19 | 20 | chapter_name_order.each do |chapter_name| 21 | chapters << "en-US/src/#{chapter_name}.md" 22 | end 23 | 24 | files = ["en-US/title.txt"] + ["en-US/01-errata.md"] + chapters 25 | 26 | `pandoc --toc -S --template=en-US/template.html -o output/just-enough-command-line-en-us.epub #{files.join(" ")}` 27 | -------------------------------------------------------------------------------- /design/Cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Cover.png -------------------------------------------------------------------------------- /design/Cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cover 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | $ 13 | 14 | The Unix Command Line 15 | 16 | $ echo "hello" 17 | hello 18 | $ pwd 19 | /users/just-enough/cli 20 | $ ls 21 | Learning Projects 22 | Awesome CatGifs 23 | $ echo "meow" > says 24 | $ 25 | 26 | Jessica Dillon 27 | $ cat says 28 | meow 29 | 30 | 31 | Just Enough Media 32 | Presents 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-Black.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-Bold.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-BoldItalic.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-HeavyItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-HeavyItalic.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-Italic.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-Light.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-LightItalic.ttf -------------------------------------------------------------------------------- /design/Merriweather/Merriweather-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/Merriweather/Merriweather-Regular.ttf -------------------------------------------------------------------------------- /design/Merriweather/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2013, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name 'Merriweather' 2 | 3 | Merriweather is a trademark of Sorkin Type Co. 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /design/design.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/design/design.sketch -------------------------------------------------------------------------------- /en-US/01-errata.md: -------------------------------------------------------------------------------- 1 | # READ THIS FIRST 2 | 3 | ## Submitting Feedback 4 | 5 | This is a *very early release* and we're eager to get your feedback. 6 | 7 | If you find an error or omission, or want to give us some advice, please send 8 | feedback to [http://support.justenough.media](support.justenough.media) 9 | 10 | Make sure you include the page number, as well as this books version number 11 | (Found on the title page). 12 | 13 | ## About This Book 14 | 15 | This book is based on a series of blog posts designed to help beginning 16 | programmers familiarize themselves with the Unix command line. They were written 17 | by author Jessica Dillon while she worked for Quick Left, and originally 18 | appeared on the Quick Left blog. 19 | 20 | This book may be read in order, or readers may look in the table of contents or 21 | index for topics and commands they would most like to focus on, and read the 22 | book in the order they choose. The table of contents lists the commands covered 23 | in each chapter. 24 | -------------------------------------------------------------------------------- /en-US/src/command-line-basics-part-one.md: -------------------------------------------------------------------------------- 1 | # Command Line for Beginners Part 1 2 | 3 | If there's one thing that separates code masters from the unknowing masses, it's their ability to use the command line effectively. When I began coding, I quickly realized that by utilizing the command line, many tasks became easier and faster. Your computer is smart; you just have to learn to speak its language. 4 | 5 | We're going to start off slow, getting you accustomed to navigating your computer using the Terminal application, but as we go, you'll learn more and more commands, along with some bonus efficiency tips and exciting command line theory! Remember, it's important to take it slow and build a solid foundation, but soon you'll be hacking away like a pro. 6 | 7 | Before we begin, I'm going to assume that you're using OSX. Command line in a Windows environment isn't too different, but for simplicity's sake, we'll stick with the Mac. I'm also going to assume you're using bash for a shell. Personally, I use zsh, but most computers are configured with bash to start out with. Either way, you'll be able to follow along with this guide. 8 | 9 | Start by firing up your Terminal. If you've never done that before, you can use Spotlight to search for it (press Command and the space bar, then type "Terminal" and press enter). Make sure you pin it to your dock for easy access in the future. If you're successful, you'll have a command prompt! 10 | 11 | A quick side note: if you're like most users, Terminal will place you in your home directory, which is denoted by the tilde ("~"). Typing "~" anywhere you would input a folder name will reference your home directory, just like a shortcut. There's a similar shortcut for your "root directory", which is represented by the forward slash ("/"). 12 | 13 | I'll touch on a few basic commands for navigating your file system, along with some other basic commands. For your first command, type: 14 | 15 | ``` 16 | pwd 17 | ``` 18 | 19 | This will tell you what current directory you're in. In fact, `pwd` is short for "print working directory", which is nerd speak for asking the computer to tell you where you are currently. After pressing enter, your computer will answer your question. Next, try typing: 20 | 21 | ``` 22 | ls 23 | ``` 24 | 25 | This command asks the computer to show you what's in the current directory; ls is short for "list". After you hit enter, you should see all the files and subdirectories inside your working directory. That's all well and good, but how can you move around the different folders on your computer? That's done by using the `cd` command, or in English, "change directory". Type: 26 | 27 | ``` 28 | cd / 29 | ``` 30 | 31 | `cd` works by switching to the directory immediately after the command itself. If you've been following along, you'll know that this command will switch you to your root directory. After you switch, try executing another "pwd", and confirm that you have actually changed directories. A common practice is to change to a new folder, use "ls" to see what's inside, then use `cd` to change to a subdirectory. A super sweet alternative is to type `cd`, then a space, then press the tab key. Your shell will then print a list of folders and files that you can change to. You can also tab through this list and press enter when you find the file or folder you're interested in. That will type it for you in your prompt (which can be a faster way to get to where you're going). 32 | 33 | Pressing tab at any time will auto-complete your input, meaning your computer will take its best guess at what which folder/file you're trying to get at (with the computer's selection limited to the working directory, of course). If you're in the middle of typing a command, like if you type `cd` without a space after, bash will instead attempt to find other commands that start with `cd` instead of finding available files and folders. 34 | 35 | Now, try typing this: 36 | 37 | ``` 38 | cd ~/Desktop 39 | ``` 40 | 41 | No matter where you are buried in your computer's files, this will bring you straight to your Desktop. This is an example of chaining folders on – in this example we are using `home/Desktop`, `home` of course being signified by the `~`. If you have any files or folders on your Desktop, you should be able to use the `cd ` + tab trick and see it all in your terminal. From there, you can choose available folders to `cd` into. 42 | 43 | Additionally, all the commands you enter into Terminal are saved. If you make a typo or type something the computer doesn't like (for instance, `cd`ing into a text file), then you can access the old command to fix it by pressing the up arrow. Pressing the up arrow again will take you further back into your old commands, and pressing down will show you newer commands. 44 | -------------------------------------------------------------------------------- /en-US/src/command-line-basics-part-two.md: -------------------------------------------------------------------------------- 1 | # Command Line for Beginners Part 2 2 | 3 | So you know how to make the computer change directories, and you're able to print the contents of the directory. What about making a directory? How do you do that? From your home directory ("~"), type: 4 | 5 | ``` 6 | mkdir practice 7 | ``` 8 | 9 | `mkdir`, short for make directory. Simple, right? Perform an `ls` command to verify that the practice file is inside your home directory, then `cd` into it. Once there, type: 10 | 11 | ``` 12 | touch helloworld.txt 13 | ``` 14 | 15 | We just made an empty file called helloworld.txt. Print the content of your practice directory, and make sure you see your file. Success! Now, brace yourself, because we're about to enter the world of the command line editor. This is an important tool, but it's very easy to mess up, so make sure you follow along closely. Type: 16 | 17 | ``` 18 | vi helloworld.txt 19 | ``` 20 | 21 | This opens the editor. The most important thing to know about vi is that it has two states: *insert mode* and *command mode*. Right now, you're in command mode. Press the `i` key on your keyboard to enter insert mode; you should see "– INSERT –" at the bottom of your screen. If you did it right, you should be able to type freely! Let's just be boring and type "Hello world!". Once you're done, hit escape to exit insert mode (If you take away one thing from this blog, it should be this: in vi, `i` is for insert, escape is for command). Then, in command mode, type `:wq` to tell vi that you want to write (save) your changes and quit. The colon is super duper important! Don't forget it. 22 | 23 | Phew, that was a close one. Let's make sure that our changes really were saved inside the file. 24 | 25 | ``` 26 | cat helloworld.txt 27 | ``` 28 | 29 | This new command is short for concatenate, and it just spits out the content of the file onto the command line. Do you see "Hello world!"? If so, fantastic job! If not, try using vi to edit the file again. 30 | 31 | Okay, so we can make a directory, we can make and edit a file, and we can see the contents of that file. Let's look at copying and moving files. These two commands are very similar, but it's important to take note of their differences. To copy a file, type: 32 | 33 | ``` 34 | cp helloworld.txt helloagain.txt 35 | ``` 36 | 37 | `ls`, and make sure you have both files inside your practice directory. `cat` your new helloagain.txt file and you'll see that it has the same content as the original. This command just copies the first file to a new file. You're not limited to supplying just the name for the file; you can also supply the path (For instance, type `cp helloworld.txt ~/helloagain.txt` to copy the file into your home directory). 38 | 39 | Let's move a file. The command for that is mv, and it looks something like this: 40 | 41 | ``` 42 | mv helloworld.txt ~ 43 | ``` 44 | 45 | What are we doing? We're moving the file immediately after the command into the directory immediately after the file name. Type: 46 | 47 | ``` 48 | ls ~ 49 | ``` 50 | 51 | …and you should see your "helloworld.txt" file in your home directory. That's not all that `mv` does though: you can give `mv` a file name instead of a directory, and it will change the file's name for you, e.g. 52 | 53 | ``` 54 | mv ~/helloworld.txt ~/hi.txt 55 | ``` 56 | 57 | `ls` your home directory again and you'll see your renamed file. Let's do a little bit of cleanup and take care of what we've made. Type 58 | 59 | ``` 60 | rm helloagain.txt 61 | ``` 62 | 63 | This command will delete the helloagain.txt file inside your current directory. 64 | 65 | `cd` back to your home directory. You should have both hi.txt and helloagain.txt here, so use `rm` to take care of those, if you want more practice. Speaking of which, type: 66 | 67 | ``` 68 | rmdir practice 69 | ``` 70 | 71 | This deletes the practice directory. An important note about the `rmdir` command: the folder MUST be empty. bash will bark at you if it's not. If you've been following along, then it should be empty anyway. 72 | 73 | If you want to delete an entire directory, including the contents, you can type `rm -rf `. Be careful with this, as it's a powerful tool! Never, EVER type `rm -rf /`. With those flags set, you'll delete your entire root directory, otherwise known as the most important directory on your computer. This is a common prank that people like to pull on command line newbies, so be on your guard. 74 | -------------------------------------------------------------------------------- /en-US/src/curl.md: -------------------------------------------------------------------------------- 1 | # Curl 2 | 3 | In this chapter we're going to cover one command in depth, since it's a pretty important one. We're going to learn about `curl`, and if time permits – curling! 4 | 5 | `curl` is "a command line tool for getting or sending files using URL syntax." It might help to read it as cURL, in order to help remind yourself what it does. First, to get some information, type: 6 | 7 | ``` 8 | man curl 9 | ``` 10 | 11 | As we've previously learned, most commands that come with your system have what's called a `man` page, short for manual; by typing in that command, you've opened the system's help page for the `curl` command. To move around, use your arrow keys. I don't expect you to read the whole thing (and if you already did, then wow, I'm sorry), but just know that this page exists and can be a handy resource to refer to. When you're done, press `Q` to quit. 12 | 13 | So to see it in action, type: 14 | 15 | ``` 16 | curl http://www.google.com 17 | ``` 18 | 19 | Oops! Now your shell is filled with the response that Google spits back at us. `curl` went out, made an http GET request against the website we supplied, then brought back everything it found and threw it into your command prompt. Let's refine that a little bit: 20 | 21 | ``` 22 | curl http://www.google.com | tidy -i 23 | ``` 24 | 25 | This passes `curl`'s output into a command we haven't seen before: `tidy`. `tidy` will nicely format any code we pass to it, and it's configurable to boot (check out the `man` page!). The only option we're setting is for indentation, since that'll make it look nice and pretty. After running the command, you should see some feedback from `tidy` containing the formatted code. That's a step forward, but I think we can do better. 26 | 27 | ``` 28 | curl http://www.google.com | pbcopy 29 | ``` 30 | 31 | Here, we're feeding the response retrieved by `curl` into another new command, `pbcopy`. This is a little bit nicer on the eyes and the brain, since it just puts the `curl` results straight to your clipboard, which allows you to paste straight into your favorite text editor. No code will be printed in your Terminal, only a confirmation graph of `curl`'s download. 32 | 33 | We can also use redirection with `curl` to copy it straight to a file, skipping the middleman. 34 | 35 | ``` 36 | curl http://www.google.com >> ~/google.txt 37 | ``` 38 | 39 | This will append the response into `google.txt`, located in your home directory. You could also use a single '>' to obliterate what's in that file, leaving only Google's source in the file. 40 | 41 | Curl also works with grep: let's single out the title of Google's homepage: 42 | 43 | ``` 44 | curl http://www.google.com | grep "<title>" 45 | ``` 46 | 47 | With this combination of commands, we're searching for any line that contains the phrase <title>; Google has mashed a lot of things onto the same line with the title, but you should see the part you're interested in appear in a different color, thanks to grep. 48 | 49 | Coders will often use `curl` and pipes to execute code off the internet. Here, we're going to grab someone's Ruby "Hello World!" script from GitHub with `curl` and pass it into the ruby command: 50 | 51 | ``` 52 | curl https://raw.github.com/leachim6/hello-world/master/r/ruby.rb | ruby 53 | ``` 54 | 55 | *WARNING WARNING WARNING*: Just because you *can* doesn't mean you *should*. *Always read the 3rd party code before executing locally*. 56 | 57 | After downloading the source (you'll get the chart again (charts are neat)), you should see the output of the script. That's a very simple application of using `curl` and ruby, but you get the picture. If you've installed RVM before, you used `curl` to retrieve a bash script, that you then passed into bash. Check out [the RVM install page]("https://rvm.io/rvm/install/"), and peep the first command. It should make a lot more sense to you, now that you know what `curl` is! 58 | 59 | That's all for today! Maybe we can get to curling in the next chapter. 60 | -------------------------------------------------------------------------------- /en-US/src/finding-and-grepping.md: -------------------------------------------------------------------------------- 1 | # Finding & Grepping 2 | 3 | We're going to cover a few slightly more advanced topics in this chapter, so strap yourself in and fire up your Terminal! 4 | 5 | Your Terminal has a couple built in commands intended for searching, be it for files or for the contents of a file. The first one is find, and it searches a directory for files. Let's say you want to list all the pathnames of all the ".jpg"'s in your home directory. You could type: 6 | 7 | ``` 8 | find ~ -name *.jpg 9 | ``` 10 | 11 | Let's break this down. First, you have the command name, then you have the directory to search (~ in this case). Following that is a flag that specifies a certain way for the command to behave (typically anything following a dash is a flag; there are a few exceptions). In this case, the flag tells find to search specifically for things with the name that follows, which in this case is *.jpg. The "*" is a wildcard, telling find to match any file as long as it ends with ".jpg". 12 | 13 | Running `find` without any flags will list all the files in your current directory, and all the files in the subdirectories. `find` is recursive; it keeps drilling down your directory structure until it can't find any more files to process. 14 | 15 | Another search command is `grep`, which is a little bit more useful. `grep` will search a given file for an expression, typically a string. Let's see an example: 16 | 17 | ``` 18 | grep "blog" temp.txt 19 | ``` 20 | 21 | This command will return every line in temp.txt that contains the word blog. What's interesting about grep is that it gives you some options for what you search on, allowing you to insert wildcards to increase the range of what gets matched. 22 | 23 | ``` 24 | grep "bl.g" temp.txt 25 | ``` 26 | 27 | The "." is a wildcard; it matches any character just once; for instance, output of this command might look something like: 28 | 29 | ``` 30 | blog 31 | blag 32 | bl&g 33 | ``` 34 | 35 | There are way more wildcards than just "." though. To whet your appetite, take a look at [this site]("http://www.panix.com/~elflord/unix/grep.html"). 36 | 37 | "grep" provides a few more options too. To search a file for a string that's case insensitive, add the "-i" flag. The following command could match a line containing cats, cATs, CATS, etc. 38 | 39 | ``` 40 | grep -i "cats" ~/cats.txt 41 | ``` 42 | 43 | "grep" is a super useful tool that serves a lot of different purposes. For example, if you know you entered a command recently that you want to use again, but you just don't want to press up a billion times to find it, you can use grep to search your command history! Here's how it's done: 44 | 45 | ``` 46 | history | grep "find" 47 | ``` 48 | 49 | Here we're searching our command line history for all the commands that have find in them. The "|" character is right above the enter key on most keyboards (press shift, then the backslash). The "|" has a special meaning at the command line. Essentially, it takes the output of the command on the left and feeds it to the command on the right. In this case, it's pretty plain to see that we're searching our history. Try typing history to see what exactly we're searching. 50 | 51 | You can find your commands this way, but how can you execute them? Bash has another built-in feature that allows you to execute old commands. Once you have the list of commands, you'll see they each have a number in front. By typing: 52 | 53 | ``` 54 | !5 55 | ``` 56 | 57 | …you'll execute the command following the number 5. It's pretty straightforward, and typically beats mashing your up key hoping to find what you're looking for. 58 | 59 | Let's look at one more usage of `grep`. If you wanted to take a look at the processes running on your system and the files they currently have open, you can do a little command line wizardry to accomplish just that. First, the command `ps aux` will list all the processes running, but only their process ids (under the PID column). To get that list, type: 60 | 61 | ``` 62 | ps aux 63 | ``` 64 | 65 | You can also use `grep` to search through your processes with `ps aux`. 66 | 67 | ``` 68 | ps aux | grep terminal 69 | ``` 70 | 71 | Now what do we do with that list? Well, we have another command, "lsof", that lists files your system currently has open; you can read a little more about it [here]("http://en.wikipedia.org/wiki/Lsof"). Using the process id from running "ps aux" as above, you can see what exactly that process has open by typing: 72 | 73 | ``` 74 | lsof | grep 1234 75 | ``` 76 | 77 | …replacing `1234` with the appropriate process number. 78 | -------------------------------------------------------------------------------- /en-US/src/irb-and-bash.md: -------------------------------------------------------------------------------- 1 | # IRB & Bash 2 | 3 | This chapter we're going to cover some more scripting. We're going to mix up Ruby and bash this week and see if we can do something cool along the way. If you don't know Ruby, don't worry: we won't do anything super complicated. You should have Ruby installed by default if you're using OSX. If not, check out [this site]("http://www.ruby-lang.org/en/downloads/") to download it. 4 | 5 | First, type: 6 | 7 | ``` 8 | irb 9 | ``` 10 | 11 | This brings up the "interactive Ruby shell", which gives you a back-and-forth session with Ruby inside your Terminal. This is a great way to immerse yourself with Ruby. Being able to type pure Ruby into the console is invaluable. Also, don't tell anyone, but sometimes I use it as a calculator. 12 | 13 | Okay, you should have a Ruby prompt. We're going to tell Ruby to do something 10 times: 14 | 15 | ``` 16 | 10.times do |i| 17 | `touch ~/#{i}.txt` 18 | end 19 | ``` 20 | 21 | Make sure you press enter after each line. If you haven't written Ruby before this may look complicated, but there's not too much going on here. The first line just says that we want to do something 10 times, which makes sense when you read it out loud. The |i| part might make less sense, but it enables us to use the number of times we've repeated so far inside the loop. 22 | 23 | Here's where we come to the most interesting part: Ruby lets us type in bash commands, where it executes them. This works not just in irb, but in any full length script you might want to write. Anything encased in backticks (`) will be processed as a bash command. Inside, you should recognize our old friend, the touch command. The file name might look like gibberish right now, so let's break that down too. 24 | 25 | We want to create a file inside our home directory (`~/`). Ruby will interpret the next part (`#{i}`) as something different each time the loop gets processed. The first time through, `#{i}` will be replaced by 0, then the next time it'll be replaced by 1, etc., all the way up through 9. 26 | 27 | Make sure you type in end, to let Ruby know the loop is being ended; that's all we wanted to do. After you press end and enter, you'll see some feedback from irb. Go check out your home directory – you should see 10 shiny new text files. 28 | 29 | Let's do a little cleanup on those files. 30 | 31 | ``` 32 | 10.times do |i| 33 | `rm ~/#{i}.txt` 34 | end 35 | ``` 36 | 37 | This pretty closely resembles the commands above; we want to make sure we delete exactly the same files that we created (otherwise you could just do something like `rm ~/*.txt`, which would delete all `.txt` files in your home directory). 38 | 39 | Playing around with the command line and irb a little more, you can do things like: 40 | 41 | ``` 42 | puts `cat ~/temp/test.html`.split.first 43 | ``` 44 | 45 | This grabs the contents of temp/test.html, splits it into chunks based on white space, then prints (`puts`) the first one out to the command line. 46 | -------------------------------------------------------------------------------- /en-US/src/linking.md: -------------------------------------------------------------------------------- 1 | # Linking 2 | 3 | This chapter we're going to talk about links, both soft and hard! 4 | 5 | So what's a soft link? For that matter, what's a hard link? Let's backtrack a little bit before we answer that. Your operating system has a filepath for every file on your system; you already know that most commands need a filepath to do their thing — think `ls`, `mv`, `cp`, etc. Filepaths are crucial to your computer's basic operation. To that end, your computer gives you a couple options for creating links to files; not necessarily changing the filepath itself, but enabling you to create an alias, or a shortcut to the file. 6 | 7 | Armed with that knowledge, let's delve into hard links. When you create a hard link, you're essentially giving a file another name; another filepath. After you create the hard link, you can use either name to refer to the exact same file. For instance, you could edit one file with `vi`, then `cat` the contents of the other file and see your changes. 8 | 9 | By comparison, a soft link (aka a "symbolic link", or "symlink") doesn't link to a file — it links to a file name. Woah. Inception. This sounds crazy, but maybe an example will help. Recently, I converted to Sublime Text from TextMate. One thing I loved about TextMate was its command line tool, which made it super easy to open a file in TextMate from a command prompt. I wanted that behavior with Sublime, so I followed [this guide]("http://www.sublimetext.com/docs/2/osx_command_line.html") from the Sublime Text documentation. The first command in the guide is: 10 | 11 | ``` 12 | ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl 13 | ``` 14 | 15 | The `ln` command, with the `-s` option, creates a soft link with the first argument (`"/Applications/Sublime Text 2…"`) as the source file and the second argument (`~/bin/subl`) as the target file (essentially just the name of your soft link). The source file in the example above is Sublime's built-in command line tool. You can execute it by typing out that long file path, but you don't want to do that every time. After creating the soft link, and assuming `~/bin` is in my `PATH` (callback!), I'll be able to execute the subl command from anywhere! For example, when I type: 16 | 17 | ``` 18 | subl ~/puppies.txt 19 | ``` 20 | 21 | …my shell locates the subl command (inside `~/bin`), sees it's a soft link, then follows it to the command contained inside the Sublime Text application and executes the command, which opens the file `~/puppies.txt` inside Sublime. 22 | 23 | In case you don't use Sublime Text, let's do another example to get some more practice with links. Follow along! Type: 24 | 25 | ``` 26 | touch ~/Desktop/kittens.txt; echo "just kidding, puppies for life" > ~/Desktop/kittens.txt 27 | ``` 28 | 29 | Here's something we haven't seen before: we can execute multiple commands on the same line by separating them with a semicolon. After that line, you should see a new file on your desktop. Now, let's create a pair of links (hard links are also created using `ln`, without the `-s` option). 30 | 31 | ``` 32 | ln ~/Desktop/kittens.txt ~/Desktop/hard 33 | ln -s ~/Desktop/kittens.txt ~/Desktop/soft 34 | ``` 35 | 36 | Okay, so now we have three files on our desktop: the original `kittens.txt`, a hard link, and a soft link to that file. Let's make sure we have everything correct: 37 | 38 | ``` 39 | ls -l ~/Desktop 40 | ``` 41 | 42 | When you give the `ls` command the `-l` option, it takes all of the soft links in the directory and shows you where they point to, i.e. the source file used when the link was created. You should see soft pointing towards `kittens.txt`, and no text next to the hard link. If you don't, try creating the links again. Otherwise, let's move on and edit the file using a link: 43 | 44 | ``` 45 | echo "knuckle tat: dawg life" > hard 46 | ``` 47 | 48 | Now, check the original file. You should see the contents have been replaced with your new tattoo idea! 49 | 50 | Now, here's an important note about OSX and hard links: if you use a text editor like TextEdit, TextMate, or Sublime to edit the hard link, it'll break the link! The two files will then have different content, which defeats the entire purpose of using a link. For more information on why that occurs, [check out this Super User post]("http://superuser.com/questions/302051/how-do-you-create-a-working-hard-link-in-osx"). You can edit the hard link using `vi` or `echo` (like above) freely, plus you'll earn bonus command line points. 51 | -------------------------------------------------------------------------------- /en-US/src/path.md: -------------------------------------------------------------------------------- 1 | # Path 2 | 3 | This chapter we're gonna talk a little bit about your path variable and some related commands. 4 | 5 | *Just for a quick note – these directory structures are reflective of OSX. If you are using a different operating system, these paths might not be correct.* 6 | 7 | First, type 8 | 9 | ``` 10 | echo $PATH 11 | ``` 12 | 13 | You know what `echo` does, so what's `$PATH`? That's an environment variable! These are set for you when your shell session starts up. To get a full list of all the defined environment variables, type: 14 | 15 | ``` 16 | printenv 17 | ``` 18 | *\* (You can also use the command "env" to print the same list)* 19 | 20 | You should see a list of all the variables, with their names on the left and their values on the right. And hey, there's the `PATH` variable! Let's talk a little bit about what `PATH` does for you. `PATH` is a colon-separated list of directories that contain executable programs. This is where some (but not all) of your commands are actually located on the system. When you execute a command, your computer looks through `PATH` until it finds that command, then it runs the code (usually). You can add or remove directories to the list as you see fit. Here's an example of adding a directory: 21 | 22 | ``` 23 | PATH=$PATH:/tmp/cmd 24 | ``` 25 | 26 | This adds the /tmp/cmd directory onto the end of your `PATH` variable; the colon is key, since that's how directories are split up inside the `PATH` variable. Try the `echo` command above again, and you should see your change. That's how you add a directory, but what about removing one? I'll get back to that. For now, quit your Terminal session and restart it. Try `echo` on your path again. You should see that /tmp/cmd is no longer on the end of your path. Wait, what? 27 | 28 | Setting an environment variable like above is only temporary. It won't last between sessions (or even between multiple tabs within the same application). So what are you supposed to do? There are a couple options. First, you can add a path export function to your shell's profile, located in your home directory. If you're using zsh, you would place the following line of code in the file `~/.zshrc`. If you're running bash, then they can go in `~/.bash_profile` (If you're still using bash, check out [this post](http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html) for more information on your profile files, for there's two of them you see). 29 | 30 | ``` 31 | export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/ 32 | local/bin:/usr/X11/bin:/usr/local/git/bin:/tmp/cmd 33 | ``` 34 | 35 | Put that line in your profile, then in every shell that you start, that will be your new `PATH` variable. If that seems a little messy, then you might prefer the second way, which has to do with how your computer even populated that `PATH` variable with directories in the first place. Type: 36 | 37 | ``` 38 | cat /etc/paths 39 | ``` 40 | 41 | What's printed is a list of the default directories your computer adds to `PATH`. But wait, there's more! Type: 42 | 43 | ``` 44 | ls /etc/paths.d 45 | ``` 46 | 47 | Here's a list of files that contain even more entries for your `PATH`! If you have one in there, then you should try `cat on that file; you'll see that it has even more directories for `PATH`. Try comparing `PATH`'s contents with all of the entries you've found. Here's the trick – when you want to add a directory onto your `PATH` variable, you can add it to either /etc/paths or you can wrap it in a file inside /etc/paths.d – your shell will correctly build the `PATH` variable for you when you start your session. 48 | 49 | Okay, one more thing: check out this command: 50 | 51 | ``` 52 | which printenv 53 | ``` 54 | 55 | The 'which' command tells you where the command on the right lives. For `printenv`, you should see `/usr/bin/printenv`. This is useful for debugging – if you try to execute a command and your shell barks at you, telling you it can't find it, then try using 'which' to locate the command in question. Usually this happens when I think a command is in my path, but it's really not – that's when I edit `PATH` using one of the two methods above. 56 | -------------------------------------------------------------------------------- /en-US/src/redirection-and-pipes.md: -------------------------------------------------------------------------------- 1 | # Redirection & Pipes 2 | 3 | This chapter we're going to look at a few basic operators that your shell supports. The operators we're examining allow you to send a command's output to different places, like files or even other commands. Formally, this is called "redirection", and it's one of Bash's coolest features. 4 | 5 | For a quick example, let's try putting our current directory's filepath into a file, just for safekeeping: 6 | 7 | ``` 8 | pwd > directory_path 9 | ``` 10 | 11 | What's happening here? First, we have the command whose output we want, pwd. Then, we have our operator, >. It grabs the output from the command on the left and feeds it to the file on the right, which in this case is directory_path. 12 | 13 | Did it work? Try printing the contents of the directory_path file by typing 14 | 15 | ``` 16 | cat directory_path 17 | ``` 18 | 19 | Success! A couple notes: the > operator will create the file if it doesn't exist, and it will overwrite it if it does exist. What if you don't want that? Then you have the >> operator. Let's see it in action: 20 | 21 | ``` 22 | echo 'Hello, cruel world!' >> directory_path 23 | ``` 24 | 25 | The "echo" command simply outputs the text that you feed it. Cat that file again, as above, to see what exactly happened. You should see that the output of the list command was appended to the file we created above, giving you a file that contains your current directory's location and the phrase we entered using "echo". It looks like this: 26 | 27 | ``` 28 | /Users/jessica 29 | Hello, cruel world! 30 | ``` 31 | 32 | The command >> is a little nicer to your files; if the file specified doesn't exist, it gets created and modified, but if it does exist, then the output from your command gets added to the end of that file's contents. 33 | 34 | Okay, let's delve a little deeper. We got a brief taste of the pipe operator in last week's edition, but now we're going to cover it a little bit more in depth. The best way to learn how the pipe works is to look at some examples. Let's look at one now: 35 | 36 | ``` 37 | du | sort -nr | head 38 | ``` 39 | 40 | Here, we have three commands separated by "|", which is the pipe operator. This is located above the enter key on most keyboards. The first command is "du", which is short for disk usage. It tells you how much memory each subdirectory or file contained inside your current directory is using, listing the size of each, along with the name. We pass the output of that command to the command on the right using the pipe. 41 | 42 | The next command, `sort`, normally sorts the input in ascending order, but with the `-r` flag we pass in, will reverse the order to descending (the -n flag tells sort to do so numerically). At this point, our output would be a list of all the files in our current directory sorted by how much memory they're using, from highest to lowest. However, we have one more pipe and one more command. 43 | 44 | The final command is `head`, which is similar to the `cat` command we use to print files to the Terminal. `head` is a little different; it's designed to print just the first few lines of a file. By default, it will only print 10, so unless you tell it otherwise, that's all you'll get. So in the chain of commands that we have above, `head` was passed the sorted list of files, and it takes the top 10 and chops off the rest. Our end result will be a list of the 10 most memory-consuming files inside our current directory. From my root directory, it looks something like this: 45 | 46 | ``` 47 | 94543224 . 48 | 46532448 ./Music 49 | 46532432 ./Music/iTunes 50 | 44352472 ./Music/iTunes/iTunes Music 51 | 28346504 ./Library 52 | 24024488 ./Library/Application Support 53 | 21787536 ./Library/Application Support/Steam 54 | 21719184 ./Library/Application Support/Steam/SteamApps 55 | 10770008 ./Downloads 56 | 3540216 ./Music/iTunes/iTunes Music/Podcasts 57 | ``` 58 | 59 | Okay, that's a lot to take in, but let's try it all together at the same time. Try thinking like your shell, and consider the various inputs and outputs being passed from command to command in the line of code below: 60 | 61 | ``` 62 | ls -la | head >> new_file 63 | ``` 64 | 65 | First, we're listing the contents of our directory, then we're grabbing the top 10 listed and adding them to the file "new_file". 66 | -------------------------------------------------------------------------------- /en-US/src/scripting.md: -------------------------------------------------------------------------------- 1 | # Scripting 2 | 3 | Okay, Command-os (I'm so sorry, the joke had to be made), let's get back to it. This chapter, we're going to look at scripting in a very general sense. Scripting is a complex topic that would be hard to cover in just one post, but it's a handy thing to know the basics. Put simply, scripting is like storing a bunch of commands into a file and executing them one-by-one. 4 | 5 | First, from your home directory, type: 6 | 7 | ``` 8 | touch first.sh 9 | ``` 10 | 11 | As you know, we just created a file; the `.sh` extension on the end signifies that it's a bash script. It's not strictly required, but it's a useful convention to adhere to. Next, let's open it up for editing. You can do this by using the "vi" command if you have the chops, or you can open up the file in your favorite text editor. 12 | 13 | First things first, we're going to start our script with what's called a `shebang`. 14 | 15 | ``` 16 | #!/bin/bash 17 | ``` 18 | 19 | A what now? The "#" symbol is commonly called a hash, and the "!" is referred to as a bang, and when you jam those symbols together like in that line of code, it's called a "shebang". Yup. But what does this line actually do? It signifies that what follows is a Bash script, and it allows you to execute the whole script at the command line, just like a command! Keep that in your brain, we're going to come back to it soon. 20 | 21 | Keeping up so far? Next, in your script, type: 22 | 23 | ``` 24 | echo 'hey world hey' 25 | ``` 26 | 27 | Here's our friend again, the `echo` command. It just prints out what it's told, but in this case it makes our script meaningful; the `shebang` by itself doesn't do anything. So now that our script does something, we're ready to execute it. At the command line (not inside your script), type: 28 | 29 | ``` 30 | bash first.sh 31 | ``` 32 | 33 | What? An error? If you've been following along, you should get an error that says something along the lines of "permission denied". You created a file with read/write privileges, but what it doesn't have is permission to execute. How do you do that? Just ask the computer! Still at the command line, type: 34 | 35 | ``` 36 | chmod u+x first.sh 37 | ``` 38 | 39 | The `chmod` command changes the permissions on a given file; the `u+x` indicates that we want to give the *u*ser e*x*ecution privileges. You can read more about `chmod` and privileges [here]("http://en.wikipedia.org/wiki/Chmod"). 40 | 41 | Okay, now that's taken care of, let's try executing it again. This time, type: 42 | 43 | ``` 44 | ./first.sh 45 | ``` 46 | 47 | I promised I'd come back around, so here's what the `shebang` buys us. The syntax here indicates that we want to execute a command in the current directory, signified by the "." I won't get too far into it, but that's a security feature of Bash that protects you from executing code that you don't want to. This allows you to execute the script without specifying which command should handle it (i.e. Ruby, Python, Bash, etc.) 48 | 49 | Did you see the text from your script? If you did, that's great! If you get an error that says something about your syntax, make sure your `shebang` and `echo` statements are correct (Your script should only contain two lines. It's a shorty!). If you still get a permission error, then try executing the `chmod` command again, as above. 50 | 51 | That's all for this week! Join me again in two weeks' time for more command line fun! 52 | -------------------------------------------------------------------------------- /en-US/src/sed-and-awk.md: -------------------------------------------------------------------------------- 1 | # Sed & Awk 2 | 3 | It's time to command and conquer! This chapter we're going to take a look at two very important commands for your toolbox – `sed` and `awk`. These two commands are pretty powerful, but as a result, their learning curve can be pretty steep. I'll provide you an outline to get you up to speed on sed and awk, but there's more to these commands than I have room here to cover. Fortunately, there's a ton of information on the internet about these commands, and I encourage you to read up on them once we're done. 4 | 5 | The first command we'll discuss is `sed`, which stands for "stream editor" – it gives you a nifty way to perform operations on files you're passing around through pipes. If that sounds confusing, hang on for one second – an example should help clear it up. One of the most common things you'll use sed for is text substitution, i.e. replacing certain text with something else. The syntax for doing that looks like this: 6 | 7 | ``` 8 | echo "it's a trap" | sed s/ra/ar/ 9 | ``` 10 | 11 | First we perform an echo on a string, so we have some data to actually work with. That text gets piped to the `sed` command (pipes are super important for sed and awk; if you need a refresher, check out [my post on redirection and pipes]("http://quickleft.com/blog/command-line-tutorials-redirection-pipes")). Let's break apart that `sed` command. 12 | 13 | First, we have "s", for substitute. Next is "/", our delimiter for separating the different components of the command (note that you're not limited to just "/"; if what you're searching for contains slashes, it might be more convenient to use an underscore or a colon). After the first delimiter, we have a [regular expression]("http://en.wikipedia.org/wiki/Regular_expression") for the text we'd like to replace. Finally, we have another delimiter, followed by the replacement string (i.e. what you'd like the old text to say after running the command), with a trailing delimiter after that. Phew, that's lengthy! 14 | 15 | Try out that command, and you should see "it's a tarp" printed out. Substitution on a basic string isn't too useful, so let's try it out on a file instead. Type the following two commands: 16 | 17 | ``` 18 | echo "how now brown cow" > ~/temp.txt 19 | sed s/ow/aagh/ ~/temp.txt 20 | ``` 21 | 22 | 23 | First we create the file, then we perform the substition. You'll see the result fed to the screen, but you should see only the first "ow" got replaced. Why? Only the first match of the regex got replaced. To hit every match, you need to add a flag to the end of the `sed` command, like so: 24 | 25 | ``` 26 | sed s/ow/aagh/g ~/temp.txt 27 | ``` 28 | 29 | That's more like it, but if you check out the file, you'll see that that change wasn't actually saved. You could pipe the output to the same file, but `sed` provides another flag that will do it for you. Try this: 30 | 31 | ``` 32 | sed -ie 's/ow/aagh/g' ~/temp.txt 33 | ``` 34 | 35 | There we go! What else can `sed` do? Deletions are pretty simple. Here's an example that duplicates the functionality of the `head` command. 36 | 37 | ``` 38 | sed '11,$ d' ~/temp.txt 39 | ``` 40 | 41 | Of course, this doesn't actually delete the lines; you're not writing to the file, so it just feeds those lines out to your shell. The "11,$" portion of the command tells `sed` to delete everything from the eleventh line to the end of the file. You're not limited to numbers for that range; instead you can use regular expressions to mark the beginning and end of what you'd like to delete. Or, if you'd like, you can use one expression, causing `sed` to delete everything that matches it. You can use sed to delete comments from a Ruby script like so: 42 | 43 | ``` 44 | sed '/#.*/ d' 45 | ``` 46 | 47 | That regular expression matches every comment in a file – any text that follows a "#". 48 | 49 | There's a bunch more to `sed`, but let's move onto `awk` now. `awk` is a utility that's useful for processing text files. The utility considers each file as a set of records, which by default are the lines in the file. `awk` enables you to create a condition and action pair, and for each record that matches the condition, the action will fire. That's really wordy, so hopefully an example will help. First, let's create a file to use for the demo, then let's run a basic `awk` command on that file. 50 | 51 | ``` 52 | ls -la > temp.txt 53 | awk '/root/ {print $1, $9;}' temp.txt 54 | ``` 55 | 56 | Again, let's break it down. Most `awk` commands follow this pattern – you have a condition, followed by an action in curly braces. Our condition in this case is the regular expression /root/, which will match any line that contains "root". The action that follows is written in the AWK language, which could take up an entire series of blog posts, but all you need to know here is that it's printing the first and ninth fields ("columns") of the record (which in our case are the permissions of the file and the filename). You can play around with the expression and see how many matches you can get, and you can also add columns to the action statement. You can also omit the action entirely, like so: 57 | 58 | ``` 59 | awk '/root/' ~/temp.txt 60 | ``` 61 | 62 | The default action for `awk` is to print the entire record, so the previous command will print every line that contains "root". Of course, you can use other conditions; for example, checking whether or not a certain field is above or below a given threshold (i.e. $5 > 2), or checking whether a record has a certain column. Your actions can be varied too, based on the AWK language. You can use `awk` to substitute just like `sed`, by using the AWK `sub` or `gsub commands. Here, I'll change every occurence of "jessica" to "nicelady", but only if the filename starts with a period: 63 | 64 | ``` 65 | awk '$9 ~/^\./ {gsub(/jessica/, "nicelady"); print;}' ~/temp.txt 66 | ``` 67 | 68 | Wow, that's a beefy command. First, the condition checks whether or not `$9`, the ninth field, matches the regular expression `/^./`; in plain people language, does the filename start with a period? Then the action calls the AWK function gsub, for global substitution. Everywhere in the file that matches /jessica/, we substitute the string "nicelady". Then, once that's done, we print the line. If I want to make that change to the file permanent, then the easiest way is to pipe the output straight to the file, adding " | ~/temp.txt" onto the end of the `awk` command. 69 | 70 | So for a quick overview, `sed` and `awk` are flexible stream editing utilities. They operate a little differently, but each relies on the power of regular expressions and text matching to do its job. There is SO MUCH MORE to these commands that I hope you take the time to look them up; hopefully this introduction opened your eyes to the world of command line stream editing. 71 | 72 | That's all for this week! Post in the comments if you have anything to add, or any questions to ask! 73 | -------------------------------------------------------------------------------- /en-US/src/ssh.md: -------------------------------------------------------------------------------- 1 | # SSH 2 | 3 | This chapter, we're going to talk about two commands related to accessing other servers or computers. If you've ever plan on deploying your software to a server, then remote computing is an important skill to have. Luckily, it's not too hard. 4 | 5 | First, you're going to want to master the `ssh` command. `ssh` stands for Secure SHell, and it's included on most Unix systems. This kind of command has been around as long as Unix, but this one is important because it encrypts your session, meaning nobody can steal your login credentials, or see what kind of things you're doing on the server. Unfortunately, I can only show you what the commands look like, but if you know a remote host you can connect to (and you have credentials, those are important too), then feel free to follow along. 6 | 7 | ``` 8 | ssh username@hostname 9 | ``` 10 | 11 | It's that easy! Technically the only argument `ssh` needs is the host name. If that's all you supply, then `ssh` assumes your user name on the remote server is the same as your local name. The next thing you'll see, if it's your first time on the server as that user, is a confirmation of the host name. 12 | 13 | ``` 14 | The authenticity of host 'hostname (123.4.567.890)' can't be established. 15 | RSA key fingerprint is 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff. 16 | Are you sure you want to continue connecting (yes/no)? 17 | ``` 18 | 19 | `ssh` wants to protect you, so it makes sure that that's the computer you're really trying to connect to. Make sure you carefully read this description, since someone could be trying to pull one over on you. If you know you have the right one, then type `yes`. 20 | 21 | After that, you'll be prompted for your password. Assuming you have one, go ahead and type it in. Further assuming you're successful, then you'll have a command prompt on the remote host. Celebrate! 22 | 23 | Now that you're here, you'll be able to run most commands that you normally could at your own command prompt. Obviously, the file directory will be different, since you're on a different machine. Depending on the system's configuration, you might have your own home directory, separate from all the other users who could access that machine, but more likely is that you share the same home as everyone else. As a result, it's important to be thoughtful whenever your move/remove/create files on the system; you don't want to accidentally delete someone else's stuff (or maybe you do, but just know that I'm always judging you if that's the case). 24 | 25 | Okay, that's neat. When you're done, type: 26 | 27 | ``` 28 | exit 29 | ``` 30 | 31 | `exit` finishes your session on the remote server and returns you to wherever you were when you originally typed the `ssh` command. Let's go a little bit deeper now: assume you have a file on your system that you want to put on a remote server. How could you do that? 32 | 33 | ``` 34 | scp test.txt username@hostname: 35 | ``` 36 | 37 | The `scp` command stands for "*S*ecure *C*o*P*y"; it always takes two arguments: the file you want to copy, and the destination for that file. Here you see the same "username@hostname" as above (swap that with your real name and server name, just like last time). That signifies the machine that you want to port your file over to. After you enter the command, you'll be prompted for your password, just like the "ssh" command. 38 | 39 | Take note of the colon at the end, because it's pretty important. If you leave it just like that, then your file will have the same name it does locally, and it'll be placed in your home directory on the remote machine. 40 | 41 | ``` 42 | scp ~/test.txt username@hostname:~/temp/party_time.txt 43 | ``` 44 | 45 | Here we're taking a file from your local home directory and putting it up on the remote server under the subdirectory `temp`. At the same time, we're changing the name to `party_time.txt`. 46 | 47 | Let's take it in reverse. What if you want to get a file from the server and put it on your local machine? 48 | 49 | ``` 50 | scp username@hostname:~/.ssh/authorized_keys ~/keys.txt 51 | ``` 52 | 53 | This command rips the list of authorized keys from the server and puts it in a text file in your home directory. All we had to do was flip the order of the from/to files. Basically, you're taking the file pointed at by the first argument and putting it in the second argument. 54 | 55 | If you have two computers, try taking `scp` and `ssh` for a test drive! All you need to do is figure out your IP address for your target computer, which you can find in your connection settings. 56 | 57 | That's all for this week! 58 | -------------------------------------------------------------------------------- /en-US/src/summary.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | ## Command Line Basics Pt. 1 and Pt. 2 4 | 5 | The first and second chapters described the very basics of command line usage. We covered how to launch your Terminal for the very first time, how to navigate through your directories from the command line, how to destroy/create both files and folders, how to move and copy files, and how to print the contents of a file out onto your screen. 6 | 7 | Commands covered: `cd`, `ls`, `pwd`, `mkdir`, `touch`, `vi`, `rm`, `rmdir`, `mv`, `cp`, `cat 8 | 9 | ## Finding and Grepping 10 | 11 | In the next chapter, we discussed commands intended for searching. The 'find' command searches for filenames, and the `grep` command searches through file contents. We also covered using `grep` in combination with the `history` and `ps aux` commands, in order to find a particular command or process. 12 | 13 | Commands covered: `find`, `grep`, `history`, `ps aux`, `lsof` 14 | 15 | ## Redirection and Pipes 16 | 17 | Next, we covered a complex topic: redirection. For a quick refresher, redirection is the act of sending one command's output to a file or another command. We discussed using `<` and `<<`, the redirection output operators to output text to file in either overwrite or append mode. Next, we chained commands together using `|`, the pipe. 18 | 19 | Commands/operators covered: `<`, `<<`, `|`, `echo`, `du`, `sort`, `head` 20 | 21 | ## Scripting 22 | 23 | In March, we dove into scripting. We created our first script that simply printed out a phrase. First, we included a "shebang" at the top of the file in order to mark it as a script, but when we tried to execute our script, we got an error. Finally, we had to change the permissions on the file to get it to run. 24 | 25 | Commands covered: `bash`, `chmod` 26 | 27 | ## Profiler and Top 28 | 29 | Next, we investigated the systemprofiler and top commands. We used `grep` to search the output of `systemprofiler` to find our computers' serial numbers. After that, we figured out how to `kill` the process that`s consuming the most memory, using `top` to identify that particular process. 30 | 31 | Commands covered: `man`, `systemprofiler`, `top`, `kill_` 32 | 33 | ## SSH 34 | 35 | In this chapter, we covered the basics of using the `ssh` and `scp` commands to get access to another server/computer. We discussed logging in (and out) with `ssh`, then running commands remotely. We then used the `scp` command to put move a local file onto a server, then we reversed that process to move a remote file onto our local machine. 36 | 37 | Commands covered: `ssh`, `scp` 38 | 39 | ## IRB and Bash 40 | 41 | This chapter showed how to mix basic bash commands with some Ruby goodness. We fired up `irb`, an interactive Ruby REPL (read, evaluate, print, and loop) to repeatedly execute bash commands. We also used `irb` to use more advanced Ruby commands to achieve something that'd be harder in bash. 42 | 43 | Commands covered: `irb` 44 | 45 | ## Curl 46 | 47 | Next, we went in-depth on the `curl` command. We used `curl` to grab the source code from google.com, then we cleaned it up with tidy. We also used pbcopy to grab the code and copy it onto our clipboard, so we could paste it into our favorite text editor. Finally, we looked at a practical applications of `curl`, like fetching code from the internet and executing it (WHICH IS *DANGEROUS*, but you knew that already). 48 | 49 | Commands covered: `curl`, `tidy`, `pbcopy` 50 | 51 | ## Path 52 | 53 | In this chapter, we learned about environment variables and how to list them using `printenv`. We went pretty deep on the PATH variable, an environment variable that determines where your shell looks for commands. We covered how to add and remove directories from the path. More accurately how to change the contents of an environment variable, both temporarily and permanently by adding it to your shell's profile. 54 | 55 | Commands covered: `printenv`, `export`, `which` 56 | 57 | ## Linking 58 | 59 | In July, we learned a little bit more about how the file system operates with links, which are essentially aliases/shortcuts for files on your computer. We covered the difference between hard links and soft links, then we learned how to create each using the `ln` command. This is a pretty complex topic that's unlike anything we've covered, so I definitely recommend checking out that blog again if you have any questions. 60 | 61 | Commands covered: `ln` (with various flags) 62 | 63 | ## Sed & Awk 64 | 65 | Stream editors are useful command-line tools for performing operations on data being passed around in "streams" – i.e., data/files being piped between commands. In this chapter, we covered the very basics of the `sed` and `awk` commands, which are probably the most complicated things that we've covered in this series. While there's still a lot to be learned in this area, these chapters are a useful outline to get started. 66 | 67 | Commands covered: `sed`, `awk` 68 | 69 | ## Xargs & Cut 70 | 71 | Next, we experimented with a different form of redirection by using the `xargs` command. `xargs` takes a whitespace separated list of arguments and performs a command on each. We looked at a lengthy application of `xargs`, chaining together commands to move all of the text files in the current directory into a hidden folder. Then, we looked at the `cut` command, which is used for slicing up a file into portions that you specify. We looked at a couple different flags in order to specify which part of the file you want, then we used cut in an example to familiarize ourself with it. 72 | 73 | Commands covered: `xargs` (with various flags), `cut` (with various flags) 74 | 75 | ## Tips & Tricks 76 | 77 | These chapters covered some smaller odds and ends that didn't merit their own chapter, along with some tips for efficient use of the command line. I encouraged you guys to add some tips of your own, and you guys did not disappoint! I definitely recommend reading the comments on these chapters if you haven't already, because you might learn something new. 78 | 79 | Commands/operators covered: `&&`, `!!`, `pushd`, `popd`, `jobs`, `fg` 80 | -------------------------------------------------------------------------------- /en-US/src/system-profiler-and-top.md: -------------------------------------------------------------------------------- 1 | # System Profiler & Top 2 | 3 | This chapter we're going to cover a couple commands that you should find useful at some point. The first is the `system_profiler` command. Run without any arguments, the command simply spits out a (huge) list of your computer's current configuration. The information includes practically everything about your computer; it's like the "About This Mac" utility on steroids. Type: 4 | 5 | ``` 6 | man system_profiler 7 | ``` 8 | 9 | The `man` command opens up the manual in VIM for the command that follows. Generally, it'll list the different arguments available for the command. Sometimes, it'll give you an example usage. To exit the manual, press `q` (for quit)! 10 | 11 | For a quick demonstration, type: 12 | 13 | ``` 14 | system_profiler | grep "Serial Number (system)" 15 | ``` 16 | 17 | Here's our new `system_profiler` command, followed by our good friend `grep`. We're going to search the output of the system_profiler command for the string "Serial Number (system)", which will end up outputting something like this… 18 | 19 | ``` 20 | Serial Number (system): ########## 21 | ``` 22 | 23 | This is the serial number of your computer! Using `system_profiler`, we were able to figure that out without opening anything or turning the computer over. The command has many more uses than that, so it's a good one to keep in your pocket. 24 | 25 | Next is the command `top`. This command will show you all of the processes that are running on your system, sorted by their usage of the CPU, with the highest on top. 26 | 27 | *Edit (3/30/2012)* – [Mike Pack]("http://www.mikepackdev.com") gave this awesome correction and tip – 28 | "Not every system orders the results of `top` the same. For instance, my system's (OS X 10.7.3) default ordering is by PID. You can find the default ordering in `man top` and scrolling down to to the -o flag. When I want to order by CPU usage, I run `top -o cpu`." 29 | 30 | If your computer is running super slow, you can run the top command to see if any single process is consuming more than it should. Type: 31 | 32 | ``` 33 | top 34 | ``` 35 | 36 | This will fill up your Terminal with the list of processes and take away control from you. While it's open, take a note of a couple things. The columns we're interested in are *COMMAND*, *%CPU*, and *PID*. *COMMAND* is obviously the name of the command that's running, and *%CPU* is the percentage of the CPU that command is using. *PID* is the process id, an identifier that's unique for each process in the table. 37 | 38 | Okay, that's all we're interested in. In order to take control back from the process, press `Control + C` (this is a pretty standard procedure for taking control back from processes, so you'd do well to remember this key sequence). Now that you know which process/command is hogging up all your memory, what are you gonna do about it? Here's where the `kill` command comes into play. `kill` looks like this: 39 | 40 | ``` 41 | kill [PID] 42 | ``` 43 | 44 | …Where [PID] is a number that represents a process, just like the ones we saw in the table after running top. For a fun exercise and to see kill in action, let's fire up top again. Find the top process in the table and make a note of the `PID`. Once you have that, open up a new Terminal (don't do it in the same one! Taking control back from the process kills it before you can, and that's boring!) session and type the following: 45 | 46 | ``` 47 | kill 1234 48 | ``` 49 | 50 | …substituting `1234` with the `PID` you just found. Switch back to the other Terminal window and you'll see that your table is gone. 51 | -------------------------------------------------------------------------------- /en-US/src/tips-and-tricks-part-one.md: -------------------------------------------------------------------------------- 1 | # Tips & Tricks 2 | 3 | Are you ready for some more command line goodness? This chapter we've got a veritable cornucopia of small tricks and tips to improve your terminal skills. 4 | 5 | ## 1. Alerts for process completion 6 | 7 | When you're executing a command that takes a while to finish, you can do something like this: 8 | 9 | ``` 10 | rake db:migrate && say "all done" 11 | ``` 12 | 13 | This is similar to a trick we saw last week. You can execute two commands on the same line by separating them with a semicolon, or you can use a boolean and ('&&'). The second command will only fire if the first one was successful. If your first command finishes without erroring out, the second one will fire – in this case, causing your computer's text-to-speech to say aloud whatever you typed in. While that's a neat trick, your environment might be inappropriate for sound. In that case, you should check out [Growl]("http://growl.info/"), an OSX tool that manages notifications*. 14 | 15 | * Also check out [Ruby Growl]("http://segment7.net/projects/ruby/growl/") for notifications, a fantastic suggestion by [Ben Johnson]("https://twitter.com/benbjohnson"). * 16 | 17 | ## 2. Execute the last command 18 | 19 | Let's say you execute a command, and your shell complains that you don't have permission to do that. You could type out the whole command again, prefixed with sudo, or you could do this: 20 | 21 | ``` 22 | sudo !! 23 | ``` 24 | 25 | `!!` grabs the last command you entered and substitutes it into the current text in the command line, giving you a chance to further edit the command before executing it. `!` has other uses too; you can grab the last command you entered that started with `mk` like this: 26 | 27 | ``` 28 | !mk 29 | ``` 30 | 31 | ## 3. cd – / pushd / popd 32 | 33 | Let's say you accidentally change directories and you don't want to type out the whole filepath to get back to where you were. You can just type: 34 | 35 | ``` 36 | cd - / pushd / popd 37 | ``` 38 | 39 | That'll take you back to the last directory you were in. On a related note, if you're working in multiple directories, you can use the `pushd` and `popd` commands to efficiently manage the directories you're interested in. `pushd` takes the directory you're currently working in, adds it to a stack of directories, then changes to either a directory passed in as a parameter or the directory on top of the stack. `popd` changes you to the directory on the top of the stack, then removes it from the stack. For more information on these two commands, check out [their Wikipedia page]("http://en.wikipedia.org/wiki/Pushd_and_popd"). Try experimenting with them yourself and see if you can get a better feel for their behavior. 40 | 41 | ## 4. Command-line navigation 42 | 43 | If you're like me, you're probably frustrated whenever you realize you made a typo at the beginning of your command. Using the arrow keys to maneuver back to the error and correct it is tedious at best. Fortunately, your prompt has some built in keyboard shortcuts that make it a little bit easier. 44 | 45 | To jump to the beginning of the line, use `ctrl + a`. Similarly, to get to the end of the line, type `ctrl + e`. These are easy to remember! The letter 'a' is at the beginning of the alphabet, and end starts with the letter `e`. 46 | 47 | To move back and forth between individual characters (just like the left and right arrow keys, but now you don't have to move your hand), use `ctrl + b` and `ctrl + f`. These are also easy to remember: `b` for back, and `f` for forward. 48 | 49 | To move between words in the command line, use `esc + b` and `esc + f`. This is a little bit more of a reach for your hand, but the ability to move between words is incredibly useful. 50 | -------------------------------------------------------------------------------- /en-US/src/tips-and-tricks-part-two.md: -------------------------------------------------------------------------------- 1 | # More Tips & Tricks 2 | 3 | ## 1. Customizing your prompt 4 | 5 | This trick is for everybody still using bash as their shell, because the format is a little bit different for people using zsh [nice, long post](here's a ("http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/") about customizing your zsh prompt). For bash, there are a few different environment variables that are used when determining what your shell prints out for the prompt. The one we're interested in is PS1, so let's check out what's there. 6 | 7 | ``` 8 | echo $PS1 9 | ``` 10 | 11 | If you're using the default bash prompt for OSX, you should see h:W u$ printed out. It only looks like gibberish right now. We can break it down into components to make it more sensible. 12 | 13 | First, you have h, which is a special character in this context. It tells the prompt command to spit out the hostname (just the first part); this will be what you named your computer when you took it out of the box, i.e. JaneBook or FancyPants. Sandwiched between h and the next special character is a colon. It doesn't have any special meaning, it's just there as a delimiter. Next is `W`; this prints out the working directory (without any of the parent directories listed; if that's something you want, try using `w`). Finally, you have `u` followed by `$`. u corresponds to your user name, and `$` is an escaped dollar sign; all that gets printed out is a dollar sign. 14 | 15 | Remembering all of those special characters can be a drag, so here's [a cheat sheet]("http://ss64.com/bash/syntax-prompt.html") for you to use. Armed with all of that knowledge, let's try building our own prompt. 16 | 17 | ``` 18 | export PS1="[\t \w] $" 19 | ``` 20 | 21 | This will make your prompt look something like this: `[21:51:42 ~] $`. We have the current time, given by `t`, followed by the working directory (`w`), encased in a pair of parentheses, followed up by a dollar sign. To make this change permanent, put that line of code into your `.bashrc` profile. 22 | 23 | ## 2. Background Tasks 24 | 25 | If you've ever run a command that takes ahold of your prompt and won't let go until you terminate it, this trick might be useful for you. To run a command in the background (i.e., without relinquishing control of your shell), append '&' to the end of the command. As an example, we'll use a command we've covered before that takes up your prompt, although it won't be the most useful command to run in the background: 26 | 27 | ``` 28 | top & 29 | ``` 30 | 31 | We've seen top before; we used it to identify which process was consuming the most memory before killing it. Again, it's not the most useful command to run in the background, but it's convenient for us to use here. After running that, you'll get confirmation from your shell that the command's process is up and running, and you'll also get the Pid. Next, try: 32 | 33 | ``` 34 | jobs 35 | ``` 36 | 37 | This command will show you all the commands you have running in the background (which are called jobs! Hence, this command's name). Now, to bring a job back to the foreground, type: 38 | 39 | ``` 40 | fg %1 41 | ``` 42 | 43 | The `fg` command is short for "foreground"; it brings a process forward. The syntax is a little strange; enter `%`, followed by the job number. You should note the job number is separate from the process number. If you add the `-l` flag onto jobs, it'll show you both. 44 | 45 | ## 3. Control + R 46 | 47 | We've seen how you can combine the `grep` and `history` commands to find a particular command, then execute it. We've also seen that you can type !! to execute the last command. Here's the new trick that combines these two. If you press the control key in combination with `r`, then you can perform a backwards search on your history for a given phrase. When you press `control + r`, you'll get a prompt that says `bck-i-search:`. Type in a phrase, and your prompt will be automatically completed with the last command that contained that phrase. If you keep pressing `control + r`, then the search will iterate backwards over your history, finding the next match. Executing the command listed is as simple as pressing enter! 48 | -------------------------------------------------------------------------------- /en-US/src/xargs-and-cut.md: -------------------------------------------------------------------------------- 1 | # Xargs & Cut 2 | 3 | This chapter we're going to talk about the `xargs` command in depth, and then we'll touch on the cut command. 4 | 5 | When you chain commands together to achieve a longer effect, you have a few different options. Typically you'll use a [pipe]("http://quickleft.com/blog/command-line-tutorials-redirection-pipes") to accomplish something longer, like so: 6 | 7 | ``` 8 | ps aux | grep rails 9 | ``` 10 | 11 | That should be nothing new, but what if you wanted to chain a command together for multiple arguments? Perhaps you want to move all the files of a certain type in the current directory somewhere else, or you want to print out several files at once to more easily search their contents (something that '[grep]("http://quickleft.com/blog/command-line-tutorials-finding-grepping")' can do by itself, actually. but stick with me). How would I do something like that? 12 | 13 | ### xargs 14 | 15 | Enter the `xargs` command. `xargs` is a command "used to build and execute command lines from standard input". It executes commands that don't accept standard input (i.e. things passed in using a pipe) with the arguments from standard input. If that doesn't make any sense, then maybe an example will help: 16 | 17 | ``` 18 | ls | xargs cat 19 | ``` 20 | 21 | Here's a normal '[ls]("http://quickleft.com/blog/command-line-for-beginners-part-1")' command, being piped into `xargs`. The latter takes a list of white space separated arguments – like the one ls produces – and then executes the command that follows ('("http://quickleft.com/blog/command-line-for-beginners-part-2")[cat]', in this example) on each file listed. This results in having each file in the current directory 'cat'ed out to your screen. 22 | 23 | ### ALL the flags 24 | 25 | Here's how you can use xargs to move all the files of a certain kind somewhere else, like a hidden directory: 26 | 27 | ``` 28 | ls ~/*.txt | xargs -pI text_file mv text_file ~/.temp_txt 29 | ``` 30 | 31 | Oh man. There's a lot of stuff going on in there. First, we have an `ls` for all the files that end in '.txt' inside our home directory. We've seen that [wildcard operator]("http://quickleft.com/blog/command-line-tutorials-finding-grepping") (the '*') before, so that's nothing new. Next, we pipe that list into `xargs`, which now has a pair of flags to go with it. The 'p' flag gives us a prompt before executing each command; when you executed, you'll get a yes or no confirmation for each file it matched. 32 | 33 | The 'I' flag is used to give the argument received a name ('text_file' in this case: the name is given immediately after the flag). As you can see, that name gets used later in the `xargs` command, as the first argument to the '[mv]("http://quickleft.com/blog/command-line-for-beginners-part-2")'. That `mv` command is still part of `xargs`; it's where the magic actually happens, so remember that! 34 | 35 | Whew, okay. Let's regroup. If you execute that command, you'll be prompted whether or not you'd like to move each text file you have in your home directory, one at a time. That's pretty neat! 36 | 37 | ### cut 38 | 39 | A useful tool for `xargs` is the `cut` command. `cut` takes in a file and extracts certain portions of it – typically either characters or fields. Here's an example that counts up the number of subdirectories inside your current directory: 40 | 41 | ``` 42 | ls -la | cut -c 1 | grep d | wc -l 43 | ``` 44 | 45 | Here we print out the current directory's contents, then we cut only the first character. With the long form (-l) of `ls`, that character will be a "d" if the file is a directory. Then, we `grep` for the letter "d", eliminating everything else, then we use the `wc` command to count up the number of lines. Chaining commands together is fun! 46 | 47 | ### MOAR flags 48 | 49 | The `c` flag for `cut` cuts on characters, and the argument that follows tells `cut` how many characters to grab and from where. To use `cut` to get a whole field, you can do something like this: 50 | 51 | ``` 52 | ls -la | cut -f 1 -d " " 53 | ``` 54 | 55 | The `f` flag is exclusive to the `c` flag; that tells `cut` to grab fields instead of characters. Closely tied to the `f` flag is the `d` flag. That allows you to change the delimiter for `cut`, which is the tab character by default. That command will spit out the permissions for each file in your current directory, which isn't actually useful by itself, but serves as a nice example. 56 | -------------------------------------------------------------------------------- /en-US/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | $pagetitle$ 9 | $if(highlighting-css)$ 10 | 13 | $endif$ 14 | $for(css)$ 15 | 16 | $endfor$ 17 | 18 | 19 | $if(titlepage)$ 20 | $for(title)$ 21 | $if(title.text)$ 22 |

$title.text$

23 | $else$ 24 |

$title$

25 | $endif$ 26 | $endfor$ 27 | $if(subtitle)$ 28 |

$subtitle$

29 | $endif$ 30 | $for(author)$ 31 |

$author$

32 | $endfor$ 33 | $for(creator)$ 34 |

$creator.text$

35 | $endfor$ 36 | $if(publisher)$ 37 |

$publisher$

38 | $endif$ 39 | $if(date)$ 40 |

$date$

41 | $endif$ 42 | $if(rights)$ 43 |

$rights$

44 | $endif$ 45 | $if(version)$ 46 |

Version: $version$

47 | $endif$ 48 | $else$ 49 | $body$ 50 | $endif$ 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /en-US/title.txt: -------------------------------------------------------------------------------- 1 | --- 2 | title: Just Enough Unix Command Line 3 | creator: 4 | - role: author 5 | text: Jessica Dillon 6 | - role: editor 7 | text: Kiera Manion-Fischer 8 | publisher: Just Enough Media 9 | rights: © 2015 Zinc Technology Inc, CC BY-NC 10 | language: en-US 11 | cover-image: design/Cover.png 12 | version: 0.2.0-DEV 13 | --- 14 | -------------------------------------------------------------------------------- /output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cohere-coop/just-enough-unix-command-line/8e20c7858384827d6b825783479d356cded937c7/output/.gitkeep --------------------------------------------------------------------------------