├── .gitignore ├── AUTHORS.md ├── CONTRIBUTING.md ├── README-cs.md ├── README-de.md ├── README-el.md ├── README-es.md ├── README-fr.md ├── README-id.md ├── README-it.md ├── README-ja.md ├── README-ko.md ├── README-pl.md ├── README-pt.md ├── README-ro.md ├── README-ru.md ├── README-sl.md ├── README-uk.md ├── README-zh-Hant.md ├── README-zh.md ├── README.md ├── admin └── authors-info.yml └── cowsay.png /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | This work is the result of the effort of many people around the world. 4 | Contributors are listed in alphabetical order by GitHub login. 5 | 6 | Some contributors are also assigned roles as maintainers. 7 | They have kindly agreed to review and help update future contributions for the translation or section they own. 8 | 9 | 10 | 11 | *Maintainers* 12 | 13 | * [Ahmad Zafrullah (23Pstars)](https://github.com/23Pstars) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=23Pstars)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3A23Pstars) — _translation maintainer (id)_ 14 | * [Anna Damtsa (anna-d)](https://github.com/anna-d) — [24+](https://github.com/jlevy/the-art-of-command-line/commits?author=anna-d)/[7+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aanna-d) — _translation maintainer (el)_ 15 | * [Carlos Mantilla (ceoaliongroo)](https://github.com/ceoaliongroo) — [29+](https://github.com/jlevy/the-art-of-command-line/commits?author=ceoaliongroo)/[16+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aceoaliongroo) — _translation maintainer (es)_ 16 | * [Dmytro Kovalov (uk: Дмитро Ковальов) (dmytro)](https://github.com/dmytro) — [6+](https://github.com/jlevy/the-art-of-command-line/commits?author=dmytro)/[4+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Admytro) — _translation maintainer (uk)_ 17 | * [Hayato Matsuura (doublemarket)](https://github.com/doublemarket) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=doublemarket)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adoublemarket) — _translation maintainer (ja)_ 18 | * [Diomidis Spinellis (dspinellis)](https://github.com/dspinellis) — [15+](https://github.com/jlevy/the-art-of-command-line/commits?author=dspinellis)/[11+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adspinellis) — _section maintainer (Windows)_ 19 | * [Éric Guirbal (ericguirbal)](https://github.com/ericguirbal) — [31+](https://github.com/jlevy/the-art-of-command-line/commits?author=ericguirbal)/[14+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aericguirbal) — _translation maintainer (fr)_ 20 | * [Francesco Malatesta (francescomalatesta)](https://github.com/francescomalatesta) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=francescomalatesta)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Afrancescomalatesta) — _translation maintainer (it)_ 21 | * [Joshua Levy (jlevy)](https://github.com/jlevy) — [162+](https://github.com/jlevy/the-art-of-command-line/commits?author=jlevy)/[59+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajlevy) — _original author and project maintainer_ 22 | * [kevingo (kevingo)](https://github.com/kevingo) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=kevingo)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akevingo) — _translation maintainer (zh-Hant)_ 23 | * [lsrom](https://github.com/lsrom) — [14+](https://github.com/jlevy/the-art-of-command-line/commits?author=lsrom)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Alsrom) — _translation maintainer (cs)_ 24 | * [Mihai Maruseac (mihaimaruseac)](https://github.com/mihaimaruseac) — [10+](https://github.com/jlevy/the-art-of-command-line/commits?author=mihaimaruseac)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amihaimaruseac) — _translation maintainer (ro)_ 25 | * [Nilton Vasques (niltonvasques)](https://github.com/niltonvasques) — [24+](https://github.com/jlevy/the-art-of-command-line/commits?author=niltonvasques)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aniltonvasques) — _translation maintainer (pt)_ 26 | * [Oleg Berman (olegberman)](https://github.com/olegberman) — [15+](https://github.com/jlevy/the-art-of-command-line/commits?author=olegberman)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aolegberman) — _translation maintainer (ru)_ 27 | * [Peter Kokot (petk)](https://github.com/petk) — [54+](https://github.com/jlevy/the-art-of-command-line/commits?author=petk)/[39+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Apetk) — _translation maintainer (sl)_ 28 | * [Chujie Zeng (Psycho7)](https://github.com/Psycho7) — [25+](https://github.com/jlevy/the-art-of-command-line/commits?author=Psycho7)/[9+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3APsycho7) — _translation maintainer (zh)_ 29 | * [Martin Folkers (S1SYPHOS)](https://github.com/S1SYPHOS) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=S1SYPHOS)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AS1SYPHOS) — _translation maintainer (de)_ 30 | * [Stepan Babala (stepan0904)](https://github.com/stepan0904) — [37+](https://github.com/jlevy/the-art-of-command-line/commits?author=stepan0904)/[6+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Astepan0904) — _translation (uk)_ 31 | * [Ungsik Yun (Ungsik-Yun)](https://github.com/Ungsik-Yun) — [15+](https://github.com/jlevy/the-art-of-command-line/commits?author=Ungsik-Yun)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AUngsik-Yun) — _translation maintainer (ko)_ 32 | 33 | *Translators* 34 | 35 | * [Antonio Ossa (aaossa)](https://github.com/aaossa) — [5+](https://github.com/jlevy/the-art-of-command-line/commits?author=aaossa)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aaaossa) — _translator (es)_ 36 | * [Chong Guo (Armour)](https://github.com/Armour) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=Armour)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AArmour) — _translator (zh)_ 37 | * [Bogdan Luput (bgdnlp)](https://github.com/bgdnlp) — _translator (ro)_ 38 | * [Alex Vergara Gil (BishopWolf)](https://github.com/BishopWolf) — [4+](https://github.com/jlevy/the-art-of-command-line/commits?author=BishopWolf)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ABishopWolf) — _translator (es)_ 39 | * [Gernot Pointner (gernd)](https://github.com/gernd) — [6+](https://github.com/jlevy/the-art-of-command-line/commits?author=gernd)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agernd) — _translator (de)_ 40 | * [githubashto](https://github.com/githubashto) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=githubashto)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agithubashto) — _translator (ru)_ 41 | * [Grigory Rechistov (grigory-rechistov)](https://github.com/grigory-rechistov) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=grigory-rechistov)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agrigory-rechistov) — _translator (ru)_ 42 | * [Sung Kim (hunkim)](https://github.com/hunkim) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=hunkim)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ahunkim) — _translator (ko)_ 43 | * [kstn (kastian)](https://github.com/kastian) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=kastian)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akastian) — _translator (ru)_ 44 | * [Kohei Takada (koh7)](https://github.com/koh7) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=koh7)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akoh7) — _translator (ja)_ 45 | * [osmero](https://github.com/osmero) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=osmero)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aosmero) — _translator (ru)_ 46 | * [Remi Verchere (rverchere)](https://github.com/rverchere) — _translator (fr)_ 47 | * [Snowcat8436 (Snowcat8436)](https://github.com/Snowcat8436) — [4+](https://github.com/jlevy/the-art-of-command-line/commits?author=Snowcat8436)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ASnowcat8436) — _translator (ko)_ 48 | * [spmbt (spmbt)](https://github.com/spmbt) — [13+](https://github.com/jlevy/the-art-of-command-line/commits?author=spmbt)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aspmbt) — _translator (ru)_ 49 | * [Steven Liu (stevenlordiam)](https://github.com/stevenlordiam) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=stevenlordiam)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Astevenlordiam) — _translator (zh)_ 50 | * [Thomas Sungjin Kang (ujuc)](https://github.com/ujuc) — [6+](https://github.com/jlevy/the-art-of-command-line/commits?author=ujuc)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aujuc) — _translator (ko)_ 51 | * [Valeria de Paiva (vcvpaiva)](https://github.com/vcvpaiva) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=vcvpaiva)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Avcvpaiva) — _translator (pt)_ 52 | * [Xu Chunyang (xuchunyang)](https://github.com/xuchunyang) — [13+](https://github.com/jlevy/the-art-of-command-line/commits?author=xuchunyang)/[7+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Axuchunyang) — _translator (zh)_ 53 | 54 | *Contributors* 55 | 56 | * [0xCD](https://github.com/0xCD) — [4+](https://github.com/jlevy/the-art-of-command-line/commits?author=0xCD)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3A0xCD) 57 | * [0xmohit](https://github.com/0xmohit) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=0xmohit)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3A0xmohit) 58 | * [Jiang Guoxi (374632897)](https://github.com/374632897) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=374632897)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3A374632897) 59 | * [Andrii (aaabramov)](https://github.com/aaabramov) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=aaabramov)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aaaabramov) 60 | * [Ahmet Alp Balkan (ahmetb)](https://github.com/ahmetb) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=ahmetb)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aahmetb) 61 | * [Alexander Bodin (AlexanderBodin)](https://github.com/AlexanderBodin) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=AlexanderBodin)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AAlexanderBodin) 62 | * [Semir Patel (analogue)](https://github.com/analogue) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=analogue)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aanalogue) 63 | * [Andreas Hofmann (andreas-hofmann)](https://github.com/andreas-hofmann) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=andreas-hofmann)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aandreas-hofmann) 64 | * [Desmond Stonie (aneasystone)](https://github.com/aneasystone) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=aneasystone)/[8+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aaneasystone) 65 | * [anna-4](https://github.com/anna-4) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=anna-4)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aanna-4) 66 | * [Brad Beyenhof (augmentedfourth)](https://github.com/augmentedfourth) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=augmentedfourth)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aaugmentedfourth) 67 | * [b-jazz (b-jazz)](https://github.com/b-jazz) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=b-jazz)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ab-jazz) 68 | * [bafoed](https://github.com/bafoed) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=bafoed)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Abafoed) 69 | * [Colas BROUX (brouxco)](https://github.com/brouxco) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=brouxco)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Abrouxco) 70 | * [Alex Cabrera (cabreraalex)](https://github.com/cabreraalex) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=cabreraalex)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Acabreraalex) 71 | * [Chris Kuehl (chriskuehl)](https://github.com/chriskuehl) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=chriskuehl)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Achriskuehl) 72 | * [Christopher Biscardi (ChristopherBiscardi)](https://github.com/ChristopherBiscardi) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=ChristopherBiscardi)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AChristopherBiscardi) 73 | * [Sihan Li (ClumsyLee)](https://github.com/ClumsyLee) — [12+](https://github.com/jlevy/the-art-of-command-line/commits?author=ClumsyLee)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AClumsyLee) 74 | * [Corey Richardson (cmr)](https://github.com/cmr) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=cmr)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Acmr) 75 | * [CodinCat (CodinCat)](https://github.com/CodinCat) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=CodinCat)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ACodinCat) 76 | * [Colin Wang (colinwjd)](https://github.com/colinwjd) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=colinwjd)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Acolinwjd) 77 | * [Chris Rhodes (crr0004)](https://github.com/crr0004) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=crr0004)/[4+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Acrr0004) 78 | * [Daniel t. (danasmera)](https://github.com/danasmera) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=danasmera)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adanasmera) 79 | * [Dmytro Danylevskyi (danylevskyi)](https://github.com/danylevskyi) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=danylevskyi)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adanylevskyi) 80 | * [Dave Loyall (daveloyall)](https://github.com/daveloyall) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=daveloyall)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adaveloyall) 81 | * [Kirill (DDyst)](https://github.com/DDyst) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=DDyst)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ADDyst) 82 | * [Deborah Gertrude Digges (Deborah-Digges)](https://github.com/Deborah-Digges) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=Deborah-Digges)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ADeborah-Digges) 83 | * [Jamie Luck (delucks)](https://github.com/delucks) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=delucks)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adelucks) 84 | * [Dillon Flamand (dflamand)](https://github.com/dflamand) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=dflamand)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adflamand) 85 | * [Michael Diamond (dimo414)](https://github.com/dimo414) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=dimo414)/[4+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Adimo414) 86 | * [Vincent Wong (EaterOA)](https://github.com/EaterOA) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=EaterOA)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AEaterOA) 87 | * [Veck Hsiao (fbukevin)](https://github.com/fbukevin) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=fbukevin)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Afbukevin) 88 | * [Fernando Almeida (fernandoalmeida)](https://github.com/fernandoalmeida) — [8+](https://github.com/jlevy/the-art-of-command-line/commits?author=fernandoalmeida)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Afernandoalmeida) 89 | * [Sami (fnzv)](https://github.com/fnzv) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=fnzv)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Afnzv) 90 | * [Gaga Pan (gaga5lala)](https://github.com/gaga5lala) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=gaga5lala)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agaga5lala) 91 | * [Massimiliano Arione (garak)](https://github.com/garak) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=garak)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agarak) 92 | * [XinYu Zheng (gayu-mike)](https://github.com/gayu-mike) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=gayu-mike)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agayu-mike) 93 | * [Konstantin Gribov (grossws)](https://github.com/grossws) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=grossws)/[6+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Agrossws) 94 | * [Ashhar Hasan (hashhar)](https://github.com/hashhar) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=hashhar)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ahashhar) 95 | * [Beau Hastings (hastinbe)](https://github.com/hastinbe) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=hastinbe)/[4+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ahastinbe) 96 | * [Iliana Panagopoulou (hpanago)](https://github.com/hpanago) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=hpanago)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ahpanago) 97 | * [Space exploration enthusiast (Hunter-Github)](https://github.com/Hunter-Github) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=Hunter-Github)/[5+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AHunter-Github) 98 | * [Hyojin Kwak (hyojin)](https://github.com/hyojin) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=hyojin)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ahyojin) 99 | * [Ihor Dvoretskyi (idvoretskyi)](https://github.com/idvoretskyi) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=idvoretskyi)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aidvoretskyi) 100 | * [Kevin Morales (iKenshu)](https://github.com/iKenshu) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=iKenshu)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AiKenshu) 101 | * [Ilja Krauchanka (ikrauchanka)](https://github.com/ikrauchanka) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=ikrauchanka)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aikrauchanka) 102 | * [Sergey Isaev (isvforall)](https://github.com/isvforall) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=isvforall)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aisvforall) 103 | * [Igor Veksler (iveksl2)](https://github.com/iveksl2) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=iveksl2)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aiveksl2) 104 | * [J Alan Brogan (jalanb)](https://github.com/jalanb) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=jalanb)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajalanb) 105 | * [James Kolce (jameskolce)](https://github.com/jameskolce) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=jameskolce)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajameskolce) 106 | * [Dotan J. Nahum (jondot)](https://github.com/jondot) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=jondot)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajondot) 107 | * [Jesse Sightler (jsight)](https://github.com/jsight) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=jsight)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajsight) 108 | * [Konstantin Mikhailov (jtraub)](https://github.com/jtraub) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=jtraub)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajtraub) 109 | * [Jakub Wilk (jwilk)](https://github.com/jwilk) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=jwilk)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ajwilk) 110 | * [Wael Nasreddine (kalbasit)](https://github.com/kalbasit) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=kalbasit)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akalbasit) 111 | * [Colin Chan (kalgynirae)](https://github.com/kalgynirae) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=kalgynirae)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akalgynirae) 112 | * [Michalis Kargakis (kargakis)](https://github.com/kargakis) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=kargakis)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akargakis) 113 | * [Kesu J (kesu)](https://github.com/kesu) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=kesu)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akesu) 114 | * [Takuma Yamaguchi (kumon)](https://github.com/kumon) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=kumon)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Akumon) 115 | * [Dmytro Prokhorenkov (l13t)](https://github.com/l13t) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=l13t)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Al13t) 116 | * [Mikhail Letunovskiy (l3xx)](https://github.com/l3xx) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=l3xx)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Al3xx) 117 | * [Lakshmipathi (Lakshmipathi)](https://github.com/Lakshmipathi) — [10+](https://github.com/jlevy/the-art-of-command-line/commits?author=Lakshmipathi)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ALakshmipathi) 118 | * [Pavel Zhukov (landgraf)](https://github.com/landgraf) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=landgraf)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Alandgraf) 119 | * [lcmtwn](https://github.com/lcmtwn) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=lcmtwn)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Alcmtwn) 120 | * [Lampros Mountrakis (lmount)](https://github.com/lmount) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=lmount)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Almount) 121 | * [Luke Yeager (lukeyeager)](https://github.com/lukeyeager) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=lukeyeager)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Alukeyeager) 122 | * [TAKAGI Masahiro (m-takagi)](https://github.com/m-takagi) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=m-takagi)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Am-takagi) 123 | * [Who? Me?! (mark-i-m)](https://github.com/mark-i-m) — [5+](https://github.com/jlevy/the-art-of-command-line/commits?author=mark-i-m)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amark-i-m) 124 | * [marocchino](https://github.com/marocchino) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=marocchino)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amarocchino) 125 | * [Matjaž Lipuš (matjaz)](https://github.com/matjaz) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=matjaz)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amatjaz) 126 | * [Mayra Cabrera (mayra-cabrera)](https://github.com/mayra-cabrera) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=mayra-cabrera)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amayra-cabrera) 127 | * [Michael Barlow (michaelbarlow7)](https://github.com/michaelbarlow7) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=michaelbarlow7)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amichaelbarlow7) 128 | * [Jinhui-Lin (mintisan)](https://github.com/mintisan) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=mintisan)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amintisan) 129 | * [Crisoforo Gaspar Hernández (mitogh)](https://github.com/mitogh) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=mitogh)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amitogh) 130 | * [miuc (miuc)](https://github.com/miuc) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=miuc)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amiuc) 131 | * [Michael Kwardakov (mkwardakov)](https://github.com/mkwardakov) — [7+](https://github.com/jlevy/the-art-of-command-line/commits?author=mkwardakov)/[14+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amkwardakov) 132 | * [Harry Moreno (morenoh149)](https://github.com/morenoh149) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=morenoh149)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amorenoh149) 133 | * [Dongliang Mu (mudongliang)](https://github.com/mudongliang) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=mudongliang)/[10+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Amudongliang) 134 | * [Lilian Besson (Naereen)](https://github.com/Naereen) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=Naereen)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ANaereen) 135 | * [Namgoo Lee (nglee)](https://github.com/nglee) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=nglee)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Anglee) 136 | * [Serg Petrov (p12se)](https://github.com/p12se) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=p12se)/[0+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ap12se) 137 | * [王霄池(wangxiaochi) (picasso250)](https://github.com/picasso250) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=picasso250)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Apicasso250) 138 | * [pravdomil (pravdomil)](https://github.com/pravdomil) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=pravdomil)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Apravdomil) 139 | * [Rahul Kavale (rahulkavale)](https://github.com/rahulkavale) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=rahulkavale)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Arahulkavale) 140 | * [Rasmus Wriedt Larsen (RasmusWL)](https://github.com/RasmusWL) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=RasmusWL)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ARasmusWL) 141 | * [Riley Shaw (rileyjshaw)](https://github.com/rileyjshaw) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=rileyjshaw)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Arileyjshaw) 142 | * [Ryan Delaney (rpdelaney)](https://github.com/rpdelaney) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=rpdelaney)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Arpdelaney) 143 | * [Haoxuan Li (Sagir1)](https://github.com/Sagir1) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=Sagir1)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ASagir1) 144 | * [Saksham Sharma (sakshamsharma)](https://github.com/sakshamsharma) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=sakshamsharma)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Asakshamsharma) 145 | * [Semen Martynov (SemenMartynov)](https://github.com/SemenMartynov) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=SemenMartynov)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ASemenMartynov) 146 | * [Kit Chan (shukitchan)](https://github.com/shukitchan) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=shukitchan)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ashukitchan) 147 | * [Simarpreet Singh (simar7)](https://github.com/simar7) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=simar7)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Asimar7) 148 | * [snowme34 (snowme34)](https://github.com/snowme34) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=snowme34)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Asnowme34) 149 | * [Soham Chakraborty (SohamChakraborty)](https://github.com/SohamChakraborty) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=SohamChakraborty)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3ASohamChakraborty) 150 | * [Fabien Dubosson (StreakyCobra)](https://github.com/StreakyCobra) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=StreakyCobra)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3AStreakyCobra) 151 | * [Chengcheng Tang (tangchengcheng)](https://github.com/tangchengcheng) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=tangchengcheng)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Atangchengcheng) 152 | * [taxusyew](https://github.com/taxusyew) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=taxusyew)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ataxusyew) 153 | * [Timur (tim-teufel)](https://github.com/tim-teufel) — [4+](https://github.com/jlevy/the-art-of-command-line/commits?author=tim-teufel)/[3+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Atim-teufel) 154 | * [Timotei Dolean (timotei)](https://github.com/timotei) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=timotei)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Atimotei) 155 | * [Haoyu Qiu (timothyqiu)](https://github.com/timothyqiu) — [4+](https://github.com/jlevy/the-art-of-command-line/commits?author=timothyqiu)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Atimothyqiu) 156 | * [René Ribaud (uggla)](https://github.com/uggla) — [5+](https://github.com/jlevy/the-art-of-command-line/commits?author=uggla)/[10+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Auggla) 157 | * [Joe Block (unixorn)](https://github.com/unixorn) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=unixorn)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aunixorn) 158 | * [vitzli](https://github.com/vitzli) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=vitzli)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Avitzli) 159 | * [Eduardo Rolim (vndmtrx)](https://github.com/vndmtrx) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=vndmtrx)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Avndmtrx) 160 | * [senhtry (w169q169)](https://github.com/w169q169) — [3+](https://github.com/jlevy/the-art-of-command-line/commits?author=w169q169)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Aw169q169) 161 | * [Evan Wong (wyf88)](https://github.com/wyf88) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=wyf88)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Awyf88) 162 | * [Okunev Yu Dmitry (xaionaro)](https://github.com/xaionaro) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=xaionaro)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Axaionaro) 163 | * [yasuhiroki (yasuhiroki)](https://github.com/yasuhiroki) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=yasuhiroki)/[2+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ayasuhiroki) 164 | * [Alex F. (youmee)](https://github.com/youmee) — [1+](https://github.com/jlevy/the-art-of-command-line/commits?author=youmee)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ayoumee) 165 | * [Youngwoo Kim (youngwookim)](https://github.com/youngwookim) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=youngwookim)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ayoungwookim) 166 | * [yssmcl](https://github.com/yssmcl) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=yssmcl)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Ayssmcl) 167 | * [Zack Piper (zackp30)](https://github.com/zackp30) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=zackp30)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Azackp30) 168 | * [Aleksandr Zhuravlev (zelark)](https://github.com/zelark) — [2+](https://github.com/jlevy/the-art-of-command-line/commits?author=zelark)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Azelark) 169 | * [Xudong Zhang (zxdvd)](https://github.com/zxdvd) — [0+](https://github.com/jlevy/the-art-of-command-line/commits?author=zxdvd)/[1+](https://github.com/jlevy/the-art-of-command-line/issues?q=author%3Azxdvd) 170 | 171 | Numbers link to commits/issues. 172 | For simplicity, this file is maintained only in English. 173 | 174 | If your name does not appear as you would like it above, verify your name on your GitHub profile. 175 | Also confirm that your commits are using the correct e-mail to it is linked to your profile. 176 | 177 | If you see inaccuracies or omissions, please file an issue, or edit the authors-info.yml file, regenerate, and file a PR. 178 | 179 | 180 | 181 | (This file was auto-generated by [ghizmo assemble-authors](https://github.com/jlevy/ghizmo).) -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to The Art of Command Line 2 | 3 | This guide is a [collaborative effort](AUTHORS.md), based on the generous work of many contributors. 4 | 5 | ## Questions 6 | 7 | [![Ask a Question](https://img.shields.io/badge/%3f-Ask%20a%20Question-ff69b4.svg)](https://airtable.com/shrzMhx00YiIVAWJg) 8 | 9 | The simplest thing you can do to help is [**submit any questions you might have**](https://airtable.com/shrzMhx00YiIVAWJg). 10 | The more the better. Questions help identify where the guide needs to be improved. 11 | 12 | 13 | ## Contributions 14 | 15 | Contributions of all kinds, including corrections, additions, improvements, and translations, are welcome! 16 | 17 | We hope you'll join and help, in small ways or large. 18 | Here are few notes before you jump in. 19 | 20 | ### Style 21 | 22 | - Stay close to the existing style of the document when possible. 23 | - Remember to focus on **brevity**, **specificity**, and **utility**. 24 | - Avoid long explanations and instead prefer links to resources. 25 | 26 | ### Using issues and PRs 27 | 28 | - Please **create and comment on issues freely** to discuss. A lot of the difficulty in accepting PRs is around style and format, and whether changes should be made at all, so rationale or explanations for the change are useful. 29 | - Please **review open issues and pull requests** before submitting a new one, to help reduce duplication. 30 | - To the extent possible, **break up changes into multiple PRs** so they can be approved separately. Large contributions are also welcome, but are harder and slower to approve, as they tend to require discussion or rewriting. 31 | 32 | 33 | ## Translations 34 | 35 | The guide is now available in many languages. Here is the process for maintaining translations: 36 | 37 | - This original version and content of the guide is maintained in English. 38 | - *Translations follow the content of the original.* Note this means contributors to a translation must be able to read some English, so that translations do not diverge (unless it is only fixing a typo). 39 | - Each translation has a maintainer to update the translation as the original evolves and to review others' changes. This doesn't require a lot of time, but review by the maintainer is important to maintain quality. 40 | - See the [AUTHORS.md](AUTHORS.md) file for current maintainers. (This file is generated from the [authors-info.yml](admin/authors-info.yml) file.) 41 | 42 | ### Changes to translations 43 | 44 | - Changes to content should be made to the English version first, and then translated to each other language. 45 | - Changes that improve translations should be made directly on the file for that language. PRs should only modify one language at a time. 46 | - Submit a PR with changes to the file in that language. Each language has a maintainer, who reviews changes in that language. Then the primary maintainer @jlevy merges it in. 47 | - Prefix PRs and issues with language codes if they are for that translation only, e.g. "es: Improve grammar", so maintainers can find them easily. 48 | 49 | ### Adding a translation to a new language 50 | 51 | Translations to new languages are always welcome! Keep in mind a transation must be maintained, so it's needed to have one person maintain each translation. 52 | 53 | - Check existing issues to see if a translation is in progress or stalled. If so, offer to help. 54 | - Do you have time to be a maintainer for the new language? Please say so so we know we can count on you in the future. 55 | - If it is not in progress, file an issue for your language so people know you are working on it and we can arrange. Confirm you are native level in the language and are willing to maintain the translation, so it's not orphaned. 56 | - To get it started, fork the repo, then submit a PR with the single file README-xx.md added, where xx is the language code. Use standard [IETF language tags](https://www.w3.org/International/articles/language-tags/), i.e. the same as is used by Wikipedia, *not* the code for a single country. These are usually just the two-letter lowercase code, for example, `fr` for French and `uk` for Ukrainian (not `ua`, which is for the country). For languages that have variations, use the shortest tag, such as `zh-Hant`. 57 | - *Invite friends to review* if possible. Tranlsations are difficult and usually have erros others need to find. If desired, feel free to invite them to help your original translation by letting them fork your repo, then merging their PRs. 58 | - Add links to your translation at the top of every README*.md file. (For consistency, the link should be added in alphabetical order by ISO code, and the anchor text should be in the native language.) 59 | - When done, indicate on the PR that it's ready to be merged into the main repo. 60 | 61 | ### Further questions 62 | 63 | Unsure of the process? 64 | Or do you have skills and inclination to help in a more substantial way? 65 | File an issue or e-mail the original author [@jlevy](https://github.com/jlevy). 66 | -------------------------------------------------------------------------------- /README-cs.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | # Umění příkazové řádky 5 | 6 | [![Join the chat at https://gitter.im/jlevy/the-art-of-command-line](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 7 | 8 | - [Meta](#meta) 9 | - [Základy](#zaklady) 10 | - [Každodenní použití](#kazdodenni-pouziti) 11 | - [Zpracování souborů a dat](#zpracovani-souboru-a-dat) 12 | - [Ladění systému](#ladeni-systemu) 13 | - [Jednořádkové příkazy](#jednoradkove-prikazy) 14 | - [Neobvyklé ale užitečné](#neobvykle-ale-uzitecne) 15 | - [Pouze pro OS X](#pouze-pro-os-x) 16 | - [Další zdroje](#dalsi-zdroje) 17 | - [Zřeknutí se odpovědnosti](#zreknuti-se-odpovednosti) 18 | 19 | 20 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 21 | 22 | Plynulost práce na příkazové řádce je umění často opomíjené nebo považované za překonané, ale zlepšuje vaši flexibilitu a produktivitu jako inženýr jak očividně tak nenápadně. Toto je výběr poznámek a tipů pro použití příkazové řádky které shledáváme užitečnými při práci na Linuxu. Některé tipy jsou základní a některé jsou velmi specifické, komplikované či nejasné. Tato stránka není dlouhá, ale pokud dokážete použít a vybavit si všechny věci zde zmíněné, máte dostatečně rozsáhlé vědomosti. 23 | 24 | Tato práce je výsledkem [mnoha autorů a překladatelů](AUTHORS.md). 25 | Mnoho se 26 | [původně](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands) 27 | [objevilo](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix) 28 | na webu [Quora](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know), 29 | ale s ohledem na zájem, který tam panoval, se zdálo vhodné použít GitHub, kde lidé více talentovaní než původní autor mohli okamžitě navrhovat zlepšení. Pokud najdete chybu či něco, co by mohlo být vylepšeno, prosím vytvořte issue nebo pull request! (Samozřejmě nejdříve zkontrolujte meta sekci a existující pull requesty a issues.) 30 | 31 | 32 | ## Meta 33 | 34 | Rozsah: 35 | 36 | - Tento průvodce je pro začátečníky i pro pokročilé. Cílem je *široký záběr* (vše důležité), *specifičnost* (poskytnout konkrétní příklady nejčastějšího použití) a *stručnost* (vyhnout se věcem, které nejsou nezbytné nebo podobným tématům, které lze vyhledat jinde). Každý tip je v některých případech nenahraditelný nebo značně šetří čas oproti alternativám. 37 | - Tento dokument je napsán pro Linux s vyjímkou sekcí označených jako "[Pouze pro OS X](#os-x-only)". Mnoho ostatních položek lze použít nebo je lze nainstalovat na jiných Unixových systémech nebo MacOS (dokonce i na Cygwin). 38 | - Zaměření dokumentu je na inteaktivní Bash ačkoli mnoho tipů lze aplikovat na jiné shelly a obecné bashové scriptování. 39 | . Jsou zahrnuty jak "standardní" Unixové příkazy tak příkazy vyžadující instalaci extra balíčků -- pokud jsou dost důležité aby zasloužily zmínku. 40 | 41 | Poznámky: 42 | 43 | - Pro udržení délky textu na jednu stranu, obsah je implicitně obsažen v odkazech. Jste dostatečně inteligentní aby jste si vyhledali více detailů z jiných zdrojů jakmile znáte příkaz či myšlenku na Googlu. Použijte `apt-get`, `yum`, `dnf`, `pacman`, `pip` nebo `brew` podle distribuce k instalaci nových progamů. 44 | - Použijte [Explainshell](http://explainshell.com/) pro užitečné vysvětlení co příkazy, možnosti, roury a jiné dělají. 45 | 46 | 47 | ## Základy 48 | 49 | - Naučte se základy Bashe. Vlastně, napište `man bash` a alespoň si to proleťte; je to celkem jednoduché a ne tak dlouhé. Jiné shelly mohou být dobré, ale Bash je mocný a vždy dostupný (znalost *pouze* zsh, fish a jiných ačkoli lákavá na vlastním notebooku omezuje v mnoha situacích, jako například při použití existujících serverů). 50 | 51 | - Poznejte alespoň jeden textový editor dobře. Nejlépe Vim (`vi`) jelikož opravdu nemá pro občasné úpravy v terminálu nemá konkurenci (ani pokud většinu času používáte Emacs, velké IDE nebo moderní okenní editor). 52 | 53 | - Naučte se číst dokumentaci pomocí `man` (pro zvědavce, `man man` vypíše čísla sekcí, například 1 jsou "obvyklé" příkazy, 5 jsou soubory/konvence a 8 je administrace). Hledejte manuálové stránky pomocí `apropos`. Vězte, že některé příkazy nejsou spustitelné programy, ale funkce zabudované v Bashi a nápovědu k nim můžete zobrazit příkazem `help` a `help-d`. 54 | 55 | - Naučte se přesměrování výstupu a vstupu pomocí `>` a `<` a roury pomocí `|`. Pamatujte, že `>` přepíše obsah výstupního souboru a `>>` přidá na jeho konec. Nezapomeňte na stdout (stndardní výstup) a stderr (standardní chybový výstup). 56 | 57 | - Poznejte souborovou hromadnou expanzi za pomoci `*` (případně `?` a `[`...`]`) a úvozovkách a rozdílu mezi dvojitými uvozovkami `"` a jednoduchými `'`. (Více na expanzi proměných níže.) 58 | 59 | - Seznamte se se správou činností v Bashi: `&`, **ctrl-z**, ctrl-c**, `jobs`, `fg`, `bg`, `kill`, atd. 60 | 61 | - Seznamte se s `ssh` a základy bezheslové autentizace pomocí `ssh-agent`, `ssh-add`, atd. 62 | 63 | - Základní správa souborů: `ls` a `ls -l` (zejména co který sloupec v `ls -l` znamená), `less`, `head`, `tail` a `tail -f` (nebo ještě lépe `less +F`), `ln` a `ln -s` (pochopte rozdíly a výhody pevného odkazu a symoblického odkazu), `chown`, `chmod`, `du` (pro krátký souhrn využití disku: `du -hs *`). Pro správu souborového systému, `df`, `mount`, `fdisk`, `mkfs`, `lsblk`. Pochopte co je inode (`ls -i` nebo `df -i`). 64 | 65 | - základní správa síťí: `ip` nebo `ifconfig`, `dig`. 66 | 67 | - Dobře se naučte regulárních výrazů a rozličné příznaky pro `grep`/`egrep`. Přepínače `-i`, `-o`, `-v`, `-A`, `-B` a `-C` je také vhodné znát. 68 | 69 | - Naučte se používat `apt-get`, `yum`, `dnf` nebo `pacman` (podle vaší distribuce) k hledání a instalaci balíků. A ujistěte se, že máte `pip` k instalace Pythonových terminálových nástrojů (některé je nejjednodušší nainstalovat pomocí `pip`). 70 | 71 | 72 | ## Každodenní použití 73 | 74 | - V Bashi používejte **Tab** k dokončení argumentů nebo vylistování všech dostupných příkazů a **ctrl-r** k vyhledávání v historii příkazů (po stisknutí pište pro hledání a poté mačkejte opakovaně **ctrl-r** k procházení více shod, **Enter** k provedení nalezeného příkazu nebo šipku vpravo pro vložení výsledku hledání do terminálu a následnou editaci). 75 | 76 | - V Bashi používejte **ctrl-w** pro smazní posledního slova a **ctrl-u** pro smazání všeho od současné pozice kurzoru až po začátek řádku. Používejte **alt-b** a **alt-f** k procházení řádku po slovech, **ctrl-a** pro skok na začátek řádku, **ctrl-e** pro skok kurzoru na konec řádku, **ctrl-k** pro smazání všeho od současné pozice až ke konci řádku, **ctrl-l** pro vyčištění obrazovky. Prohlédněte si `man readline` pro všechny defaultní klávesové zkratky v Bashi. Je jich hodně. Například **alt-.** projíždí předchozí argumenty a **alt-*** rozšíří řetězec. 77 | 78 | - Pokud milujete klávesové zkratky ve stylu *vi*, použijte `set -o vi` (a `set -o emacs` pro návrat ke standardnímu rozložení). 79 | 80 | - Pro úpravu dlouhých příkazů, po nastavení vašeho editoru (například `export EDITOR=vim`), **ctrl-x** **ctrl-e** v něm otevře stávající příkaz pro víceřádkovou úpravu. Nebo ve *vi* stylu, **escape-v**. 81 | 82 | - Zobrazení nedávných příkazů se provádí pomocí `history`. Existuje spousta zkratek jako `!$` (poslední argument) a `!!` (poslední příkaz), ale tyto jsou jednoduše nahraditelné pomocí **ctrl-r** a **alt-.**. 83 | 84 | - Pro přechod do předchozího pracovního adresáře: `cd -`. 85 | 86 | - Pokud máte zpola napsaný příkaz, ale rozmyslíte si to, stiskněte **alt-#** pro přidání `#` na začátek řádku a vložte ho jako komentář (nebo použijte **ctrl-a**, **#**, **enter**). Takto se k němu můžete později vrátit v historii příkazů. 87 | 88 | - Používejte `xargs` (nebo `parallel`). Jde o mocný příkaz. Nezapomeňte, že můžete ovládat kolik položek se má vykonat na řádku (`-L`) stejně jako paralelismus (`-P`). Pokud si nejste jisti zda to udělá co má, zkuste nejdříve `xargs echo`. Hodí se také `-I{}`. 89 | Příklady: 90 | ```bash 91 | find . -name '*.py' | xargs grep nejaka_funkce 92 | cat hosts | xargs -I{} ssh root@{} hostname 93 | ``` 94 | 95 | - `pstree -p` je užitečné zobrazení stromu procesů. 96 | 97 | - Používejte `pgrep` a `pkill` k hledání nebo posílání signálů procesům podle jména. (`-f` je také užitečné). 98 | 99 | - Pamatujte si rozličné signály, které lze posílat procesům. Například, k pozastavení procesu, použijte `kill -STOP [pid]`. Celý seznam signálů v `man 7 signal`. 100 | 101 | - Používejte `nohup` nebo `disown` pokud chcete, aby proces na pozadí běžel navždy. 102 | 103 | - Kontrolujte, které procesy naslouchají pomocí `netstat -lntp` nebo `ss -plat` (pro TCP; přidejte `-u` pro UDP). 104 | 105 | - Podívejte se také na `lsof` pro otevřené sockety a soubory. 106 | 107 | - Jak dlouho systém běží poznáte díky `uptime` nebo `w`. 108 | 109 | - Pomocí `alias` si nastavte zkratky pro často používané příkazy. Například `alias ll='ls -latr'` vytvoří novou zkratku `ll`. 110 | 111 | - V Bashových scriptech používejte `set -x` (nebo jeho variantu `set -v`, která zaznamenává nezpracovaný vstup včetně nečekaných proměnných a komentářů) pro ladící výstup. Používejte striktní módy pokud nemáte dobrý důvod proč to tak nedělat: Příkazem `set -e` nastavíte přerušení při chybě (nenulový návratový kód). Použijte `set -u` pro zjištění použití neinicializovaných proměnných. Zvažte také `set -o pipefail` pro chyby v rourách (přečtěte si na tohle téma více pokud tuto možnost využijete, jelikož jde o citlivé téma). Pro více zapojených scriptů použijte `trap` na EXIT nebo ERR. Dobrým zvykem bývá začínat scripty takto, což zachytí a ukončí běh na běžných chybách a vypíše zprávu: 112 | ```bash 113 | set -euo pipefail 114 | trap "echo 'error: Script selhal: neuspesny prikaz vyse'" ERR 115 | ``` 116 | 117 | - V Bash scriptech jsou subshelly (psané s kulatými závorkami) vhodným způsobem shlukování příkazů. Běžným příkladem budiž dočasný přesun do jiného pracovního adresáře, například: 118 | ```bash 119 | # udelej neco v soucasnem pracovnim adresari 120 | (cd /nejaky/jiny/adresar && jiny-prikaz) 121 | # pokracuj v puvodnim adresari 122 | ``` 123 | 124 | - Nezapomeňte, že v Bashi je mnoho druhů expanze proměnných. KOntrola, že proměnná existuje `${jmeno:?chybova hlaska}`. například, pokud script vyžaduje jediný argument, napište `vstupni_soubor=${1:?pouziti: $0 vstupni_soubor}`. Aritmetická expanze: `i=$(( (i + 1) % 5 ))`. Sekvence: `{1..10}`. Ořezání (trimming) řetězců: `${var%suffix}` a `${var#prefix}`. Pokud například `var=foo.pdf`, pak `echo ${var%.pdf}.txt` zobrazí `foo.txt`. 125 | 126 | - Expanze složených závorek použitím `{`...`}` může snížit potřebu přepisovat podobné texty a zautomatizovat kombinaci položek. Toto může být užitečné například v `mv foo.{txt,pdf} nejaky-adresar` (což přesune oba soubory), `cp nejakysoubor{,.bak}` (což se rozšíří do `cp nejakysoubor nejakysoubor.bak`) nebo `mkdir -p test-{a,b,c}/subtest-{1,2,3}` (což se rozšíří do všech možných kombinací a vytvoří příslušný adresářový strom). 127 | 128 | - S výstupem některých příkazů lze zacházet jako se souborem pomocí `<(nejaky prikaz)`. Například porovnání lokálního `/etc/hosts` se vzdáleným: 129 | ```sh 130 | diff /etc/hosts <(ssh nejakyhost cat /etc/hosts) 131 | ``` 132 | 133 | - Poznejte "zdejší dokumenty" v Bashi, míněno `cat < logsoubor 2>&1` nebo `nejaky-prikaz &>logsoubor`. Častokrát, k zajištění, že příkaz nezanechá otevřený souborový držák (handle), navázání ho na terminál ve kterém jste, je dobrá praktika také přidat ` bar: 213 | repren --full --preserve-case --from foo --to bar . 214 | # Obnov zalozni soubory cokoliv.bak -> cokoli: 215 | repren --renames --from '(.*)\.bak' --to '\1' *.bak 216 | # Stejne jako vyse za pouziti jmena pokud mozne: 217 | rename 's/\.bak$//' *.bak 218 | ``` 219 | 220 | - Jak říká manuálová stránka, `rsync` je skutečně rychlý a neobyčejně univerzální nástroj na kopírování souborů. Je znám pro synchronizaci mezi stroji, ale je stejně užitečný lokálně. Jde také o jednu z [nejrychlejších cest](https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html) k odstranění velkého množství souborů: 221 | ```sh 222 | mkdir prazdny && rsync -r --delete prazdny/ nejaky-adr && rmdir nejaky-adr 223 | ``` 224 | 225 | - Použijte `shuf` k zamíchání nebo vybrání náhodných řádek ze souboru. 226 | 227 | - Mějte přehled v `sort` možnostech. Pro čísla, použijte `-n` nebo `-h` pro práci s lidsky čitelnými čísly (například z `du -h`). Pochopte jak fungují klíče (`-t` a `-k`). Zejména mějte na paměti, že musíte psát `-k,1` pro třídění za použití pouze prvního pole; `-k1` znamená třídění podle celého řádku. Stabilní třídění (`sort -s`) může být užitečné. Například k setřídění primárně podle druhého pole a sekundárně podle druhého pole můžete použít `sort -k1,1 | sort -s -k2,2`. 228 | 229 | - Pokud někdy potřebujete zapsat znak tabulátor do příkazové řádky v Bashi (například pro -t argument pro třídění), stiskněte press **ctrl-v** **[Tab]** nebo napište $'\t'` (druhá možnost je lepší, protože výsledek můžete zkopírovat/vložit). 230 | 231 | - Standardní nástroje pro porovnávání zdrojového kódu jsou `diff` a `patch`. Za zmínku stojí také `diffstat` zobrazující statistiky z diffu a `sdiff` pro rozdíly bok po boku. Nezapomeňte, že `diff -r` funguje pro celé adresáře. Použijte `diff -r strom1 strom2 | diffstat` pro shrnutí změn. A `vimdiff` pro porovnání a úpravu souborů. 232 | 233 | - Pro binární soubory použijte `hd`, `hexdump` nebo `xxd` pro jednoduché hex dumpy a `bvi` nebo `biew` pro editaci binárek. 234 | 235 | - Pro binární soubory můžete také použít `strings` (například spolu s `grep`, atd), což je nástroj pro hledání částí textu. 236 | 237 | - Pro binární rozdíly (delta komprese) použijte `xdelta3`. 238 | 239 | - Pro konverzi testových kódování zkuste `iconv`. Nebo `uconv` pro pokročilejší použití; podporuje některé pokročilé Unicode věci. Například tento příkaz mění text na malé znaky a odstraňuje akcenty (jejich rozvinutím a zahozením): 240 | ```sh 241 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt 242 | ``` 243 | 244 | - Na rozdělení souborů do částí zkuste `split` (na rozdělení podle velikosti) a `csplit` (na rozdělení podle řetězce). 245 | 246 | - K manipulaci s datem a časem použijte `dateadd`, `datediff`, `strptime` atd. z [`dateutils`](http://www.fresse.org/dateutils/). 247 | 248 | - Použijte `zless`, `zmore`, `zcat`, a `zgrep` k operacím s komprimovanými soubory. 249 | 250 | 251 | ## Ladění systému 252 | 253 | - Pro webové ladění jsou vhodné `curl` a `curl /I` nebo jejich `wget` ekvivalenty nebo více moderní [`httpie`](https://github.com/jkbrzt/httpie). 254 | 255 | - Pro zjištění současného procesorového/diskového stavu, klasické nástroje jako `top` (nebo lépe `htop`). Použijte `iostat -mxz 15` pro základní CPU a detailní diskové stavy pro každý diskový oddíl a výkonostní statistiky. 256 | 257 | - Pro detaily ohledně síťové konektivity použijte `netstat` a `ss`. 258 | 259 | - Rychlý přehled co se děje v systému získáte pomocí užitečného `dstat`. Pro širší přehled s detaily použijte [`glances`](https://github.com/nicolargo/glances). 260 | 261 | - Na zjištění stavu paměti spusťte `free` a `vmstat` a pokuste se porozumět jejich výstupům. Zejména dbejte na "cached" hodnotu což je paměť držená Linuxovým kernelem jako souborová cache, tudíž se počítá do "volné" paměťi. 262 | 263 | - Ladění Javy je odlišný šálek čaje, ale jednoduchý trik na Javu od Oraclu a některé jiné JVM je, že stále můžete použít `kill -3 ` a výpis zásobníku a haldy (včetně obecnějších detailů z **garbage collectoru**, které mohou být nesmírně informativní) bude zapsán do stderr/logs. Nástroje JDK jako `jps`, `jstat`, `jstack` a `jmap` jsou také užitečné, avšak [SJK tools](https://github.com/aragozin/jvm-tools) jsou více pokročilé. 264 | 265 | - Použijte [`mtr`](http://www.bitwizard.nl/mtr/) jako lepší `traceroute` pro identifikování potíží se sítí. 266 | 267 | - Při zjištování proč je disk plný, [`ncdu`](https://dev.yorhel.nl/ncdu) šetří čas oproti obvyklým příkazům jako `du /sh *`. 268 | 269 | - Ke zjištění, který socket nebo proces zahlcuje pásmo, zkuste [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) nebo [`nethogs`](https://github.com/raboof/nethogs). 270 | 271 | - Nástroj `ab` (přibalený k Apachi) je užitečný pro rychlé a hrubé zkontrolování výkonosti webového serveru. Komplexnější měření umožňuje `siege`. 272 | 273 | - Pro důslednější síťové ladění, [`wireshark`](https://wireshark.org/), [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html) nebo [`ngrep`](http://ngrep.sourceforge.net/) jsou to pravé. 274 | 275 | - Nezapomínejte na `strace` a `ltrace`. Mohou být nápomocné zejména pokud některý program selhává, zasekává se nebo padá a nevíte proč nebo pokud chcete mít obecnou představu o výkonu. Myslete na přepínač profilingu (`-c`) a schopnost připnout se k běžícímu procesu (`-p`). 276 | 277 | - Dynamické knihovny vám umožní zkontrolovat `ldd`. 278 | 279 | - Je důležité umět se připojit k běžícímu procesu za pomoci `gdb` a získat výpis jeho chodu. 280 | 281 | - Používejte `/proc`. Je úžasně nápomocný v okamžicích, kdy ladíte živé problémy. Příklady: /proc/cpuinfo`, `/proc/meminfo`, `/proc/cmdline`, `/proc/xxx/cwd`, `/proc/xxx/exe`, `/proc/xxx/fd/`, `/proc/xxx/smaps` (kde `xxx` je id nebo pid procesu.). 282 | 283 | - Když zjišťujete proč se něco v minulosti pokazilo, [`sar`](http://sebastien.godard.pagesperso-orange.fr/) může být nedocenitelný. Ukazuje historické statistiky CPU, paměti, sítě, atd. 284 | 285 | - Pro hlubší systémovou a výkonostní analýzu se podívejte na `stap`([SystemTap](https://sourceware.org/systemtap/wiki)), [`perf`](https://en.wikipedia.org/wiki/Perf_(Linux)), a [`sysdig`](https://github.com/draios/sysdig). 286 | 287 | - Zkontrolujte na jakém jste OS za pomoci `uname` nebo `uname -a` (obecné Unix/kernel informace) nebo `lsb_release -a` (v Linuxových distribucích). 288 | 289 | - Použijte `dmesg` kdykoli se něco chová neočekávaně (může jít o hardwarový nebo driverový problém). 290 | 291 | 292 | ## Jednořádkové příkazy 293 | 294 | Pár příkladů na spojování příkazů: 295 | 296 | - Někdy je pozoruhodně užitečné dělat průnik, sjednocení a rozdíl textových souborů pomocí `sort`/`uniq`. Předpokládejte, že `a` a `b` jsou unikátní textové soubory. Toto je rychlé a funguje na souborech libovolné velikosti až do mnoha gigabytů. (Třídění pomocí `sort` není omezené pamětí, ale je možné, že budete muset použít `-T` přepínač, pokud se `/tmp` nachází na malém diskovém oddílu). Podívejte se také na poznámku o LC_ALL výše a přepínač `sortu` `-u` (vynechaný pro přehlednost). 297 | ```sh 298 | cat a b | sort | uniq > c # c je sjednocení b 299 | cat a b | sort | uniq -d > c # c je průnik b 300 | cat a b b | sort | uniq -u > c # c je rozdíl a - b 301 | ``` 302 | 303 | - Použijte `grep .*` pro rychlé prošetření obsahu všech souborů v adresáři (každý soubor je spojen s názvem souboru) nebo `head -100 *` (aby každý soubor měl záhlaví). Může být užitečné pro adresáře s konfiguračními soubory jako jsou například `/sys`, `/proc` a `/etc`. 304 | 305 | - Součet všech čísel ve třetím sloupci textového souboru (pravděpodobně 3x rychlejší a 3x méně kódu než ekvivalentní funkce v Pythonu): 306 | ```sh 307 | awk '{ x += $3 } END { print x }' mujsoubor 308 | ``` 309 | 310 | - Pokud chcete zobrazit velikosti/datumy na souborovém stromu, následující příkaz je jako rekurzivní `ls -l`, ale jedodušší na čtení než `ls -lR`: 311 | ```sh 312 | find . -type f -ls 313 | ``` 314 | 315 | - Řekněme, že máte textový soubor, jako log webového serveru, a jisté hodnoty, které se objevují na některých řádcích, jako například `acct_id` parametr, který se vyskytuje v URL. Pokud chcete záznam kolik požadavků pro každý `acct_id`: 316 | ```sh 317 | cat access.log | egrep -o 'acct_id=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -rn 318 | ``` 319 | 320 | - K průběžnému monitorování změn použijte `watch`, například změn souborů v adresáři pomocí `watch -d -n 2 'ls -rth | tail'` nebo síťových nastavení při řešení potíží nastavení wifi: `watch -d -n 2 ifconfig`. 321 | 322 | - Spusťte tuto funkci k získání náhodného tipu z tohoto dokumentu (parsuje Markdown a vyextrahuje jednu položku): 323 | ```sh 324 | function taocl() { 325 | curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md | 326 | pandoc -f markdown -t html | 327 | xmlstarlet fo --html --dropdtd | 328 | xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 329 | xmlstarlet unesc | fmt -80 330 | } 331 | ``` 332 | 333 | ## Neobvyklé ale užitečné 334 | 335 | - `expr`: provede aritmetické nebo logické operace nebo vyhodnotí regulární výrazy 336 | 337 | - `m4`: jednoduchý procesor maker 338 | 339 | - `yes`: tiskne řetězec vícekrát 340 | 341 | - `cal`: hezký kalendář 342 | 343 | - `env`: provede příkaz (užitečné ve scriptech) 344 | 345 | - `printenv`: vypíše proměnné prostředí (užitečné při ladění a ve scriptech) 346 | 347 | - `look`: najde anglická slova (nebo řádky v souboru) začínající řetězcem 348 | 349 | - `cut`, `paste` a `join`: manipulace s daty 350 | 351 | - `fmt`: formátuje text do odstavců 352 | 353 | - `pr`: formátuje text do stránek/sloupců 354 | 355 | - `fold`: zalamuje řádky textu 356 | 357 | - `column`: formátuje textová pole do zarovnaných sloupců nebo tabulek s danou šířkou 358 | 359 | - `expand` a `unexpand`: převádí tabulátory a mezery 360 | 361 | - `nl`: přidá čísla řádků 362 | 363 | - `seq`: tiskne čísla 364 | 365 | - `bc`: kalkulačka 366 | 367 | - `factor`: provádí faktorizaci celých čísel (15 = 5 a 3) 368 | 369 | - [`gpg`](https://gnupg.org/): šifruje a podepisuje soubory 370 | 371 | - `toe`: tabulka informací o dostupných terminálech 372 | 373 | - `nc`: síťové ladění a přenos dat 374 | 375 | - `socat`: socketové relé a tcp port přesměrování (podobné `netcat`) 376 | 377 | - [`slurm`](https://github.com/mattthias/slurm): visualizace síťového provozu 378 | 379 | - `dd`: přesun dat mezi soubory nebo zařízeními 380 | 381 | - `file`: identifikuje typ souboru 382 | 383 | - `tree`: zobrazí adresáře a podadresáře jako vnořený strom; podobně jako `ls` ale rekurzivně 384 | 385 | - `stat`: informace o souboru 386 | 387 | - `time`: provede a načasuje příkaz 388 | 389 | - `timeout`: provádí příkaz po specifikovanou dobu a zastaví proces když daná doba uplyne 390 | 391 | - `lockfile`: vytvoří semaforový soubor, který lze odstranit pouze pomocí `rm -f` 392 | 393 | - `logrotate`: rotuje, komprimuje a posílá logy emailem 394 | 395 | - `watch`: spouští opakovaně příkaz a zobrazuje výsledky a/nebo zvýrazňuje změny 396 | 397 | - `tac`: tiskne soubory pozpátku (po řádcích) 398 | 399 | - `shuf`: náhodně vybere řádky ze souboru 400 | 401 | - `comm`: porovná seřazení soubory řádek po řádku 402 | 403 | - `pv`: monitoruje postup dat skrz rouru 404 | 405 | - `hd`, `hexdump`, `xxd`, `biew` a `bvi`: vypíše nebo edituje binární soubory 406 | 407 | - `strings`: vypreparuje textové řetězce z binárních souborů 408 | 409 | - `tr`: překládá znaky nebo s nimi manipuluje 410 | 411 | - `iconv` nebo `uconv`: převod pro kódování textu 412 | 413 | - `split` a `csplit`: dělí soubory 414 | 415 | - `sponge`: čte všechen vstup před tím než ho zapíše, užitečné pro čtení a následný zápis do téhož souboru, např. `grep -v neco nejaky-soubor | sponge nejaky-soubor` 416 | 417 | - `units`: převody jednotek a výpočty; převádí jednotky mezi sebou, (viz. `/usr/share/units/definitions.units`) 418 | 419 | - `apg`: generuje náhodná hesla 420 | 421 | - `7z`: vysoko-poměrová datová komprese 422 | 423 | - `ldd`: informace o dynamických knihovnách 424 | 425 | - `nm`: vypíše symboly z objektových souborů 426 | 427 | - `ab`: zátěžové testy webserverů 428 | 429 | - `strace`: ladění systému 430 | 431 | - [`mtr`](http://www.bitwizard.nl/mtr/): vylepšení traceroute pro síťové ladění 432 | 433 | - `cssh`: vizuální souběžný shell 434 | 435 | - `rsync`: synchronizuje soubory a adresáře přes SSH nebo v lokálním systému souborů 436 | 437 | - [`wireshark`](https://wireshark.org/) a [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html): zachytávání packetů a síťové ladění 438 | 439 | - [`ngrep`](http://ngrep.sourceforge.net/): grep pro síťovou vrstvu 440 | 441 | - `host` a `dig`: DNS vyhledávání 442 | 443 | - `lsof`: zpracovává souborové popisovače (descriptory) a informace o socketech 444 | 445 | - `dstat`: užitečné systémové informace 446 | 447 | - [`glances`](https://github.com/nicolargo/glances): vysoko úrovňový, multi-systémový přehled 448 | 449 | - `iostat`: statistiky využití disku 450 | 451 | - `mpstat`: statistiky využití CPU 452 | 453 | - `vmstat`: statistiky využití paměti 454 | 455 | - `htop`: vylepšená verze top (správa procesů) 456 | 457 | - `last`: historie přihlášení 458 | 459 | - `w`: kdo je přihlášen 460 | 461 | - `id`: informace o identitě uživatele/skupiny 462 | 463 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/): historické systémové statistiky 464 | 465 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) nebo [`nethogs`](https://github.com/raboof/nethogs): využití sítě pro proces nebo socket 466 | 467 | - `ss`: statistika socketů 468 | 469 | - `dmesg`: bootovací a systémové chybové zprávy 470 | 471 | - `sysctl`: zobrazení a konfigurace parametrů Linuxového kernelu za běhu 472 | 473 | - `hdparm`: SATA/ATA disková manipulace/výkon 474 | 475 | - `lsblk`: seznam blokových zařízení: stromové zobrazení disků a diskových oddílů 476 | 477 | - `lshw`, `lscpu`, `lspci`, `lsusb`, `dmidecode`: informace o hardwaru zahrnující CPU, BIOS, RAID, grafiku, zařízení, atd. 478 | 479 | - `lsmod` a `modinfo`: seznam a detaily kernelových modulů 480 | 481 | - `fortune`, `ddate`, a `sl`: hm, no, záleží jestli považujete parní lokomotivy a Zippyho citáty za "užitečné" 482 | 483 | 484 | ## Pouze pro OS X 485 | 486 | Tyto věci jsou relevantní pouze pro macOS. 487 | 488 | - Balíčky spravované pomocí `brew` (Homebrew) a/nebo `port` (MacPorts). Mohou být použity k instalaci mnoha předešlých příkazů na macOS. 489 | 490 | - Kopírujte výstup jakéhokoli příkazu do desktopové aplikace pomocí `pbcopy` a vložte vstup z nějaké pomocí `pbpaste`. 491 | 492 | - K povolení klávesy Option v Terminálu Mac OS jako klávesu Alt (pro použití v příkazech jako **alt-b**, **alt-f**, atd.), otevřete Předvolby -> Profily -> Klávesnice a zvolte "Použít Option jako Meta klávesu". 493 | 494 | - K otevření souboru za pomoci desktopové aplikace použijte `open` nebo `open -a /Aplikace/Cokoli.app`. 495 | 496 | - Spotlight: Prohledávejte soubory s `mdfind` a vypište metadata (například EXIF informace fotografie) pomocí `mdls`. 497 | 498 | - Nezapomínejte, že macOS je založen na BSD Unixu a mnoho příkazů (například `ps`, `ls`, `tail`, `awk`, `sed`) mají spoustu jemných odlišností od Linuxu, což je z velké části ovlivněno System V (System Five) stylem Unixu a GNU nástroji. Mnohokrát mmůžete rozdíl poznat podle manuálové stránky mající v nadpise "BSD General Commands Manual". V některých případech mohou být GNU verze instalovány také (třeba `gawk` a `gsed` pro GNU awk a sed). Pokud píšete multi-platformní Bashové scripty, vyhýbejte se takovým příkazům (například, zvažte Python či `perl`) nebo pečlivě testujte. 499 | 500 | - K získání informací o verzi vydání macOS použijte `sw_vers`. 501 | 502 | 503 | ## Další zdroje 504 | 505 | - [awesome-shell](https://github.com/alebcay/awesome-shell): Organizovaný seznam shellových nástrojů a zdrojů. 506 | - [awesome-osx-command-line](https://github.com/herrbischoff/awesome-osx-command-line): Průvodce Mac OS příkazovou řádkou více do hloubky. 507 | - [Striktní mód](http://redsymbol.net/articles/unofficial-bash-strict-mode/) pro psaní lepších shellových scriptů. 508 | - [shellcheck](https://github.com/koalaman/shellcheck): Nástroj pro statickou analýzu shellových scriptů. V podstatě lint pro bash/sh/zsh. 509 | - [Souborové názvy a cesty v shellu](http://www.dwheeler.com/essays/filenames-in-shell.html): Bohužel velmi komplexní drobnosti o korektní práci se souborovými jmény v shellových scriptech. 510 | 511 | 512 | ## Zřeknutí se odpovědnosti 513 | 514 | S vyjímkou velmi malých úkolů je kód psán tak, aby ho ostatní mohli přečíst. S mocí přichází zodpovědnost. Skutečnost, že něco *můžete* v Bashi udělat nemusí nutně znamenat, že byste měli! ;) 515 | 516 | 517 | ## License 518 | 519 | [![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 520 | 521 | Tato práce je licencována pod [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). 522 | -------------------------------------------------------------------------------- /README-ja.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | # The Art of Command Line 5 | 6 | [![質問してみよう](https://img.shields.io/badge/%3f-Ask%20a%20Question-ff69b4.svg)](https://airtable.com/shrzMhx00YiIVAWJg) 7 | 8 | [![https://gitter.im/jlevy/the-art-of-command-lineでチャットに参加しよう](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 9 | 10 | - [メタ情報](#メタ情報) 11 | - [基本](#基本) 12 | - [日常的に使うもの](#日常的に使うもの) 13 | - [ファイルとデータの処理](#ファイルとデータの処理) 14 | - [システムのデバッグ](#システムのデバッグ) 15 | - [ワンライナー](#ワンライナー) 16 | - [目立たないが便利なもの](#目立たないが便利なもの) 17 | - [OS X用のもの](#os-x用のもの) 18 | - [Windows専用](#windows専用) 19 | - [さらなるリソース](#さらなるリソース) 20 | - [免責事項](#免責事項) 21 | 22 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 23 | 24 | コマンドラインで流れるように操作ができるということは、軽く見られたり他人から理解されないスキルだとみなされることもあるだろう。しかしそのスキルは、明らかにかすぐ分かるようかは問わず、エンジニアとしてのあなたの柔軟性や生産性を改善してくれるものだ。ここでは、Linuxでコマンドラインを使う上で便利だと思ったメモやTipsの数々を挙げてみる。あるものは基礎的だが、非常に詳しいもの、洗練されたもの、曖昧なものもある。このページはそんなに長いものではないが、ここに書いてあることの全てを使ったり思い出すことができれば、かなり詳しくなれるだろう。 25 | 26 | このドキュメントは[多くの執筆者と翻訳者](AUTHORS.md)による成果である。 27 | ここに書いてあることの多くは、[元々](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands)[Quora](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know)に[書かれて](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix)いたものが多いが、より優れた人たちがすぐに改善案を出すことができるGitHubに置くのがよいのではと思った。 28 | コマンドラインについて疑問があるなら[**質問してみよう**](https://airtable.com/shrzMhx00YiIVAWJg) エラーや改善点を見つけたら[**貢献してみよう**](/CONTRIBUTING.md)! 29 | 30 | ## メタ情報 31 | 32 | 対象 : 33 | 34 | - このガイドは、初心者向けでも経験者向きでもある。幅広く(書いてあることは全て重要)、かつ明確で(多くのケースに対して具体的な例を付ける)、そして簡潔(他の場所で見つけられるような重要でないことや脱線したことは省く)であることをゴールにしている。各項目は、多くの場面において必須であるか、他の方法に比べて劇的に時間を節約してくれるだろう。 35 | - [OS X用のもの](#os-x-only)を除き、Linux向けの内容となっており、その多くは各種LinuxおよびMacOS(あるいはCygwin)でも使えるだろう。 36 | - インタラクティブなBashを使うことを想定しているが、多くの項目は他のシェルやBashのスクリプトでも使えるだろう。 37 | - (このリポジトリへ)組み込むメリットがあるのであれば、標準Unixコマンドやパッケージインストールコマンドも含める。 38 | 39 | 注意 : 40 | 41 | - 1ページ内に収めるために、内容には暗黙的に書かれていることがある。ここで取りかかりを知ったりコマンドが分かれば、詳細をどこかで調べたりするくらいはできるだろう。新しいプログラムをインストールするには、`apt-get`、`yum`、`dnf`、`pacman`、`pip`、`brew`(どれか適したもの)を使おう。 42 | - コマンドやオプション、パイプを分解して理解する手助けに、[Explainshell](http://explainshell.com/)を使おう。 43 | 44 | ## 基本 45 | 46 | - 基本的なBashを学ぼう。実際のところ、`man bash`は結構簡単に理解できるしそんなに長くないので、これで一通りのことは分かる。それ以外のシェルもよいが、Bashは強力だし、常に使用可能であるという利点もある(自分のPCに入れてしまったと言ってzshやfishなど*だけ*を学んでしまうと、既存のサーバを触らなくてはならない時などに制約が出てしまう)。 47 | 48 | - テキストエディタのどれか最低1つに習熟しよう。`nano`エディタは編集の基本操作(開く、修正する、保存する、検索する)を学ぶ最もシンプルな方法のひとつだ。ターミナル内で適当にものを書くにあたって他に全く代替品がないという点で、理想的にはVim(`vi`)がよいだろう(通常はEmacsや高機能なIDEや最新のかっこいいエディタをメインに使っていたとしても)。 49 | 50 | - `man`でのドキュメントの読み方を知ろう(知りたがりのために書くと、`man man`でセクション番号が分かる。例えば1は「一般的な」コマンド、5はファイルやそのお作法、8は管理についてといった具合)。`apropos`でmanページを探そう。コマンドによっては実行可能ファイルではなくBashのビルトインコマンドであることを理解し、`help`や`help -d`でヘルプが見られることを知ろう。 51 | 52 | - `>`や`<`、`|`を使ったパイプによる入出力のリダイレクションを学ぼう。`>`は出力ファイルを上書き、`>>`は追記となる。stdout(標準出力)とstderr(標準エラー出力)を学ぼう。 53 | 54 | - `*`(または`?`や`[`...`]`)を使ったファイルグロブ展開、クォーテーション、ダブルクォート`"`とシングルクォート`'`の違いを学ぼう(詳しくはこの後の変数展開の項を参照)。 55 | 56 | - `&`、**ctrl-z**、**ctrl-c**、`jobs`、`fg`、`bg`、`kill`など、Bashのジョブ管理について詳しくなろう。 57 | 58 | - `ssh`について知るとともに、`ssh-agent`や`ssh-add`を使ったパスワードなしの認証の基本について理解しよう。 59 | 60 | - ファイル管理について。`ls`や`ls -l`(特に、`ls -l`の各列が何を意味するか理解)、`less`、`head`、`tail`、`tail -f`(または`less +F`)、`ln`と`ln -s`(ハードリンクとソフトリンクの違いとそれぞれの利点の理解)、`chown`と`chmod`、`du`(ディスク使用量まとめを簡単に見るなら`du -hs *`)。ファイルシステム管理については、`df`、`mount`、`fdisk`、`mkfs`、`lsblk`。inodeについては、`ls -i`(または `df -i`)。 61 | 62 | - 基本的なネットワーク管理について。`ip`あるいは`ifconfig`、`dig`、`traceroute`、 `route`。 63 | 64 | - `git`のようなバージョン管理システムを学んで使ってみよう。 65 | 66 | - 正規表現について詳しく知ろう。`grep`や`egrep`の色々なフラグも合わせて。`-i`、`-o`、`-v`、`-A`、`-B`、`-C`といったオプションは知っておいて損はない。 67 | 68 | - `apt-get`、`yum`、`dnf`、`pacman`(ディストリビューションによって違う)といったコマンドでパッケージを探したりインストールする方法を学ぼう。Pythonベースのコマンドラインツールをインストールするのに、`pip`も必要だ(後に出てくるいくつかのコマンドは`pip`でインストールするのが一番簡単)。 69 | 70 | 71 | ## 日常的に使うもの 72 | 73 | - Bashでは、引数を補完、または利用可能なコマンドを列挙するのに**タブ**を使い、コマンド履歴から検索するのに**ctrl-r**を使う。(検索キーを入力した後、**ctrl-r**を繰り返し入力することで次から次へと検索結果を送ることができる。**Enter**で見つかったコマンドの実行となり、**Enter**ではなく右カーソルキーを押した場合は見つかったコマンドが入力された状態になる。) 74 | 75 | - Bashでは、最後の単語を削除するのには**ctrl-w**、行頭まで全て削除するには**ctrl-u**を使う。単語ごとに移動するには**alt-b**または**alt-f**、行頭に移動するには**ctrl-a**、行末に移動するには**ctrl-e**、行末まで削除するには**ctrl-k**、画面のクリアは**ctrl-l**である。Bashにおけるデフォルトのキー割り当てを全て見るには`man readline`を参照。たくさん出てくる。例えば、**alt-.**は前の引数を順番に表示し、**alt-***はグロブを展開する。 76 | 77 | - vi風のキー割り当てが好きなら、`set -o vi`を実行しよう。(元に戻したいときは`set -o emacs`) 78 | 79 | - 長いコマンドを編集するときに、エディタを設定した後で(例えば`export EDITOR=vim`)、**ctrl-x** **ctrl-e**によって編集中のコマンドが複数行の編集のために指定したエディタで開かれる。vi風の場合は、**escape-v**。 80 | 81 | - 最近実行したコマンドを確認するなら`history`。`!n`と続けることで(nはコマンド横に表示される数字)再度実行できる。**ctrl-r**や**alt-.**で用は足りるだろうが、`!$`(直前の引数)や`!!`(直前のコマンド)といった省略形もたくさんある。 82 | 83 | - `cd`でホームディレクトリへの移動。ホームディレクトリに関連するファイルにアクセスする場合はプレフィックス`~`をつける(例: `~/.bashrc`)。`sh`スクリプトの中では`$HOME`でホームディレクトリを表すことができる。 84 | 85 | - 前のワーキングディレクトリに戻るなら`cd -` 86 | 87 | - 途中までコマンドを入力したけれど心変わりした時は、**alt-#**を打つと行頭に`#`が挿入され、コメントとして入力される(**ctrl-a**、**#**、**enter**でも同じ)。これは後でコマンド履歴から検索できる。 88 | 89 | - `xargs`(または`parallel`)を使おう。非常に強力。行ごとにいくつのアイテムを実行するか(`-L`)や、並列度(`-P`)も制御できる。正しく実行されるか定かでないなら、まず`xargs echo`してみればよい。`-I{}`も便利。例えば以下の通り。 90 | 91 | ```bash 92 | find . -name '*.py' | xargs grep some_function 93 | cat hosts | xargs -I{} ssh root@{} hostname 94 | ``` 95 | 96 | - `pstree -p`はプロセスツリーを表示するのに便利。 97 | 98 | - `pgrep`や`pkill`で、プロセス名で検索したりシグナルを送れる(`-f`も便利)。 99 | 100 | - プロセスに送れる色々なシグナルを知っておこう。例えば、プロセスをサスペンドするには`kill -STOP [pid]`を使う。全種類見るなら、`man 7 signal`。 101 | 102 | - バックグラウンドプロセスをずっと実行し続けたいなら`nohup`あるいは`disown`を使おう。 103 | 104 | - `netstat -lntp`や`ss -plat`で、どんなプロセスがリッスンしているか確認しよう(UDPなら`-u`を付ける)。 105 | 106 | - 開かれているソケットやファイルを見るには`lsof`も参照。 107 | 108 | - `uptime`や`w`によってシステムの稼働時間を調べられる。 109 | 110 | - `alias`によってよく利用するコマンドのエイリアス(ショートカット)を作成できる。例えば、`alias ll='ls -latr'`では新しいエイリアスである`ll`が作成される. 111 | 112 | - よく使うエイリアス、シェル設定、機能を`~/.bashrc`に保存し、[ログインシェルに反映しよう](http://superuser.com/a/183980/7106)。これで全てのセッションであなたの設定が利用できる。 113 | 114 | - ログイン時に実行されてほしいコマンド、環境変数を`~/.bash_profile`に記載する。画面からのログインや`cron`ジョブで起動されるシェルには別の設定が必要だ。 115 | 116 | - Gitで様々なマシンの設定ファイル(例:`.bashrc`や`.bash_profile`)を同期させよう。 117 | 118 | - 空白を含む変数やファイル名には注意が必要だ。Bash変数にはクオートをつけよう、こんな風に`"$FOO"`。 119 | ファイル名の区切りとしてヌル文字を指定する場合には`-0`や`-print0`オプションを付与しよう。例: `locate -0 pattern | xargs -0 ls -al` or `find / -print0 -type d | xargs -0 ls -al`。空白を含んだファイル名を繰り返し実行するためには、IFS=$'\n'`を使ってIFSを改行のみにしよう。 120 | 121 | - Bashスクリプトでは、`set -x`でデバッグ出力を出せる(`set -v`は、実行されるコマンドや変数名やコメントなどをそのまま出力する)。特別な理由がない限り厳格モード(strict mode)を使い、`set -e`でエラー時(0以外の終了コード時)に強制終了するように。`set -u`によって未定義の変数の利用を検知、パイプのエラーも厳格に扱うために`set -o pipefail`も使おう(これはちょっと微妙かも)。より複雑なスクリプトなら、EXITまたはERRシグナルに対して`trap`も使おう。使う場面としては以下の場合のようにエラーを検知してメッセージを出力するとき: 122 | 123 | ```bash 124 | set -euo pipefail 125 | trap "echo 'error: Script failed: see failed command above'" ERR 126 | ``` 127 | 128 | - Bashスクリプトでは、コマンドのグループを作るのにサブシェル(丸括弧で囲まれた部分)が便利。一時的にワーキングディレクトリを移動するというよくある例。 129 | 130 | ```bash 131 | # カレントディレクトリで何か実行 132 | (cd /some/other/dir && other-command) 133 | # 元のディレクトリで作業続行 134 | ``` 135 | 136 | - Bashでは、たくさんの変数展開の種類があることを覚えておこう。変数が存在するかチェックするなら、`${name:?error message}`。例えば、Bashスクリプトが1つの引数を取る必要があるなら、`input_file=${1:?usage: $0 input_file}`とだけ書けばよい。算術式の展開は、`i=$(( (i + 1) % 5 ))`。シーケンスは`{1..10}`。文字列のトリミングは`${var%suffix}`と`${var#prefix}`。例えば`var=foo.pdf`の時、`echo ${var%.pdf}.txt`とすると`foo.txt`が出力に。 137 | 138 | - `{`...`}`を使った中括弧展開によって、似たようなコマンドを複数回入力しなくて済む。例えば、 `mv foo.{txt,pdf} some-dir` (両方のファイルを移動させる), `cp somefile{,.bak}` (`cp somefile somefile.bak` と展開される)、`mkdir -p test-{a,b,c}/subtest-{1,2,3}` (すべての可能な組み合わせでディレクトリが作られる). 139 | 140 | - 展開の順序は括弧→チルダ、パラメータや変数、計算機号、コマンド置換(左から右)→文字の分割→ファイル名の順だ。(例えば、{1..20}のような範囲は{$a..$b}というようには表現できない。`seq`や`for`ループを使ってこんな風に表すことができる。`seq $a $b or for((i=a; i<=b; i++)); do ... ; done`) 141 | 142 | - コマンドの出力を`<(some command)`のようにしてファイルのように扱える。例えば、ローカルとリモートのの`/etc/hosts`を比較するなら以下のようになる。 143 | 144 | ```sh 145 | diff /etc/hosts <(ssh somehost cat /etc/hosts) 146 | ``` 147 | 148 | - スクリプトを書く時は全てのコードを中括弧で囲まなくてはいけない。もし閉じ括弧が欠けていたらシンタックスエラーで実行が妨げられる。これはあなたがスクリプトをダウンロードしたときに判明する。(不完全なスクリプトの)実行によって部分的にwebからダウンロードしてしまうのを防ぐためだ。 149 | ```bash 150 | { 151 | # Your code here 152 | } 153 | ``` 154 | 155 | - 「ヒアドキュメント」によって、ファイルからの[複数行のリダイレクト](https://www.tldp.org/LDP/abs/html/here-docs.html)のように振る舞うことができる。 156 | ``` 157 | cat <logfile 2>&1`または`some-command &>logfile`で標準出力と標準エラー出力の両方をリダイレクトできる。コマンドが標準入力に対してファイルハンドルを開きっぱなしにせず、ログインしているターミナルにひもづけておくため、`>> 2+3 208 | 5 209 | ``` 210 | 211 | ## ファイルとデータの処理 212 | 213 | - カレントディレクトリ以下のファイルをファイル名で探したいなら、`find . -iname '*something*'`。場所を指定せずにファイル名で検索したいなら、`locate something`をつかおう(ただし`updatedb`は最近作られたファイルはインデックスしていないであろうことに注意)。 214 | 215 | - ソースやデータファイルの(`grep -r`よりも高度な)一般的な検索には、[`ack`](https://github.com/beyondgrep/ack2)、[`ag`](https://github.com/ggreer/the_silver_searcher) ("the silver searcher")、そして[`rg`](https://github.com/BurntSushi/ripgrep) (ripgrep)を使おう。 216 | 217 | - HTMLをテキストに変換するなら、`lynx -dump -stdin`。 218 | 219 | - MarkdownやHTMLなど様々な種類のドキュメントの変換には、[`pandoc`](http://pandoc.org/)を試してみるとよい。 220 | 221 | - XMLを扱わなくてはならないなら、`xmlstartlet`は古いがいいツールだ。 222 | 223 | - JSONには[`jq`](http://stedolan.github.io/jq/)を使おう。 224 | 225 | - YAMLには[`shyaml`](https://github.com/0k/shyaml)を。 226 | 227 | - ExcelやCSVファイルには、[csvkit](https://github.com/onyxfish/csvkit)で`in2csv`、`csvcut`、`csvjoin`、`csvgrep`などが使えるようになる。 228 | 229 | - Amazon S3には、[`s3cmd`](https://github.com/s3tools/s3cmd)が便利で、[`s4cmd`](https://github.com/bloomreach/s4cmd)はさらに高速。AWS関連の処理にはAmazon公式の[`aws`](https://github.com/aws/aws-cli)と改善版の[`saws`](https://github.com/donnemartin/saws)が欠かせない。 230 | 231 | - `sort`や`uniq`、さらにuniqの`-u`や`-d`オプションを知っておこう。後に出てくるワンライナーも参照。`comm`も確認しておこう。 232 | 233 | - 複数のテキストファイルを操作するのには、`cut`と`paste`、`join`は知っておこう。`cut`はみんな使っているが、`join`は忘れられている。 234 | 235 | - `wc`を理解し、改行(`-l`)、文字(`-m`)、単語(`-w`)、バイト(`-c`)それぞれの数え方も知っておこう。 236 | 237 | - 標準入力をファイルと標準出力の両方に出す`tee`を理解しよう。`ls -al | tee file.txt`のように使う。 238 | 239 | - グルーピング、フィールドを入れ替える、統計的な計算といったもっと複雑な作業は[`datamash`](https://www.gnu.org/software/datamash/)の利用を検討しよう。 240 | 241 | - ロケールは、ソートの順序(照合順序)やパフォーマンスなど、たくさんのコマンドラインツールに微妙なところで影響することを覚えておこう。多くのLinuxディストリビューションでは、`LANG`や他のロケール変数はUS Englishのようなローカルな設定になっている。ロケールを変更するとソート順序が変わることに注意しよう。また、国際化(i18n)対応のルーチンはソートやその他の処理を*何倍も*遅く実行するようになる点も知っておこう。場合(設定の処理や一意性を見つける処理など)によっては、`export LC_ALL=C`としてしまい遅いi18n対応の処理を完全に無視してしまうことも可能だ。 242 | 243 | - `TZ=Pacific/Fiji date`のように起動時に変数を前につけることで、特定のコマンドの環境変数をセットすることができる。 244 | 245 | - 単純なデータ加工のために`awk`と`sed`の基礎を身につけよう。[ワンライナー](#ワンライナー)を参照。 246 | 247 | - 1つあるいは複数のファイル内の文字列を直接置き換えてしまうには、 248 | 249 | ```sh 250 | perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt 251 | ``` 252 | 253 | - 複数のファイル名の変更やファイル内の検索や置換には、[`repren`](https://github.com/jlevy/repren)を使ってみよう。(場合によっては`rename`コマンドでも複数のファイル名変更ができるが、すべてのLinuxディストリビューションで挙動が同じであるわけではないので注意が必要。) 254 | 255 | ```sh 256 | # foo -> barへとファイル名、ディレクトリ名、ファイルの中身を変更する: 257 | repren --full --preserve-case --from foo --to bar . 258 | # バックアップファイルを元に戻す whatever.bak -> whatever: 259 | repren --renames --from '(.*)\.bak' --to '\1' *.bak 260 | # 上記と同じものをrenameを使って: 261 | rename 's/\.bak$//' *.bak 262 | ``` 263 | 264 | - マニュアルページにあるように `rsync` は非常に高速で万能なファイルコピーの道具である。マシーン間のファイルを同期させることでよく知られているが、ローカルの場合でも同様に有用である。また、大量のファイルを削除する[高速な方法](https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html)としても利用できる: 265 | 266 | ```sh 267 | mkdir empty && rsync -r --delete empty/ some-dir && rmdir some-dir 268 | ``` 269 | 270 | - 実行ファイルの進捗を監視したい場合、[`pv`](http://www.ivarch.com/programs/pv.shtml)、[`pycp`](https://github.com/dmerejkowsky/pycp)、 [`pmonitor`](https://github.com/dspinellis/pmonitor)、[`progress`](https://github.com/Xfennec/progress)や`rsync --progress`を使おう。ブロックレベルバックアップは`dd status=progress`だ。 271 | 272 | - ファイルからランダムな行を抜き出すには`shuf` 273 | 274 | - `sort`のオプションを理解しよう。数値に対しては`-n`を使い、人間にとって読みやすい形式の数値の場合(例えば、`du -h`の出力)は`-h`を使おう。キーがどのように処理されるのか(`-t`や`-k`)を知ろう。特に、最初の列だけでソートするには`-k1,1`と書く必要があり、`-k1`だと全行を見てソートされるという点に注意。 275 | 276 | - stableな(安定した)ソート(`sort -s`)は便利。例えば、始めに1列目でソートし、それから2列目でソートするなら、`sort -k1,1 | sort -s -k2,2`とすればよい。 277 | 278 | - Bashのコマンドライン上でタブを表現する必要がある場合、**ctrl-v** **[Tab]**を入力するか`$'\t'` (コピペするなら後者の方がいいかも)。 279 | 280 | - ソースコードにパッチを当てる基本のツールは`diff`と`patch`。`diff`や横並びの`sdiff`の統計情報を見るなら`diffstat`も参照しよう。`diff -r`だと、ディレクトリ全体に対して実行される。変更点の概要を見るなら`diff -r tree1 tree2 | diffstat`。`vimdiff`ではファイルの比較と編集が可能。 281 | 282 | - バイナリファイルなら、単純な16進ダンプを見るのに`hd`、バイナリエディタには`bvi`。 283 | 284 | - 同じくバイナリファイルに関して、テキストを抽出したいなら`strings`(と`grep`などの組み合わせ)。 285 | 286 | - バイナリのdiff(デルタ圧縮)なら、`xdelta3`。 287 | 288 | - テキストエンコーディングの変換は`iconv`を使おう。あるいはより高度なツールとして`uconv`もあり、こちらはUnicodeの高度な処理が可能。例えば以下のコマンドでは小文字に変換しアクセント記号を取り除く(展開してから削除)。 289 | 290 | ```sh 291 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt 292 | ``` 293 | 294 | - ファイルを分割するなら`split`(サイズで分割)と`csplit`(パターンで分割)。 295 | 296 | - 日時について。現在日時を取得するには[ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)が助けになる。`date -u +"%Y-%m-%dT%H:%M:%SZ"` を使おう。(他のオプションは[こちら](https://stackoverflow.com/questions/7216358/date-command-on-os-x-doesnt-have-iso-8601-i-option) [problematic](https://unix.stackexchange.com/questions/164826/date-command-iso-8601-option))。日付や時間の表現を扱うには、[`dateutils`](http://www.fresse.org/dateutils/)にあるように、`dateadd`、 `datediff`、 `strptime` などを使いましょう。 297 | 298 | - 圧縮ファイルの操作は`zless`、`zmore`、`zcat`、`zgrep`。 299 | 300 | - `chattr`でファイル権限に代わる低階層のファイル属性情報をセットできる。例えば、意図しないファイル削除を防ぐフラグはこうやって立てる。`sudo chattr +i /critical/directory/or/file` 301 | 302 | - ファイルの権限を保存、リストアするには`getfacl`と`setfacl`を使おう。例は 303 | ```sh 304 | getfacl -R /some/path > permissions.txt 305 | setfacl --restore=permissions.txt 306 | ``` 307 | - 空ファイルを素早く作るには`truncate`([sparse file](https://en.wikipedia.org/wiki/Sparse_file)を作成)、`fallocate`(ext4, xfs, btrfs とocfs2ファイルシステム)、`xfs_mkfile`(xfsprogs packageにあるほぼ全てのファイルシステム)、`mkfile` (Solaris、Mac OSといったUnix関連システム) 308 | 309 | ## システムのデバッグ 310 | 311 | - Webのデバッグなら`curl`や`curl -l`が便利で、`wget`も同様、よりモダンなのは[`httpie`](https://github.com/jkbrzt/httpie)。 312 | 313 | - CPUやディスクのステータスを知るには、標準的なツールは`top` (または、より良い`htop`)、 `iostat`、 `iotop`。`iostat -mxz 15`を使って、基本的なCPUの情報やパーティッション単位でのディスクの詳細情報やパフォーマンスについて調べましょう。 314 | 315 | - ネットワークの状態の監視には、`netstat`や`ss`。 316 | 317 | - 手早くシステムで何が起きているのかを調べるには、`dstat`が便利。より詳しく見るには、[`glances`](https://github.com/nicolargo/glances)。 318 | 319 | - メモリのステータスを知るには、`free`あるいは`vmstat`を実行し、その出力の意味を理解しよう。特に、"cached"の値はLinuxカーネルにファイルキャッシュとして保持されているメモリ量であり、"free"の値を見る際に考慮すべきであることに注意しよう。 320 | 321 | - Javaのシステムのデバッグはまた違う困ったところがあるが、Oracleあるいは他のJVMにも共通しているシンプルなトリックは、`kill -3 `でフルスタックトレースとヒープの概要が標準出力あるいはログにダンプされる(世代別GCの詳細も参考程度だが含まれている)。JDKの `jps`、 `jstat`、 `jstack`、 `jmap` も便利で、[SJK tools](https://github.com/aragozin/jvm-tools)はより高度なツールである。 322 | 323 | - 改良版tracerouteとして[`mtr`](http://www.bitwizard.nl/mtr/)を使ってネットワークの問題を調査しよう。 324 | 325 | - ディスクがいっぱいになっている理由を調べるには、[`ncdu`](https://dev.yorhel.nl/ncdu)を使うと`du -sh *`より時間が節約できる。 326 | 327 | - 帯域を使っているのがどのソケットやプロセスなのかを見つけるには、[`iftop`](http://www.ex-parrot.com/~pdw/iftop/)あるいは[`nethogs`](https://github.com/raboof/nethogs)を試そう。 328 | 329 | - `ab`(Apacheに付属)は、Webサーバのパフォーマンスをざっくりチェックするのに便利。より複雑なテストには`siege`を試そう。 330 | 331 | - より確実なネットワークのデバッグは[`wireshark`](https://wireshark.org/)、[`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html)、[`ngrep`](http://ngrep.sourceforge.net/)。 332 | 333 | - `strace`と`ltrace`について知っておこう。プログラムの実行に失敗したりハングしたりクラッシュしたりして、その理由が分からない、あるいはパフォーマンスに関する一般的情報を知りたいなら、このツールが役立つはずだ。プロファイリングのオプション(`-c`)や起動中のプロセスにアタッチする機能(`-p`)も覚えておこう。 334 | 335 | - 共有ライブラリをチェックするなら`ldd`を覚えておこう。でも[怪しいファイルを指定して実行しないように](http://www.catonmat.net/blog/ldd-arbitrary-code-execution/) 336 | 337 | - 起動中のプロセスに`gdb`で接続し、そのスタックトレースを取る方法を知ろう。 338 | 339 | - `/proc`以下のファイルを使おう。今起こっている問題をデバッグするのには素晴らしく便利だ。例えば、`/proc/cpuinfo`、`/proc/meminfo`、`/proc/cmdline`、`/proc/xxx/cwd`、`/proc/xxx/ece`、`/proc/xxx/fd/`、`/proc/xxx/smaps` (ここで、`xxx`はプロセスIDまたはPIDを意味する)。 340 | 341 | - 過去に何か問題が起きたことの原因を探るなら、[`sar`](http://sebastien.godard.pagesperso-orange.fr/)がとても便利。CPUやメモリ、ネットワークなどの過去の統計情報を見られる。 342 | 343 | - さらに深いシステムとパフォーマンスの分析には、`stap` ([SystemTap](https://sourceware.org/systemtap/wiki))、[`perf`](https://en.wikipedia.org/wiki/Perf_(Linux))、 344 | [`sysdig`](https://github.com/draios/sysdig)。 345 | 346 | - どのOSを利用しているかを`uname`や`uname -a` (Unixカーネル情報)で確認しよう。どのディストリビューションを使っているかは`lsb_release -a` (ディストリビューション情報)。 347 | 348 | - 何かいつもと違うおかしなこと(大抵ハードウェアかドライバ関連の問題だ)が起きていたら、`dmesg`を実行しよう。 349 | 350 | - `du`で表示されたディスクースペースがファイルを消しても空かなかった場合、そのファイルがプロセスに使われているかどうかこうやって確認しよう。`lsof | grep deleted | grep "filename-of-my-big-file"` 351 | 352 | ## ワンライナー 353 | 354 | コマンドをまとめて使う例をいくつか。 355 | 356 | - `sort`や`uniq`を使ってテキストファイルの共通部分、結合、差異を求める時に特に便利なのが以下のやり方。`a`と`b`はそれぞれ内容に重複のないテキストファイルとする。この方法は高速で、数GB程度までの任意のファイルサイズで動作する(`/tmp`が小さなルートパーティションにある場合は`-T`オプションをつける必要があるが、ソートはメモリ内で行われるとは限らない)。上述の`LC_ALL`と`sort`の`-u`オプションも参照のこと。 357 | 358 | ```sh 359 | cat a b | sort | uniq > c # cはaとbの和集合 360 | cat a b | sort | uniq -d > c # cはaとbの共通部分 361 | cat a b b | sort | uniq -u > c # cはaとbの差異 362 | ``` 363 | 364 | - `grep . *`(各行にファイル名が付く)や、`head -100 *` (ファイル毎にヘッダーが付く)を使って手軽にディレクトリ内の全てのファイルの中身を確認できる。設定ファイルが含まれるような`/sys`や`/proc`や`/etc/`に対して非常に便利である。 365 | 366 | - テキストファイルの3列目を全て足し合わせるには以下で(Pythonで同じことをやるに比べて3倍速く3分の1の長さで書ける)。 367 | 368 | ```sh 369 | awk '{ x += $3 } END { print x }' myfile 370 | ``` 371 | 372 | - ファイルツリーのサイズやデータを確認したいなら、以下は再帰的な`ls -l`と同じだが`ls -lR`より見やすい。 373 | 374 | ```sh 375 | find . -type f -ls 376 | ``` 377 | 378 | - Webサーバのログのようなテキストファイルがあり、各行には例えばURLの中に出てくる`acct_id`のような特定の値が現れるとしよう。`acct_id`が何回リクエストされているかを集計するには、 379 | ```sh 380 | egrep -o 'acct_id=[0-9]+' access.log | cut -d= -f2 | sort | uniq -c | sort -rn 381 | ``` 382 | 383 | - 継続的に変更を監視する場合 `watch`を使う。例えば、ディレクトリのファイルの変更を確認するには `watch -d -n 2 'ls -rtlh | tail'` となり、wifi設定などのネットワーク設定関係のトラブルシューティングでは `watch -d -n 2 ifconfig`。 384 | 385 | - このドキュメントからランダムに項目を抜き出すには以下の関数を実行しよう(Markdownをパースし、アイテムを抽出する)。 386 | 387 | ```sh 388 | function taocl() { 389 | curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md | 390 | pandoc -f markdown -t html | 391 | xmlstarlet fo --html --dropdtd | 392 | xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 393 | xmlstarlet unesc | fmt -80 394 | } 395 | ``` 396 | 397 | ## 目立たないが便利なもの 398 | 399 | - `expr`: 算術演算、論理演算、または正規表現の評価を実行 400 | 401 | - `m4`: シンプルなマクロプロセッサ 402 | 403 | - `yes`: 文字列をたくさん表示 404 | 405 | - `cal`: いい感じのカレンダー 406 | 407 | - `env`: コマンドを実行(スクリプト内で重宝する) 408 | 409 | - `printenv`: 環境変数を表示する(デバッグやスクリプト内での使用に便利) 410 | 411 | - `look`: 文字列で始まる英単語(またはファイル内の行)を見つける 412 | 413 | - `cut `、 `paste`、`join`: データの操作 414 | 415 | - `fmt`: テキストの段落をフォーマットする 416 | 417 | - `pr`: テキストをページとカラムにフォーマットする 418 | 419 | - `fold`: テキストの行を分割 420 | 421 | - `column`: テキストをカラムあるいはテーブルにフォーマット 422 | 423 | - `expand` と `unexpand`: タブとスペースの相互変換 424 | 425 | - `nl`: 行数を表示 426 | 427 | - `seq`: 数字を表示 428 | 429 | - `bc`: 計算機 430 | 431 | - `factor`: 整数を因数分解 432 | 433 | - [`gpg`](https://gnupg.org/): ファイルの暗号化と署名 434 | 435 | - `toe`: terminfoのエントリのテーブルを表示 436 | 437 | - `nc`: ネットワークのデバッグとデータ転送 438 | 439 | - `socat`: ソケットリレーとTCPポートのフォワーダ(`netcat`と同等) 440 | 441 | - [`slurm`](https://github.com/mattthias/slurm): ネットワークトラフィックの可視化 442 | 443 | - `dd`: データをファイルあるいはデバイス間で移動 444 | 445 | - `file`: ファイルの種類を特定 446 | 447 | - `tree`: ディレクトリとサブディレクトリをツリーで表示。`ls`に似ているが再帰的に動く 448 | 449 | - `stat`: ファイルの情報 450 | 451 | - `time`: コマンドを実行して処理時間を計測 452 | 453 | - `timeout`: コマンドを実行し、指定時間経過後にプロセスを停止する 454 | 455 | - `lockfile`: セマフォファイルを生成する。これは`rm -f`のみで削除可能。 456 | 457 | - `logrotate`: ログをローテート、圧縮、メール送信 458 | 459 | - `watch`: コマンドを繰り返し実行する。変更部分の強調表示もできる。 460 | 461 | - `tac`: ファイルを逆から表示 462 | 463 | - `shuf`: ファイルからランダムに選んだ行を表示 464 | 465 | - `comm`: ソート済みファイルの行を比較 466 | 467 | - `pv`: パイプ経由でデータの進行状況をモニタリング 468 | 469 | - `sponge`: 書き込み前に全ての入力を読み込む。例えば、`grep -v something some-file | sponge some-file` のように、入力と同じファイルに書き込む際に便利。 470 | 471 | - `hd`、`hexdump`、`xxd`、`biew`、`bvi`: バイナリファイルのダンプと編集 472 | 473 | - `strings`: バイナリファイルからテキストを抽出 474 | 475 | - `tr`: 文字の置き換えと操作 476 | 477 | - `iconv` あるいは `uconv`: 文字エンコーディングの変換 478 | 479 | - `split` と `csplit`: ファイルを分割 480 | 481 | - `units`: 単位の変換と計算。2週間あたりのハロン(訳注 : 長さの単位)からまばたきごとのトゥウィップまで( `/usr/share/units/definitions.units`も参照のこと) 482 | 483 | - `apg`: ランダムなパスワードを生成 484 | 485 | - `7z`: 圧縮率の高いファイル圧縮 486 | 487 | - `ldd`: 動的ライブラリの情報 488 | 489 | - `nm`: オブジェクトファイルからシンボルを表示 490 | 491 | - `ab`: Webサーバのベンチーマーク 492 | 493 | - `strace`: システムコールのデバッグ 494 | 495 | - [`mtr`](http://www.bitwizard.nl/mtr/): ネットワークデバッグのためのより高機能なtraceroute 496 | 497 | - `cssh`: ビジュアルな並列シェル 498 | 499 | - `rsync`: ファイルやフォルダをSSH経由またはローカルファイルシステム内で同期 500 | 501 | - [`wireshark`](https://wireshark.org/) と [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html): パケットキャプチャとネットワークデバッギング 502 | 503 | - [`ngrep`](http://ngrep.sourceforge.net/): ネットワーク層のgrep 504 | 505 | - `host` と `dig`: DNS名前解決 506 | 507 | - `lsof`:プロセスのファイルディスクリプタとソケット情報 508 | 509 | - `dstat`: 便利なシステム情報 510 | 511 | - [`glances`](https://github.com/nicolargo/glances): 高レベルに複数のサブシステムの概要を把握 512 | 513 | - `iostat`: ディスクの使用状況 514 | 515 | - `mpstat`: CPUの使用状況 516 | 517 | - `vmstat`: メモリの使用状況 518 | 519 | - `htop`: topの改良版 520 | 521 | - `last`: ログイン履歴 522 | 523 | - `w`: 誰がログインしているか 524 | 525 | - `id`: ユーザやグループの情報 526 | 527 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/): システム統計情報の履歴 528 | 529 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) または [`nethogs`](https://github.com/raboof/nethogs): ソケットあるいはプロセスごとのネットワーク使用量 530 | 531 | - `ss`: ソケットの統計情報 532 | 533 | - `dmesg`: 起動時とシステムのエラーメッセージ 534 | 535 | - `sysctl`: Linuxカーネルパラメータの確認および設定 536 | 537 | - `hdparm`: SATA/ATAディスクの操作やパフォーマンス確認 538 | 539 | - `lsblk`: ブロックデバイスの一覧。ディスクとディスクパーティションのツリービュー 540 | 541 | - `lshw`、`lscpu`、`lspci`、`lsusb`、`dmidecode`: CPUやBIOS、RAID、グラフィック、その他デバイスなどのハードウェア情報 542 | 543 | - `lsmod`、`modinfo`: カーネルのモジュールリストとモジュール情報 544 | 545 | - `fortune`、 `ddate`、`sl`: んー、あー、これは蒸気機関車やZippyの引用句が「便利」だと思うかどうかによる 546 | 547 | ## OS X用のもの 548 | 549 | これらは*MacOS用*の項目です。 550 | 551 | - パッケージ管理は`brew` (Homebrew)や`port` (MacPorts)を使う。上記の多くのコマンドをMacOSにインストールできる。 552 | 553 | - コマンドの出力をクリップボードにコピーする`pbcopy`とクリップボードから出力する`pbpaste`。 554 | 555 | - OptionキーをaltキーとしてMac OSのターミナルで使う(上述の**alt-b**、**alt-f**などを使う場合)には、環境設定 -> 設定 -> キーボード で、"メタキーとしてoptionキーを使用"を選択。 556 | 557 | - デスクトップアプリケーションでファイルを開くには、`open`、`open -a /Applications/Whatever.app`。 558 | 559 | - Spotlight: `mdfind`でファイルを検索し、メタデータ(画像ファイルのEXIFの情報など)を`mdls`で表示。 560 | 561 | - Mac OSはBSD Unixベースであるため、多くのコマンド(例えば、`ps`、`ls`、`tail`、`awk`、`sed`)では、Unix System VとGNUツールの違いに影響されて、Linuxのものと比べて微妙な違いが多く含まれている。違いがあるかについては、マニュアルページのタイトルに"BSD General Commands Manual"と書かれているかどうかで判断できる。場合によっては、GNUバージョンをインストール可能である(例えば、`gawk`や`gsed`で、GNUのawkとsedに対応)。クロスプラットフォームのbashスクリプトを書く場合には、そのようなコマンドは避ける(Pythonや`perl`の利用を検討)か十分なテストが必要である。 562 | 563 | - Mac OSのリリース情報を取得するには、`sw_vers`。 564 | 565 | ## Windows専用 566 | 567 | これらは*Windows用*の項目です。 568 | 569 | ### Windows下でUnixツールを手に入れる方法 570 | 571 | - [Cygwin](https://cygwin.com/)をMicrosoft WindowsでインストールしてUnixシェルの力を手にしよう。このドキュメントで説明されている大部分はびっくり箱みたいに独創的だ。 572 | 573 | - Windows10であれば[Windows Subsystem for Linux (WSL)](https://msdn.microsoft.com/commandline/wsl/about)を使える。Unixコマンドラインや親しみのあるBashを提供してくれる。 574 | 575 | - windows上で、主にGNUデベロッパーツール(GCCなど)を使いたい場合、[MinGW](http://www.mingw.org/)や[MSYS](http://www.mingw.org/wiki/msys)を検討しよう。bash、gawk、make、grepを提供してくれる。MSYSはCygwinと比べると全ての機能を持っているわけではない。MinGWはUnixツールのネイティブWindowsポートを作成するのに特に有効だ。 576 | 577 | - Windows配下でUnixの見た目と操作感を得るもう一つの方法は[Cash](https://github.com/dthree/cash)だ。本当に限られたUnixコマンドやコマンドラインオプションしかこの環境では利用できないので注意が必要だ。 578 | 579 | ### 使えるWindowsコマンドラインツール 580 | - `wmic`を使って学ぶことで、Windowsシステム管理者タスクの大部分をコマンドラインで記述、実行することができる。 581 | 582 | - `ping`、`ipconfig`、`tracert`、`netstat`などのWindows固有のコマンドラインも便利だと思えるはずだ。 583 | 584 | - `Rundll32`を実行することによって[便利なWindowsタスク](http://www.thewindowsclub.com/rundll32-shortcut-commands-windows)を利用することができる。 585 | 586 | ### Cygwinの秘訣とコツ 587 | 588 | - Cygwinのパッケージマネージャーで追加のUnixプログラムをインストールしよう。 589 | 590 | - `mintty`をコマンドラインウィンドウとして使おう 591 | 592 | - `/dev/clipboard`でWindowsのクリップボードにアクセスしてみよう。 593 | 594 | - 登録されたアプリケーションで任意のファイルを開くためには`cygstart`を起動しよう。 595 | 596 | - `regtool`でWindowsレジストリにアクセスしよう。 597 | 598 | - `C:\`WindowsドライブのパスはCygwin下では`/cygdrive/c`なので注意が必要だ。また、Cygwinの`/`はWindowsの`C:\cygwin`だ。`cygpath`を使ってCygwinスタイルとWindowsスタイルのパスを切り替えられる。これはWindowsプログラムを実行するスクリプトでとても有効だ。 599 | 600 | ## さらなるリソース 601 | 602 | - [awesome-shell](https://github.com/alebcay/awesome-shell): シェルのツールやリソースのまとめ 603 | - [awesome-osx-command-line](https://github.com/herrbischoff/awesome-osx-command-line): より詳しいMac OSのコマンドラインガイド 604 | - [Strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/): よりよいシェルスクリプトを書くために 605 | - [shellcheck](https://github.com/koalaman/shellcheck): シェルスクリプト(本来、bash/sh/zsh用)の静的解析ツール 606 | - [Filenames and Pathnames in Shell](http://www.dwheeler.com/essays/filenames-in-shell.html): シェルスクリプトでファイル名を正しく扱うために 607 | - [Data Science at the Command Line](http://datascienceatthecommandline.com/#tools): 同タイトルの書籍から引用されているデータサイエンスで役に立つコマンドやツール 608 | 609 | ## 免責事項 610 | 611 | ごく一部の例外はありますが、コードは誰でも読めるように書かれている。力には責任が伴う。Bashで*できる*からといって、そうすべき必要があるという意味ではない! ;) 612 | 613 | ## ライセンス 614 | 615 | [![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 616 | 617 | このドキュメントは[Creative Commons Attribution-ShareAlike 4.0 International Licene](http://creativecommons.org/licenses/by-sa/4.0/)でライセンスされる。 618 | -------------------------------------------------------------------------------- /README-ko.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | 5 | # The Art of Command Line 6 | 7 | [![Ask a Question](https://img.shields.io/badge/%3f-Ask%20a%20Question-ff69b4.svg)](https://airtable.com/shrzMhx00YiIVAWJg) 8 | 9 | [![Join the chat at https://gitter.im/jlevy/the-art-of-command-line](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 10 | 11 | 12 | - [Meta](#meta) 13 | - [Basics](#basics) 14 | - [Everyday use](#everyday-use) 15 | - [Processing files and data](#processing-files-and-data) 16 | - [System debugging](#system-debugging) 17 | - [One-liners](#one-liners) 18 | - [Obscure but useful](#obscure-but-useful) 19 | - [macOS only](#macos-only) 20 | - [Windows only](#windows-only) 21 | - [More resources](#more-resources) 22 | - [Disclaimer](#disclaimer) 23 | 24 | 25 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 26 | 27 | 커맨드 라인을 능숙하게 다루는 기술은 종종 도외시되거나 신비스럽게 여겨집니다. 하지만 커맨드 라인은 명백하고도 미묘한 방법으로 엔지니어가 하는 작업의 유연성과 생산성을 향상시킵니다. 이 문서는 리눅스에서 커맨드 라인을 사용할 때 유용하게 활용할 수 있는 노트와 팁들의 모음입니다. 몇몇은 기초적인 것들이지만 몇몇은 상당히 구체적이고 세련되며 잘 알려지지 않은 것들입니다. 이 문서는 그리 길지 않지만 여기 있는 모든 것을 사용할 수 있고 기억해낼 수 있다면 당신은 많은 것을 알고 있다고 할 수 있습니다. 28 | 29 | 이 문서에는 [많은 저자와 번역가](AUTHORS.md)가 참여했습니다. 30 | 여기 중 일부 내용은 31 | [원래](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands) 32 | [Quora에](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix) 33 | [올라온](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know) 것이지만 34 | 후에 GitHub으로 옮겨졌고, 이 곳에서 원 저자들보다 더 재능있는 사람들이 무수히 많은 개선작업을 진행하였습니다. 35 | 커맨드 라인에 관해 궁금한 것이 있으면 [**질문해 주세요**.](https://airtable.com/shrzMhx00YiIVAWJg) 오류가 있거나 더 나아질 수 있는 내용이 보인다면 [**기여해 주세요**!](/CONTRIBUTING.md) 36 | 37 | ## Meta 38 | 39 | 범위: 40 | 41 | - 이 가이드는 초보자와 경험자 모두를 위한 것 입니다. 이 가이드의 목표는 _폭넓은 지식을 제공하는 것_(전부 다 중요합니다), _구체적으로 제공하는 것_(가장 일반적인 사례에 대한 구체적인 예제를 제공합니다), 그리고 _간결하게 제공하는 것_(중요하지 않거나 다른 문서에서 쉽게 찾아볼 수 있는 지엽적인 것들을 피합니다)입니다. 모든 팁은 특정 상황에서 매우 중요하거나 여러 다른 대안들보다 시간을 확연하게 절약합니다. 42 | - 이 문서는 리눅스를 위해 쓰였습니다. "[macOS only](#macos-only)", "[Windows only](#windows-only)" 섹션을 제외하고 말이죠. 그 밖의 대부분은 유닉스, macOS(심지어 Cygwin)에서도 적용하거나 설치할 수 있습니다. 43 | - 인터랙티브 Bash에 초점이 맞추어져있습니다만, 대부분의 팁은 다른 쉘이나, general Bash 스크립트에서도 동작합니다. 44 | - 이 문서는 "표준" 유닉스 커맨드와 특정 패키지 설치를 필요로 하는 것 둘 다 포함하고 있습니다 -- 여기서 다룰만큼 충분히 중요하다면요. 45 | 46 | 노트: 47 | 48 | - 이 문서를 하나의 파일로 유지하기 위해서 콘텐츠들은 암시적인 레퍼런스 형태로 포함되어있습니다. 한 개념이나 명령어에 대해 알게 된 후에, 구글에서 그에 대한 좀 더 자세한 정보를 찾아보세요. `apt-get`, `yum`, `dnf`, `pacman`, `pip`, `brew` (혹은 적절한 다른 것)를 이용해 새 프로그램을 설치하세요. 49 | - [Explainshell](http://explainshell.com/)을 이용해서 커맨드, 옵션, 파이프, 기타 등등이 어떤 기능을 하는지 분석하는데 도움을 받으세요. 50 | 51 | 52 | ## Basics 53 | 54 | - Bash의 기초를 배우세요. 말하자면, `man bash`를 실행하고 최소한 전부 훑어보기라도 하세요. 매뉴얼의 내용은 따라가기 쉬우며 그리 길지 않습니다. 다른 쉘들 또한 좋습니다만, Bash는 강력하고 언제나 사용 가능합니다(zsh, fish, 혹은 그 외의 쉘*만* 배운다면 개인 노트북에서는 좋겠지만 많은 경우 제한이 생길 것입니다. 이미 존재하는 서버를 사용하는 것등의 일에서 말이죠). 55 | 56 | - 텍스트 기반 에디터를 최소한 하나 정도는 잘 다룰 수 있게 배우세요. `nano` 에디터는 기본적인 편집기능(열기, 수정하기, 저장하기, 찾기)을 제공하는 가장 단순한 에디터 중 하나입니다. 그러나 텍스트 터미널을 이용하는 고급 이용자라면 Vim(`Vi`)을 대체할 수 있는 것은 없습니다. Vim은 사용법을 배우기는 어렵지만 믿음직하고 빠르며 풍부한 기능을 가졌습니다. 또한 고전적인 Emacs도 많이 사용됩니다. 특히 규모가 좀 더 큰 편집 작업에서요. (물론 요즘 같은 시대에 대형 프로젝트를 진행하고 있는 소프트웨어 개발자라면 순수한 텍스트 기반 에디터만 사용하지는 않을 것이고 최신의 그래픽 기반 IDE와 도구들에도 익숙해져야 합니다.) 57 | 58 | - `man`을 이용해서 문서를 읽는 법을 배우세요(호기심 많은 사람을 위해서 하는 얘기입니다만, `man man`은 섹션 번호들의 목록을 표시합니다. 예를 들어 1은 "regular" 커맨드, 5는 files/conventions, 그리고 8은 administration이죠). `apropos`를 이용해서 man 페이지를 찾으세요. 몇몇 커맨드는 실행파일이 아니라 Bash 빌트인 명령어임을 알아두세요. Bash 빌트인 명령어들에 대한 도움을 받으려면 `help`와 `help -d`를 이용하세요. 어떤 커맨드가 실행파일, 쉘 빌트인 명령어인지, 아니면 별칭인지는 `type command`를 통해 확인할 수 있습니다. 59 | 60 | - `>`와 `<`, `|`를 이용한 파이프를 사용해서 입력과 출력의 리다이렉션을 배우세요. `>`는 출력 파일을 덮어 씌우고, `>>`는 출력 파일 끝에 내용을 덧붙인다는 걸 알아두세요. stdout(역주: 표준 출력)과 stderr(역주: 표준 에러 출력)에 대해서 배우세요. 61 | 62 | - `*`(그리고 아마도 `?`와 `[`...`]`)을 이용하는 파일 글롭(glob) 확장을 배우세요. 그리고 쌍따옴표`"`와 홑따옴표`'`의 차이를 배우세요. (변수 확장에 대해서 더 보려면 아래를 참조하세요) 63 | 64 | - Bash 작업 관리에 익숙해지세요. `&`, **ctrl-z**, **ctrl-c**, `jobs`, `fg`, `bg`, `kill` 등등. 65 | 66 | - `ssh`를 배우고, `ssh-agent`, `ssh-add`를 통해서 비밀번호 없는 인증 방식의 기본을 배우세요. 67 | 68 | - 기본 파일 관리: `ls`와 `ls -l`(특별히, `ls -l`에서 각각의 열이 무슨 의미인지 배우세요), `less`, `head`, `tail` 그리고 `tail -f`(또는 더 좋은 `less +F`), `ln`과 `ln -s`(하드 링크와 소프트 링크의 차이와 각각의 장단점을 배우세요), `chown`, `chmod`, `du`( 디스크 사용량의 빠른 요약을 보려면 `du -hs *`). 파일 시스템 관리를 위해서는 `df`, `mount`, `fdisk`, `mkfs`, `lsblk`. inode가 무엇인지 배우세요(`ls -i` 또는 `df -i`). 69 | 70 | - 기본 네트워크 관리: `ip` 또는 `ifconfig`, `dig`, `traceroute`, `route`. 71 | 72 | - `git` 같은 버전 관리 시스템을 배우고 사용하세요. 73 | 74 | - 정규 표현식(regular expression)을 잘 알아두세요. 그리고 `grep`/`egrep`의 다양한 플래그도 알아두세요. `-i`, `-o`, `-v`,`-A`, `-B`와 `-C` 옵션은 알아둘 가치가 있습니다. 75 | 76 | - `apt-get`, `yum`, `dnf` 또는 `pacman`(배포판마다 다릅니다)을 이용하여 패키지를 찾고 설치하는 법을 배우세요. 그리고 `pip`가 설치되어 있는지 확인해서 파이선 기반의 커맨드 라인 도구를 설치할 수 있도록 하세요(밑에 설명된 것 중 몇 가지는 `pip`를 이용해 설치하는 게 제일 쉽습니다). 77 | 78 | 79 | ## Everyday use 80 | 81 | - Bash 에서 **Tab**을 쓰면 argument를 완성하고, **ctrl-r**을 쓰면 커맨드 히스토리에서 검색합니다(누른 다음, 검색할 것을 입력하고, **ctrl-r**를 계속 눌러 좀 더 맞는 것을 찾을 수 있습니다. **Enter**를 눌러 찾은 커맨드를 실행하고 오른쪽 화살표 키를 눌러 결과를 현재 라인에 복사해 수정할 수 있습니다). 82 | 83 | - Bash에서 **ctrl-w**는 마지막 단어를 지웁니다. **ctrl-u**는 라인의 처음까지 전부다 지웁니다. **alt-b**와 **alt-f**를 이용해서 단어 단위로 이동할 수 있습니다. **ctrl-a**로 라인의 시작점으로 이동할 수 있고 **ctrl-e**로 라인의 끝으로 이동할 수 있습니다. **ctrl-k**는 커서 위치부터 라인의 끝까지 지웁니다. **ctrl-l**은 화면을 깨끗하게 합니다. `man readline`을 이용해서 Bash의 기본 키 조합을 살펴보세요. 많은 것이 있습니다. 예를 들면 **alt-.**같은 경우, 이건 argument를 돌아가면서 나타내고 **alt-***는 글롭을 확장합니다. 84 | 85 | 86 | - vi 스타일의 키 조합을 사랑한다면, `set -o vi`를 사용할 수도 있습니다(`set -o emacs`로 되돌릴 수 있습니다). 87 | 88 | - 긴 명령을 수정하려면 에디터를 설정한 다음(예를 들면, `export EDITOR=vim`) **ctrl-x** **ctrl-e**를 눌러 현재 명령을 에디터에서 열어 여러줄 편집을 할 수 있습니다. vi 스타일에서는 **escape-v**를 사용합니다. 89 | 90 | - 최근 사용한 커맨드를 보려면 `history`를 입력하세요. 그 후 `!n`으로(여기서 `n`은 커맨드 번호를 뜻합니다) 다시 실행할 수 있습니다. `!$`(마지막 argument), `!!`(마지막 커맨드)와 같은 약어들이 매우 많습니다. 비록 이런 것들이 **ctrl-r**이나 **alt-.**명령어로 자주 대체되기 쉽지만요. 91 | 92 | - `cd`로 홈 디렉터리로 갈 수 있습니다. 홈 디렉터리에서 상대적으로 파일을 접근하려면 `~` 접두사를 사용합니다(예: `~/.bashrc`). `sh` 스크립트에서는 `$HOME`로 홈 디렉터리를 참조합니다. 93 | 94 | - 이전에 작업하던 디렉터리로 돌아가려면 `cd -`를 사용하세요. 95 | 96 | - 커맨드를 타이핑하던 도중에 마음이 바뀌었다면, **alt-#**을 쳐서 시작점에 `#`을 삽입하고, 엔터를 쳐서 코멘트로 여겨지게 하세요(또는 **ctrl-a**, **#**, **enter**). 나중에 커맨드 히스토리에서 찾아서 타이핑 중이었던 커맨드로 돌아올 수 있습니다. 97 | 98 | - `xargs`(혹은 `parallel`)를 사용하세요. 매우 강력합니다. 라인당 몇 개의 아이템이 실행되게 할 것인지(`-L`) 그걸 병렬로 할 것인지(`-P`)를 제어할 수 있다는 걸 기억하세요. 제대로 하고 있는지 확신할 수 없다면 `xargs echo`를 먼저 실행해보세요. 또 `-I{}`도 편리합니다. 예시: 99 | ```bash 100 | find . -name '*.py' | xargs grep some_function 101 | cat hosts | xargs -I{} ssh root@{} hostname 102 | ``` 103 | 104 | - `pstree -p`는 프로세스 트리를 표시하는데 도움이 됩니다. 105 | 106 | - `pgrep`과 `pkill`을 사용해서 프로세스를 찾거나 시그널을 보내세요(`-f`가 유용합니다). 107 | 108 | - 프로세스에 보낼 수 있는 다양한 시그널을 알아두세요. 예를 들어, 프로세스를 일시 중지 할 때는 `kill -STOP [pid]`를 사용합니다. 전체 목록은 `man 7 signal`에서 볼 수 있습니다. 109 | 110 | - 백그라운드 프로세스를 영원히 돌아가게 만들고 싶다면, `nohup`이나 `disown`을 사용하세요. 111 | 112 | - 어떤 프로세스가 리스닝(역주: 특정 포트로 들어오는 패킷 리스닝)을 하고 있는지 알려면 `netstat -lntp`나 `ss -plat`을 사용해서 알 수 있습니다(TCP 일 경우입니다. UDP의 경우 `-u`옵션을 추가하세요). 113 | 114 | - `lsof`를 이용해서 열려있는 소켓과 파일을 볼 수 있습니다. 115 | 116 | - `uptime`이나 `w`를 이용해서 시스템이 얼마나 오래 실행 중인지 알 수 있습니다. 117 | 118 | - 자주 사용되는 커맨드에 대해서 `alias`를 이용해서 숏컷을 만드세요. 예를들어, `alias ll='ls -latr'`은 새 단축 명령 `ll`을 만듭니다. 119 | 120 | - 자주 사용하는 단축, 설정, 함수는 `~/.bashrc`에 저장하고, [그것을 참조하는 로그인 셸을 고쳐보세요](http://superuser.com/a/183980/7106). 이렇게 하면 설정을 모든 셸 세션에서 사용할 수 있습니다. 121 | 122 | - 환경 변수 설정이나 로그인할 때 실행해야 할 명령은 `~/.bash_profile`에 넣으세요. 그래픽 환경의 로그인의 셸과 `cron` 잡의 셸을 분리하기 위해 설정을 분리할 필요가 있습니다. 123 | 124 | - Git으로 여러 컴퓨터에서 같은 설정 파일을 사용하세요(예 `.bashrc`, `.bash_profile`). 125 | 126 | - 공백이 들어간 변수명이나 파일명은 주의할 필요가 있습니다. Bash 변수를 따옴표로 감싸세요(예: `"$FOO"`). 파일 이름의 경계에 공백 문자를 허용하려면 `-0`이나 `-print0` 옵션을 사용하세요. 예를 들면, `locate -0 pattern | xargs -0 ls -al`, `find / -print0 -type d | xargs -0 ls -al`. for 문에서 공백문자가 포함된 파일 이름을 반복하려면, `IFS=$'\n'`로 IFS를 개행 문자만으로 설정하시면 됩니다. 127 | 128 | - Bash 스크립트에서 `set -x`를 사용하면 디버깅용 출력을 사용하게 됩니다(아니면 다른 옵션 `set -v`가 있습니다. 확장되지 않은 변수와 주석을 포함한 로우 입력을 로깅합니다). 스트릭트 모드(strict mode)가 가능할 때면 사용하세요. `set -e`를 사용하면 에러가 났을 때 중단시키게 됩니다. `set -u`을 사용하면 설정되지 않은 변수를 찾아 줍니다. `set -o pipefail`을 사용하면 에러에 대해서 강경한 기준을 적용합니다(이 주제가 조금 미묘하지만 말이죠). 더 복잡한 스크립트의 경우 EXIT나 ERR에 `trap`도 사용합니다. 이렇게 스크립트를 시작하는 습관은 유용합니다. 이렇게 하면, 일반적인 에러를 찾고 중단하고, 메시지를 출력해 줍니다. 129 | ```bash 130 | set -euo pipefail 131 | trap "echo 'error: Script failed: see failed command above'" ERR 132 | ``` 133 | 134 | - Bash 스크립트에서 (괄호로 둘러싸여 작성된) 서브 셸은 커맨드를 그룹으로 묶는 편리한 방법입니다. 일반적인 예로, 임시로 다른 디렉터리로 이동하여 작업하는 것이 있습니다. 135 | ```bash 136 | # do something in current dir 137 | (cd /some/other/dir && other-command) 138 | # continue in original dir 139 | ``` 140 | 141 | - Bash 에는 다양한 변수 확장이 있다는 것을 알아두세요. 변수가 존재하는지 확인하려면 `${name:?error message}`를 사용하세요. 예를 들어 Bash 스크립트가 하나의 argument를 요구한다면, `input_file=${1:?usage: $0 input_file}`를 사용하세요. 변수가 비어있을 때를 대비해 기본 값을 사용하세요. `${name:-default}` 이전 예제에 선택적인 파라미터를 추가하길 원한다면 `output_file=${2:-logfile}`로 할 수 있습니다. $2가 생략되어 비어있다면, `output_file`은 `logfile`로 설정됩니다. 산술 확장은 `i=$(( (i + 1) % 5 ))` 처럼 사용합니다. 순열은 `{1...10}`처럼 사용합니다. 문자열 트리밍(trimmin)은 `${var%suffix}`이나 `${var#prefix}`처럼 사용할 수 있습니다. 예를 들어 `var=foo.pdf`라면, `echo ${var$.pdf}.txt`는 `foo.txt`를 출력합니다. 142 | 143 | - `{`...`}`를 사용한 괄호 확장은 비슷한 텍스트의 재입력을 줄이고, 아이템의 조합을 자동화할 수 있습니다. `mv foo.{txt,pdf} some-dir` (양쪽 파일들을 옮김), `cp somefile{,.bak}` (`cp somefile somefile.bak`로 확장), `mkdir -p test-{a,b,c}/subtest-{1,2,3}` (모든 가능한 조합으로 확장해 디렉터리 트리를 생성) 같은 예제들은 유용합니다. 144 | 145 | - 커맨드의 실행 결과 출력물은 `<(some command)`처럼 이용해서 파일처럼 다뤄질 수 있습니다. 예를 들어 로컬의 `/etc/hosts`를 리모트의 것과 비교하려면 다음처럼 하면 됩니다. 146 | ```bash 147 | diff /etc/hosts <(ssh somehost cat /etc/hosts) 148 | ``` 149 | 150 | - 스크립트를 적을 때 모든 코드를 대괄호 안에 넣을 수 있습니다. 닫는 괄호가 없으면 스크립트는 구문 에러가 되어 실행이 방지됩니다. 이는 스크립트가 웹으로부터 다운로드할 예정이라 할 때 도중까지만 다운로드된 파일이 실행 되는 걸 예방해 줍니다. 151 | ```sh 152 | { 153 | # 여기에 코드를 넣으세요 154 | } 155 | ``` 156 | 157 | - `cat << EOF...`같은 "here documents"에 대해서 알아두세요. 158 | 159 | - Bash에서 표준 출력(standard output)과 표준 에러(standard error) 둘 다 `some-command > logfile 2>&1`같은 명령어로 리다이렉트할 수 있습니다. 종종, 커맨드가 열린 파일 핸들을 남기지 않는 것을 확실히 하기 위해, 현재 작업 중인 터미널에서 명령어에 `>> 2+3 203 | 5 204 | ``` 205 | 206 | 207 | ## Processing files and data 208 | 209 | - 현재 디렉터리에서 파일을 이름으로 찾으려면 `find . -iname '*something*'` (또는 비슷하게)를 사용하면 됩니다. 어느 곳에 있든 파일을 이름으로 찾으려면 `locate something`을 사용하세요(하지만 인내를 가져야 합니다. `updatedb`가 최근에 생성된 파일을 인덱싱하지 않았을 수 있습니다). 210 | 211 | - 소스나 데이터 파일들에서 일반적인 검색을 할 때는(`grep -r`보다 더 복잡할 때), [`ag`](https://github.com/ggreer/the_silver_searcher)를 사용하세요. 212 | 213 | - HTML을 텍스트로 변환할 때는 `lynx -dump -stdin`를 사용하세요. 214 | 215 | - 마크다운, HTML, 그리고 모든 종류의 문서 변환에는 [`pandoc`](http://pandoc.org/)을 시도해보세요. 216 | 217 | - XML을 반드시 다뤄야한다면, `xmlstarlet`을 사용하세요. 오래되었지만 좋습니다. 218 | 219 | - JSON에는 [`jq`](http://stedolan.github.io/jq/)를 사용하세요. 220 | 221 | - YAML에는 [`shyaml`](https://github.com/0k/shyaml)를 사용하세요. 222 | 223 | - Excel이나 CSV파일에는 [csvkit](https://github.com/onyxfish/csvkit)가 `in2csv`, `csvcut`, `csvjoin`, `csvgrep`외 다른 도구들을 제공합니다. 224 | 225 | - Amazon S3를 다룰 때는 [`s3cmd`](https://github.com/s3tools/s3cmd)가 편리합니다. 그리고 [`s4cmd`](https://github.com/bloomreach/s4cmd)는 빠릅니다. Amazon의 [`aws`](https://github.com/aws/aws-cli)는 다른 AWS 관련 작업에 핵심적인 도구입니다. 226 | 227 | - `sort`와 `uniq`에 대해서 알아두세요. uniq의 `-u`, `-d`옵션을 포함해서 말이죠. 하단의 one-liner를 보세요. 그리고 `comm`도 보세요. 228 | 229 | - 텍스트 파일들을 다루는 `cut`, `paste` 그리고 `join`에 대해서 알아두세요. 많은 사람들이 `cut`을 사용하지만 `join`에 대해서는 잊고 있습니다. 230 | 231 | - `wc`를 이용해서 행(`-l`), 캐릭터(`-m`), 단어(`-w`) 그리고 바이트(`-c`)를 세는 것을 알아두세요. 232 | 233 | - `tee`를 이용해서 `ls -al | tee file.txt`처럼, 표준 입력(stdin)에서 복사해서 파일로 보내거나, 표준 출력(stdout)으로 보내는 것을 알아두세요. 234 | 235 | - 그룹, 필드 뒤집기, 통계적인 계산 같은 좀 더 복잡한 계산은 [`datamash`](https://www.gnu.org/software/datamash/)를 고려해보세요. 236 | 237 | - 로케일이 커맨드 라인 도구에 정렬 순서(collation)와 퍼포먼스를 포함해서 미묘하게 영향을 끼치는 것을 알아두세요. 대부분의 리눅스 설치는 `LANG`이나 다른 로케일 변수를 US English와 같은 로컬 세팅으로 설정합니다. 하지만 로케일을 바꿀 경우 정렬도 바뀔 것이라는 것에 주의하세요. 그리고 i18n 루틴들도 정렬이나 다른 커맨드들을 *몇 배* 느리게 할 수 있습니다. `export LC_ALL=C`를 사용하여, 어떤 상황에서는( 밑에 있는 집합(set) 작업이나, 유일성 작업등) i18n의 느린 루틴들을 통째로 안전하게 무시할 수 있습니다. 그리고 전통적인 바이트 기반의 정렬 순서를 사용할 수 있습니다. 238 | 239 | - `TZ=Pacific/Fiji date`처럼 특정 명령의 환경 변수를 실행 앞에 붙여 설정할 수 있습니다. 240 | 241 | - 간단한 데이터 조작을 할 때 `awk`와 `sed`를 이용하는 것을 알아두세요. 예를 들어 텍스트 파일의 세 번째 열의 숫자들의 모든 값을 더하는 것은 이렇게 합니다: `awk '{ x += $3 } END { print x }'`. 이 방법은 같은 일을 하는 파이썬 코드보다 3배 정도 빠르고, 1/3 정도의 길이밖에 안됩니다. 242 | 243 | - 여러 파일 안의 문자열을 바꾸려면 다음과 같이 하세요. 244 | ```sh 245 | perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt 246 | ``` 247 | 248 | - 여러 파일의 이름을 바꾸거나 검색하거나 문자열을 바꿀 때에는 [`repren`](https://github.com/jlevy/repren)를 써보세요. (어떤 경우에는 `rename` 명령을 사용해서 여러 파일의 이름을 바꿀 수도 있습니다. 하지만, 모든 리눅스 배포판에서 같은 동작을 하지 않는 것에 주의하세요.) 249 | ```sh 250 | # 파일 이름, 디렉터, 컨텐츠 모두 foo에서 bar로 변경 251 | repren --full --preserve-case --from foo --to bar . 252 | # 백업 파일을 whatever.bak에서 whatever로 복원 253 | repren --renames --from '(.*)\.bak' --to '\1' *.bak 254 | # 가능하다면 rename으로 위와 같은 일을 할 수 있음 255 | rename 's/\.bak$//' *.bak 256 | ``` 257 | 258 | - man 페이지가 이야기하듯, `rsync`는 정말 빠르고 다재다능한 파일 복사 도구입니다. 기기 간의 동기화에 사용하는 것으로 알려져 있지만, 로컬에서도 충분히 유용합니다. 보안 규정이 허용한다면, `scp` 대신 `rsync`를 사용하면 처음부터 전송하는 대신 중단된 지점부터 재전송할 수 있습니다. 또 많은 수의 파일을 삭제하는 [가장 빠른 방법](https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html)이기도 합니다. 259 | ```sh 260 | mkdir empty && rsync -r --delete empty/ some-dir && rmdir some-dir 261 | ``` 262 | 263 | - `shuf`를 사용해서 파일 안의 임의의 행을 선택하거나, 섞을 수 있습니다. 264 | 265 | - `sort`의 옵션을 알아두세요. `-n`은 숫자를 정렬할 때, `-h`는 사람이 읽을 수 있게 작성한 숫자의 경우(`du -h`와 같은 형태). 키가 어떻게 작동하는지 알아두세요(`-t`와 `-k`). 특별히, 첫 번째 필드로만 정렬해야 한다면 `-k1,1`을 적어야 한다는 걸 주의하세요. `-k1`은 모든 행에 대해서 정렬하라는 뜻입니다. 안정적인 정렬(`sort -s`)도 유용합니다. 예를 들어, 먼저 2번 필드로 정렬하고, 그다음에 1번 필드로 정렬할 경우, `sort -k1,1 | sort -s -k2,2`처럼 할 수 있습니다. 266 | 267 | - 만약 탭(tab)문자를 Bash 커맨드 라인에 사용해야 할 필요가 생길 경우(예를 들면 -t argument를 이용해 정렬 할 때), **ctrl-v** **[Tab]**키를 누르거나, `$'\t'`를 쓰세요(문자쪽이 복사나 붙여넣기를 할 수 있어 더 낫습니다.). 268 | 269 | - 소스 코드를 패치하는 기본 도구는 `diff`와 `patch`입니다. diff와 `sdiff`(새로 diff)의 통계 요약을 보려면 `diffstat`를 보세요. `diff -r`은 모든 디렉터리에 대해 작업을 수행하는 걸 알아두세요. `diff -r tree1 tree2 | diffstat`으로 변경 내역의 요약을 볼 수 있습니다. 270 | 271 | - 바이너리 파일을 간단하게 hex 덤프를 뜨고 싶을 때는 `hd`, `hexdump`, `xxd`를 쓰세요. 바이너리 파일을 수정할 때는 `bvi`, `biew`를 사용하세요. 272 | 273 | - `strings` (그리고 `grep`, 등) 을 사용해서 바이너리 파일 안에서 문자열 비트를 찾을 수 있습니다. 274 | 275 | - 바이너리 파일을 diff하려면(델타 압축), `xdelta3`를 사용하세요. 276 | 277 | - 텍스트 파일 인코딩을 변경하려면 `iconv`를 시도해보세요. 또는 `uconv`는 더 복잡한 목적에 사용할 수 있습니다. `uconv`는 몇 가지 복잡한 유니코드를 지원합니다. 예를 들어, 소문자화하고 모든 악센트를 제거하는(확장하고, 떨어트리는 것을 이용해서) 커맨드는 다음과 같습니다. 278 | ```sh 279 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt 280 | ``` 281 | 282 | - 파일을 여러 조각으로 나누려면 `split`(파일을 사이즈로 나눔)이나 `csplit`(파일을 패턴으로 나눔)을 보세요. 283 | 284 | - 날짜 시간 표현식을 제어하려면 [`dateutils`](http://www.fresse.org/dateutils/)의 `dateadd`, `datediff`, `strptime`등을 사용하세요. 285 | 286 | - `zless`, `zmore`, `zcat` 그리고`zgrep`을 이용해서 압축된 파일에 대해 작업하세요. 287 | 288 | - 파일 속성은 `chattr`로 설정할 수 있습니다. 이는 파일 권한에 대한 저레벨 대안입니다. 예를 들어 `sudo chattr +i /critical/directory/or/file`로 불변 플래그를 붙여 실수로 파일을 지우는 것을 방지할 수 있습니다. 289 | 290 | - `getfacl`, `setfacl`를 사용해 파일 권한을 저장하고 복원할 수 있습니다. 예를 들어, 291 | ```sh 292 | getfacl -R /some/path > permissions.txt 293 | setfacl --restore=permissions.txt 294 | ``` 295 | 296 | ## System debugging 297 | 298 | - 웹 디버깅을 위해서는 `curl` 와 `curl -I` 가 도움이 되고, `wget`도 꽤 도움이 됩니다. 그 외에 보다 현대적인 방식으로는 [`httpie`](https://github.com/jakubroztocil/httpie)이 있습니다. 299 | 300 | - cpu/디스크의 상태를 알기 위해서는 `top` (혹은 더 나은 명령어인 `htop`), `iostat`, `iotop`을 사용하세요. `iostat -mxz 15`를 사용해 기본 CPU와 파티션 디스크별 정보와 성능 정보를 알 수 있습니다. 301 | 302 | - 네트워크 상태를 자세히 알려면 `netstat`, `ss`를 사용하세요. 303 | 304 | - 시스템에 어떤 일이 일어났는지 보려면 `dstat`가 특히 유용합니다. 보다 시스템의 심층적인 면들을 보려면 [`glances`](https://github.com/nicolargo/glances)를 사용해보세요. 305 | 306 | - 메모리의 상태를 알아보려면 `free` 와 `vmstat`를 실행하고 그 결과를 해석해보세요. 특히, "cached" 값은 Linux kernel에 의해 file cache로 잡혀있는 메모리 라는 것을 알고 있어야 하고 그래서 "free"값에 대해서 보다 효율적으로 계산할 수 있습니다. 307 | 308 | - Java 시스템의 디버깅은 조금 다른 상황입니다. 하지만 Oracle과 그 외의 회사에서 만든 다른 JVM들에서는 `kill -3 `를 실행하면 전체 stack trace 정보와 heap의 정보(시기별로 가비지 컬렉터의 세부적인 내용 같은 매우 유용한 정보)를 요약하여 stderr나 로그로 출력해주므로 간단하게 정보를 얻어올 수 있습니다. JDK의 `jps`, `jstat`, `jstack`, `jmap` 명령은 유용합니다. [SJK tools](https://github.com/aragozin/jvm-tools)은 더 고급 정보를 다룰 수 있습니다. 309 | 310 | - 네트워크 이슈들을 알아보기 위해서는 traceroute를 사용할 수도 있지만 더 좋은 [`mtr`](http://www.bitwizard.nl/mtr/)를 사용하세요. 311 | 312 | - 디스크가 왜 가득 찼는지 알아보기 위해서 [`ncdu`](https://dev.yorhel.nl/ncdu)를 사용해보세요. 일반적으로 사용하는 `du -sh *`와 같은 커맨드를 사용하는 것보다는 시간을 줄일 수 있습니다. 313 | 314 | - 어떠한 소켓이나 프로세스가 사용하는 대역폭(bandwidth)를 찾아보려면 [`iftop`](http://www.ex-parrot.com/~pdw/iftop/)나 [`nethogs`](https://github.com/raboof/nethogs)를 사용하세요. 315 | 316 | - `ab`라는 툴(Apache에 딸려있는)은 신속하고 간단하게(quick-and-dirty) 웹서버의 성능을 체크하는데 유용합니다. 보다 복잡한 부하 테스트를 할 때는 `siege`를 사용해보세요. 317 | 318 | - 보다 심각한 경우의 네트워크 디버깅을 위해서는 [`wireshark`](https://wireshark.org/), [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html), [`ngrep`](http://ngrep.sourceforge.net/)를 사용하세요. 319 | 320 | - `strace` 와 `ltrace`에 대해서 알아보세요. 이 커맨드들은 만일 어떤 프로그램에서 failing, hanging 혹은 crashing이 일어나거나 그 외에 여러분이 무슨 이유인지 알지 못하는 상황이나 성능에 대한 대략적인 내용을 얻고자 할 때 유용할 것입니다. 특히 프로파일링을 위한 옵션(`-c`)과 현재 실행 중인 프로세스에 붙이기 위한 옵션(`-p`)을 기억하세요. 321 | 322 | - 공유 라이브러리(shared libraries) 등을 체크하기 위해서는 `ldd`에 대해 알아보세요. 323 | 324 | - `gdb`를 가지고 현재 실행 중인 프로세스에 연결하고 그 프로세스의 stack trace들을 얻는 방법을 알아보세요. 325 | 326 | - `/proc`를 사용하세요. 이것은 현재 발생하고 있는 문제를 디버깅할 때 종종 놀랍도록 큰 도움이 될 것입니다. 예시:`/proc/cpuinfo`, `/proc/meminfo`, `/proc/cmdline`, `/proc/xxx/cwd`, `/proc/xxx/exe`, `/proc/xxx/fd/`, `/proc/xxx/smaps` (`xxx`는 프로세스 id나 pid입니다). 327 | 328 | - 과거에 왜 무엇인가가 잘못되었는지를 디버깅할 때에는 [`sar`](http://sebastien.godard.pagesperso-orange.fr/)가 매우 유용할 것입니다. 이 커맨드는 CPU, memory, network 등의 통계 내역을 보여줍니다. 329 | 330 | - 시스템의 보다 깊은 곳을 보거나 퍼포먼스를 분석하기 위해서는, `stap` ([SystemTap](https://sourceware.org/systemtap/wiki)), [`perf`](http://en.wikipedia.org/wiki/Perf_(Linux)), [`sysdig`](https://github.com/draios/sysdig)를 사용해보세요. 331 | 332 | - 여러분이 사용하는 Linux의 배포판이 무엇인지 확인(대부분의 배포판에서 작동합니다)하려면 `uname`이나 `uname -a` 또는 `lsb_release -a`를 사용하세요. 333 | 334 | - 언제든지 무언가가 정말로 재미있는 반응을 보인다면 `dmesg`를 사용해보세요(아마도 하드웨어나 드라이버의 문제일 것입니다). 335 | 336 | - 파일을 삭제했는데 `du`로 확인해 예상한 디스크 공간을 확보하지 못했다면, 파일이 프로세스에 의해 사용 중인지 확인해보세요. 337 | `lsof | grep deleted | grep "filename-of-my-big-file"` 338 | 339 | 340 | ## One-liners 341 | 342 | 커맨드들을 한데 묶어서 사용하는 예제들 343 | 344 | - `sort`/`uniq`를 사용하여 텍스트 파일의 교차점, 조합, 차이점을 확인이 필요할 때 상당한 도움이 될 겁니다. 가령 `a`와 `b`가 유일한 값들만을 가진 텍스트 파일이라 합시다. 이것이 임의의 크기인 파일을(그게 기가바이트라고 해도) 빠르게 작업할 수 있습니다. (Sort는 메모리 제한에 걸리지 않습니다만, 만약 루트 파티션이 작은 경우, `/tmp`를 사용하기 위해 `-T`옵션을 사용하면 됩니다.) 위의 `LC_ALL`에대한 내용은 `sort`의 `-u`옵션을 확인하십시오. (아래 예제에 집중하기 위해서 생략) 345 | ```sh 346 | cat a b | sort | uniq > c # c is a union b 347 | cat a b | sort | uniq -d > c # c is a intersect b 348 | cat a b b | sort | uniq -u > c # c is set difference a - b 349 | ``` 350 | 351 | - `grep . *`을 사용해서 디렉터리 안의 모든 파일을 비주얼하게 살펴볼 수 있습니다.(r각 줄은 파일 이름과 같이 나옵니다) 아니면 `head -100 *`를 이용할 수도 있습니다.(각 파일의 해더만 볼 수 있습니다.) 이는 `/sys`, `/proc`, `/etc` 같이 설정값들로 가득한 디렉터리에서 유용합니다. 352 | 353 | 354 | - 텍스트 파일의 세 번째 열의 숫자들의 모든 값을 더하는 것은 이렇게 합니다. 이 방법은 같은 일을 하는 파이썬 코드보다 3배 정도 빠르고, 1/3 정도의 길이밖에 안됩니다. 355 | ```sh 356 | awk '{ x += $3 } END { print x }' myfile 357 | ``` 358 | 359 | - 파일 트리에서 크기와 날짜를 보려면 이렇게 하세요. 이 명령어는 `ls -l`을 재귀적으로 수행하는 것과 같지만, `ls -lR`보다 더 읽기 쉽습니다. 360 | ```sh 361 | find . -type f -ls 362 | ``` 363 | 364 | - 웹서버 로그 같은 텍스트 파일이 있다고 합시다. 그리고 URL 파라미터에 나타나는 `acct_id`같은 특정 값이 몇몇 행에 나타난다고 해보죠. 각각의 `acct_id`에 대해 얼마나 많은 요청이 있었는지 알고 싶다면 다음처럼 할 수 있습니다. 365 | ```sh 366 | cat access.log | egrep -o 'acct_id=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -rn 367 | ``` 368 | 369 | - 변경을 계속 모니터링하려면 `watch`를 이용하세요. 예를 들어 `watch -d -n 2 'ls -rtlh | tail'`로 한 디렉터리 내의 파일 변경을 확인하거나, `watch -d -n 2 ifconfig`로 와이파이 설정을 고칠 때 네트워크 설정 변경을 확인할 수 있습니다. 370 | 371 | - 다음 함수를 실행하면 이 문서에 있는 팁 중 임의의 것을 얻을 수 있습니다(마크다운을 파싱하고 항목을 추출합니다). 372 | ```sh 373 | function taocl() { 374 | curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md | 375 | pandoc -f markdown -t html | 376 | xmlstarlet fo --html --dropdtd | 377 | xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 378 | xmlstarlet unesc | fmt -80 379 | } 380 | ``` 381 | 382 | 383 | ## Obscure but useful 384 | 385 | - `expr`: 산술적이거나 논리적인 작업을 수행하거나 정규표현식을 검증할때 사용합니다 386 | 387 | - `m4`: 간단한 메크로 수행기를 실행합니다 388 | 389 | - `yes`: 어떠한 한 문장을 매우 많이 출력합니다 390 | 391 | - `cal`: 간단한 달력을 보여줍니다 392 | 393 | - `env`: 어떤 한 커맨드를 실행합니다(스크립트를 만들때 유용합니다) 394 | 395 | - `printenv`: 환경 변수들을 출력합니다(디버깅을 할때나 스크립트를 만들때 유용합니다) 396 | 397 | - `look`: 어떤 문자열로 시작하는 영단어(혹은 파일의 어떤 한 줄)을 찾습니다 398 | 399 | - `cut `, `paste`, `join`: 데이터를 수정할때 사용합니다 400 | 401 | - `fmt`: 문단의 서식을 지정합니다 402 | 403 | - `pr`: 문서의 페이지나 컬럼 서식을 지정합니다 404 | 405 | - `fold`: 문서의 각 라인들을 특정한 길이에 맞게 수정합니다 406 | 407 | - `column`: 문서의 컬럼이나 테이블의 서식을 지정합니다 408 | 409 | - `expand`, `unexpand`: 탭을 공백으로 바꾸어주거나 공백을 탭으로 바꾸어줍니다 410 | 411 | - `nl`: 줄 번호를 추가해줍니다 412 | 413 | - `seq`: 숫자들을 출력하는데 사용합니다 414 | 415 | - `bc`: 간단한 계산기를 실행합니다 416 | 417 | - `factor`: 정수들을 인수분해하는데 사용합니다 418 | 419 | - [`gpg`](https://gnupg.org/): 파일들을 암호화하고 서명하는데 사용합니다 420 | 421 | - `toe`: terminfo 엔트리들의 테이블(table of terminfo entries) 422 | 423 | - `nc`: 네트워크를 디버깅하거나 데이터를 전송할 때 사용합니다 424 | 425 | - `socat`: 소켓 릴레이나 TCP 포트로 내용을 전달할 때 사용합니다(`netcat`과 비슷합니다) 426 | 427 | - [`slurm`](https://github.com/mattthias/slurm): 네트워크 상황을 시각화하여 보여줍니다 428 | 429 | - `dd`: 파일들이나 디바이스들 간에 데이터를 옮길때 사용합니다 430 | 431 | - `file`: 파일의 종류를 알아내는데 사용합니다 432 | 433 | - `tree`: 디렉터리들과 그 하위 디렉터리를 마치 ls를 반복적으로 입력한 것처럼 트리의 형태로 보여줍니다 434 | 435 | - `stat`: 파일의 정보를 보여줍니다 436 | 437 | - `time`: 명령을 실행하고 시간을 잽니다 438 | 439 | - `timeout`: 특정 시간만큼 명령을 실행하고 시간이 끝나면 프로세스를 종료합니다. 440 | 441 | - `lockfile`: `rm -f`로만 지울 수 있는 세마포어 파일을 생성합니다 442 | 443 | - `logrotate`: 로그를 로테이트, 압축, 메일로 보냅니다 444 | 445 | - `watch`: 명령을 반복적으로 실행해 결과를 보여주거나 변경을 하일라이트합니다 446 | 447 | - `tac`: 파일의 내용을 역순으로 출력합니다 448 | 449 | - `shuf`: 파일의 각 줄들을 임의의 순서로 출력합니다 450 | 451 | - `comm`: 정렬된 파일들을 각 라인별로 비교합니다 452 | 453 | - `pv`: 파이프를 통해서 프로세스의 정보를 모니터링하는데 사용합니다 454 | 455 | - `hd` and `bvi`: 바이너리 파일을 수정하거나 덤프를 얻어오는데 사용합니다 456 | 457 | - `strings`: 바이너리 파일들에서 특정 문장을 추출하는데 사용합니다 458 | 459 | - `tr`: 문자를 변환하거나 조작하는데 사용합니다 460 | 461 | - `iconv` or `uconv`: 문서의 인코딩방식을 변환하는데 사용합니다 462 | 463 | - `split `and `csplit`: 파일들을 쪼개는데 사용합니다 464 | 465 | - `sponge`: 쓰기 전에 모든 입력을 읽습니다. 같은 파일에서 읽은 후에 쓰기에 유용합니다. 예를 들면 `grep -v something some-file | sponge some-file`처럼 사용할 수 있습니다. 466 | 467 | - `units`: 단위를 변환하거나 계산하는데 사용합니다 예를들어 furlongs/fortnight 단위를 twips/blink로 변환합니다 (`/usr/share/units/definitions.units`를 참고하세요) 468 | 469 | - `apg`: 렌덤 패스워드를 생성합니다 470 | 471 | - `xz`: 고효율의 파일 압축프로그램입니다 472 | 473 | - `ldd`: 동적 라이브러리들의 정보를 보여줍니다 474 | 475 | - `nm`: 오브젝트 파일들에 포함된 심볼정보를 얻어옵니다 476 | 477 | - `ab`: 웹 서버를 벤치 마킹하는데 사용합니다 478 | 479 | - `strace`: 시스템 콜을 디버깅할때 사용합니다 480 | 481 | - [`mtr`](http://www.bitwizard.nl/mtr/): 네트워크 디버깅시에 traceroute보다 더 낫습니다 482 | 483 | - `cssh`: 쉘을 동시에 여러개 사용할때 사용합니다 484 | 485 | - `rsync`: SSH를 이용해 원격 파일 시스템이나, 로컬 파일시스템의 파일과 폴더들을 동기화 할때 사용합니다 486 | 487 | - [`wireshark`](https://wireshark.org/), [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html): 패킷정보를 가져오며 네트워킹을 디버깅하는데 사용합니다 488 | 489 | - [`ngrep`](http://ngrep.sourceforge.net/): 네트워크 환경에서 grep과 같은 역할을 합니다 490 | 491 | - `host`, `dig`: DNS 정보를 보여줍니다 492 | 493 | - `lsof`: 프로세스 파일 디스크립터와 소켓의 정보를 보여줍니다 494 | 495 | - `dstat`: 유용한 시스템 정보를 보여줍니다 496 | 497 | - [`glances`](https://github.com/nicolargo/glances): 보다 고차원의 여러 서브시스템들의 정보를 한번에 보여줍니다 498 | 499 | - `iostat`: 디스크의 사용량 정보를 보여줍니다 500 | 501 | - `mpstat`: CPU 사용량 정보를 보여줍니다. 502 | 503 | - `vmstat`: 메모리 사용량 정보를 보여줍니다. 504 | 505 | - `htop`: 보다 개선된 형태의 top을 보여줍니다 506 | 507 | - `last`: 로그인 했던 정보들을 보여줍니다 508 | 509 | - `w`: 현재 누가 로그인했는지 보여줍니다 510 | 511 | - `id`: 현재 유저나 그룹에 대한 식별 정보를 보여줍니다 512 | 513 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/): 시스템 상태에 대한 정보를 보여줍니다 514 | 515 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/), [`nethogs`](https://github.com/raboof/nethogs): 소켓 또는 프로세스를 이용하여 네트워크를 정보를 보여줍니다 516 | 517 | - `ss`: 소켓에 관한 통계자료들을 보여줍니다 518 | 519 | - `dmesg`: 부팅 메시지와 시스템 에러 메시지들을 보여줍니다 520 | 521 | - `sysctl`: 실행 시에 리눅스 커널 파라미터를 보여주거나 설정합니다 522 | 523 | - `hdparm`: SATA/ATA disk들의 정보를 수정하거나 그것들이 작동하도록 합니다 524 | 525 | - `lsblk`: 블록 디바이스들의 목록을 보여줍니다 : 여러분의 디스크들이나 디스크파티션들을 트리의 형태로 보여줍니다 526 | 527 | - `lshw`, `lscpu`, `lspci`, `lsusb`, `dmidecode`: CPU, BIOS, RAID, graphics, devices 등의 하드웨어 정보를 보여줍니다 528 | 529 | - `lsmod`, `modifno`: 커널 모듈의 상세정보를 목록으로 보여줍니다. 530 | 531 | - `fortune`, `ddate`, `sl`: 에... 증기기관차를 생각하고있고 그것을 인용하고 싶다면 이것은 "유용"합니다 532 | 533 | 534 | ## macOS only 535 | 536 | *OS X에서만* 해당되는 항목입니다. 537 | 538 | - `brew` (Homebrew)나 `port` (MacPorts)를 패키지 매니저로 사용합니다. 위의 많은 명령어를 OS X에 설치하여 사용할 수 있습니다. 539 | 540 | - `pbcopy`를 이용하여 데스크톱 애플리케이션에 명령어 출력물을 복사하거나 `pbpaste`를 이용해 붙여넣기를 할 수 있습니다. 541 | 542 | - OS X 터미널에서 옵션 키를 알트 키(**alt-b**, **alt-f** 같은 위에 나온 명령)로 사용하려면 Preferences -> Profiles -> Keyboard를 열어 "Use Option as Meta key"를 선택하세요. 543 | 544 | - 데스크톱 애플리케이션에서 파일을 열기위해, `open` 또는 `open -a /Applications/Whatever.app`을 사용하면 됩니다. 545 | 546 | - Spotlight: `mdfind`를 이용해 파일을 찾고, `mdls`를 이용해 메타데이타 (사진 EXIF 정보와 같은) 목록을 볼 수 있습니다. 547 | 548 | - OS X는 BSD Unix 기반이며 많은 명령어들을 (예로 `ps`, `ls`, `tail`, `awk`, `sed`) 사용할 수 있으며, 이것들은 Linux 버전들과 미묘한 차이가 있습니다. 그리고 크게는 System V-style Unix와 GNU 도구들에 많은 영향을 받았습니다. 이런 내용들을 man 페이지 상단의 "BSD General Commands Manual." 라는 문구를 통해 알 수 있습니다. 가끔은 GNU 버전이 설치되기도 합니다. (예로, GNU awk와 sed인 `gawk`와 `gsed`에서). 만약 이종 플랫폼 간 Bash 스크립트를 작성하려면, 동일한 명령어 (예로, 파이썬이나 `perl`과 같은)나 테스트시 주의해야 합니다. 549 | 550 | - OS X 릴리스 정보를 얻으시려면, `sw_vers`를 사용하세요. 551 | 552 | ## Windows only 553 | 554 | Windows*에서만* 해당되는 항목입니다. 555 | 556 | - Windows 10에서는 [Bash on Ubuntu on Windows](https://msdn.microsoft.com/commandline/wsl/about)를 사용할 수 있습니다. 이는 유닉스 커맨드 라인 도구와 함께 친숙한 Bash 환경을 제공합니다. 좋은 점은, 리눅스 프로그램을 Windows에서 사용할 수있게 합니다. 하지만 Bash에서 Windows 프로그램을 사용할 수는 없습니다. 557 | 558 | - [Cygwin](https://cygwin.com/)를 설치해 Microsoft Windows에서 유닉스 셸을 사용할 수 있습니다. 이 문서에 기술된 대부분의 것들은 그대로 동작할 것입니다. 559 | 560 | - Cygwin의 패키지 매니저로 유닉스 프로그램을 더 설치할 수 있습니다. 561 | 562 | - 커맨드 라인 창으로 `mintty`를 사용하세요. 563 | 564 | - Windows의 클립보드를 `/dev/clipboard`로 접근할 수 있습니다. 565 | 566 | - `cygstart`을 실행해 등록된 애플리케이션을 사용해 임의의 파일을 열 수 있습니다. 567 | 568 | - Windows 레지스트리는 `regtool`로 접근할 수 있습니다. 569 | 570 | - `C:\\` Windows 드라이브 경로는 Cygwin에서는 `/cygdrive/c`가 되고, Cygwin의 `/` Windows에서 `C:\cygwin`가 되는것을 알아 두세요. Cygwin과 Windows 스타일의 파일 패스는 `cygpath`로 변환할 수 있습니다. 이는 Windows 프로그램을 실행하는 프로그램에서 유용하게 사용됩니다. 571 | 572 | - You can perform and script most Windows system administration tasks from the command line by learning and using `wmic`. 573 | 574 | - Windows에서 유닉스 룩엔필을 얻는 다른 대안은 [Cash](https://github.com/dthree/cash)입니다. 이 환경에는 매우 적은 유닉스 명령과 커맨드 라인 옵션만 사용가능하니 주의하세요. 575 | 576 | - Windows에서 GNU 개발자 툴(GCC같은)을 얻는 다른 대안으로 [MinGW](http://www.mingw.org/)와 거기에 포함된 [MSYS](http://www.mingw.org/wiki/msys) 패키지가 있습니다. 여기에는 bash, gawk, make, grep같은 도구가 포함됩니다. MSYS는 Cygwin에 비교하면 모든 기능은 없습니다. MinGW는 유닉스 툴을 네이티브 Windows로 포팅할 때 부분적으로 유용합니다. 577 | 578 | ## More resources 579 | 580 | - [awesome-shell](https://github.com/alebcay/awesome-shell): 셸에 대한 툴과 리소스들이 잘 정리되어 있는 리스트입니다. 581 | - [awesome-osx-command-line](https://github.com/herrbischoff/awesome-osx-command-line): OS X 커맨드 라인에 관해 더 깊이 알수 있는 가이드 입니다. 582 | - [Strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/): 보다 나은 셸 스크립트를 작성하기 위한 정보글입니다. 583 | - [shellcheck](https://github.com/koalaman/shellcheck): 셸 스크립트 정적 분석 도구 입니다. 특히, bash/sh/zsh에 대한 린트입니다. 584 | - [Filenames and Pathnames in Shell](http://www.dwheeler.com/essays/filenames-in-shell.html): 셸 스크립트에서 파일 이름을 처리하는 법을 다루는 슬프도록 복잡한 미니츄어입니다. 585 | - [Data Science at the Command Line](http://datascienceatthecommandline.com/#tools): 같은 이름의 책에서 나온, 데이터 사이언스를 위한 더 나은 명령과 도구들 입니다. 586 | 587 | 588 | ## Disclaimer 589 | 590 | 매우 작은 작업을 제외한 코드들은 다른 사람이 읽을 수 있도록 작성됩니다. 큰 힘에는 책임이 따릅니다. Bash에서 뭔가를 *할 수 있다는* 것은 Bash로 해야 된다는 의미가 아닙니다! ;) 591 | 592 | 593 | ## License 594 | 595 | [![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 596 | 597 | 이 저작물은 [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)에 따라 이용할 수 있습니다. 598 | -------------------------------------------------------------------------------- /README-pt.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | # A arte da linha de comando 5 | 6 | - [Meta](#meta) 7 | - [Básico](#básico) 8 | - [Uso diário](#uso-diário) 9 | - [Processamento de arquivos e dados](#processamento-de-arquivos-e-dados) 10 | - [Debugando o sistema](#debugs-do-sistema) 11 | - [One-liners](#one-liners) 12 | - [Obscuros mas úteis](#obscuros-mas-úteis) 13 | - [Mais conteúdo](#mais-conteúdo) 14 | - [Aviso](#aviso) 15 | 16 | 17 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 18 | 19 | Fluência na linha de comando é uma habilidade muitas vezes negligenciada ou considerada obsoleta, porém ela aumenta sua flexibilidade e produtividade como *desenvolvedor* de diversas maneiras, sutis ou não. Este texto descreve uma seleção de notas e dicas de uso da linha de comando que me parecem muito uteis, quando usando o Linux. Algumas dicas são elementares, e outras são mais específicas, sofisticadas ou obscuras. Esta página é curta, mas se você souber usar e lembrar todos os items que estão aqui, então você está mandando bem. 20 | 21 | Muito do que está aqui [originalmente](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands) 22 | [apareceu](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix) 23 | no [Quora](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know), 24 | mas dado o interesse por lá, me pareceu importante usar o Github, onde pessoas mais talentosas do que eu, poderiam sugerir melhorias facilmente. Se você descobrir um erro ou algo que poderia ser melhorado, por favor abra um issue ou um PR! (E claro, por favor veja as `meta sections' e PRs/issues existentes, primeiro.) 25 | 26 | ## Meta 27 | 28 | Escopo: 29 | 30 | - Este guia é destinado tanto aos iniciantes quanto aos usuários mais experientes. Os objetivos são *abrangência* (tudo que é importante), *especificidade* (dar exemplos concretos dos casos de usos mais comuns), e *concisão* (evitar coisas que não são tão essenciais ou digressões que você pode facilmente encontrar pela Internet). Todas as dicas são essenciais em alguma situação ou trazem uma economia notável de tempo em relação a outras alternativas. 31 | - Este guia é escrito para o Linux. Muitos, mas não todos os items, se aplicam igualmente para o MacOS (ou mesmo o Cygwin). 32 | - O foco está na interatividade com Bash, embora muitas dicas aqui sejam aplicáveis a outras `shells' e também a scripts em Bash, em geral. 33 | - Incluímos tanto comandos no Unix "padrão", quanto comandos que requeiram instalação de pacotes adicionais -- desde que estes sejam importantes o suficiente para merecerem sua inclusão nessa lista. 34 | 35 | Notas: 36 | 37 | - Para manter este guia em uma única página, o conteúdo implícito será incluído por referência. Você é competente o suficiente para verificar mais detalhes em outros lugares, desde que você já tenha entendido a ideia ou saiba o que procurar no Google. Use `apt-get`, `yum`, `dnf`, `pacman`, `pip` ou `brew` (quando adequado) para instalar novos programas. 38 | - Use [Explainshell](http://explainshell.com/) para encontrar informações úteis sobre o que fazem os comandos, as opções, pipes, etc. 39 | 40 | 41 | ## Básico 42 | 43 | - Aprenda o básico sobre Bash. Na verdade, digite `man bash` e pelo menos entenda superficialmente o seu funcionamento; é bastante simples de ler e nem é tão grande assim. Shells alternativas podem ser legais, mas Bash é a mais poderosa e sempre está disponível (aprender *somente* zsh, fish, etc, é tentador quando você usa o seu próprio notebook, mas restringe você em muitas situações, por exemplo quando você quer usar servidores de outros). 44 | 45 | - Aprenda bem pelo menos um editor de texto tradicional. Idealmente o Vim (`vi`), já que nenhum outro funciona tão bem nos terminais aleatórios que a gente encontra por aí (mesmo que você prefira usar o Emacs, um IDE, ou um editor hipster a maior parte do tempo). 46 | 47 | - Saiba como ler a documentação com o `man` (para os curiosos, `man man` lista os números das seções, por exemplo, 1 se refere aos comandos "regulares", 5 é sobre arquivos/convenções, e 8 diz respeito a administração). Procure outros documentos do manual com o `apropos`. Saiba que alguns dos comandos não são executáveis, mas sim built-ins (embutidos) no bash, pra esses você poderá conseguir ajuda com `help` e `help -d`. 48 | 49 | - Aprenda como fazer redirecionamento de saída e entrada usando `>` e `<` e pipes usando `|`. Aprenda sobre o stdout e stdin. 50 | 51 | - Aprenda sobre a expansão de arquivos glob com `*` ( e talvez `?` e `{`...`}`) e entenda as diferenças entre aspas duplas `"` e aspas simples `'`. (Veja mais em variáveis de expansão abaixo.) 52 | 53 | - Se familiarize com o gerenciamento de jobs em Bash: `&`, **ctrl-z**, **ctrl-c**, `jobs`, `fg`, `bg`, `kill`, etc. 54 | 55 | - Aprenda `ssh`, e o básico de autenticação sem senha, através do `ssh-agent`, `ssh-add`, etc. 56 | 57 | - Gerenciamento básico de arquivos: `ls` e `ls -l` (em particular, aprenda o que cada coluna no `ls -l` significa), `less`, `head`, `tail` e `tail -f` (ou melhor ainda, `less +F`), `ln` e `ln -s`(aprenda as diferenças e vantagens de soft links comparados a hard links), `chown`, `chmod`, `du` (para um rápido resumo do uso do disco: `du -sk *`). Para gerenciamento do sistema de arquivos, `df`, `mount`, `fdisk`, `mkfs`, `lsblk`. 58 | 59 | - Gerenciamento básico da rede: `ip` ou `ifconfig`, `dig`. 60 | 61 | - Saiba bem como usar expressões regulares, e as várias flags para `grep`/`egrep`. As `-i`, `-o`, `-A`, e `-B` são opções que é importante conhecer. 62 | 63 | - Aprenda a usar `apt-get`, `yum`, `dnf` ou `pacman` (dependendo da distribuição) para procurar e instalar pacotes. E garanta que você possui o `pip` para instalar ferramentas baseadas em Python (algumas das abaixo são mais fáceis de instalar através do `pip`). 64 | 65 | 66 | ## Uso diário 67 | 68 | - Usando Bash, use **Tab** para completar argumentos e **ctrl-r** para pesquisar através a história dos comandos. 69 | 70 | - Em Bash, utilize **ctrl-w** para deletar a última palavra, e **ctrl-u** para deletar tudo e voltar para o início da linha. Use **alt-b** e **alt-f** para se mover por palavras, **ctrl-k** para apagar até o final da linha, **ctrl-l** para limpar a tela. Consulte `man readline` para todos os keybindings padrões do Bash. Existem muitos. Por exemplo **alt-.** circula através dos argumentos anteriores, e **alt-*** expande um glob. 71 | 72 | - Alternativamente, se você adora os keybinds do vi, use `set -o vi`. 73 | 74 | - Para ver os comandos recentes, `history`. Existem também muitas abreviações como `!$` (último argumento) e `!!` último comando, embora estes sejam muitas vezes facilmente substituídos por **ctrl-r** e **alt-.**. 75 | 76 | - Pra voltar para o diretório anterior de trabalho: `cd -`. 77 | 78 | - Se você está na metade do caminho ao digitar um comando, mas mudou de ideia, tecle **alt-#** para adicionar um `#` ao início da linha e definir esta como um comentário (ou use **ctrl-a**. **#**. **enter**). Mais tarde você poderá recuperar o comando através da `history`. 79 | 80 | - Use `xargs` (ou `parallel`). Estes são muito poderosos. Note que você pode controlar como os vários items são executados por linha (`-L`) assim como o paralelismo (`-P`). Se você não tem certeza se isto é a coisa certa a se fazer, use `xargs echo` primeiro. O `-I{}` também é muito útil. Exemplos: 81 | ```bash 82 | find . -name '*.py' | xargs grep some_function 83 | cat hosts | xargs -I{} ssh root@{} hostname 84 | ``` 85 | 86 | - `pstree -p` é um modo de visualização muito útil da árvore de processos. 87 | 88 | - Use `pgrep` e `pkill` para procurar ou sinalizar os processo pelo seu nome (`-f` é muito útil). 89 | 90 | - Saiba os vários sinais que você pode enviar para um processo. Por exemplo, para suspender um processo, use `kill -STOP [pid]`. Para saber a lista completas dos sinais, veja `man 7 signal`. 91 | 92 | - Use `nohup` ou `disown` se você deseja por o processo no background, executando para sempre. 93 | 94 | - Verifique quais processos estão escutando através de `netstat -lntp` ou `ss -plat` (para TCP; adicione `-u` para UDP). 95 | 96 | - Veja também `lsof` para abrir sockets e arquivos. 97 | 98 | - Em scripts Bash, use `set -x` para debugar a saída. Utilize modos estritos sempre que for possível. Use `set -e` para abortar em caso de erros. Use `set -o pipefail` para também ser restrito a respeito dos erros (embora este tópico seja um pouco sútil). Para scripts mais desenvolvidos, use também `trap`. 99 | 100 | - Em Bash scripts, subshells (escrito com parênteses) são formas convenientes de agrupar comandos. Um exemplo comum é temporariamente se mover para um diretório de trabalho diferente, e.g. 101 | ```bash 102 | # faz algo no diretório corrente 103 | (cd /some/other/dir && other-command) 104 | # continua no diretório atual 105 | ``` 106 | 107 | - No Bash, note que existem muitos tipos de variáveis de expansão. Verificando a existência de uma variável: `${name:?error_messages}`. Por exemplo, se um script Bash requer um único argumento, apenas escreva `input_file=${1:?usage: $0 input_file}`. Expansões aritméticas: `i=$(( (i + 1) % 5 ))`. Sequências: `{1..10}`. Aparando as strings: `${var%suffix}` e `${var#prefix}`. Por exemplo, se `var=foo.pdf`, então `echo ${var%.pdf}.txt` imprime `foo.txt`. 108 | 109 | - A saída de um comando pode ser tratada como um arquivo através `<(algum comando)`. Por exemplo, comparar um arquivo local `/etc/hosts` com um remoto: 110 | ```sh 111 | diff /etc/hosts <(ssh somehost cat /etc/hosts) 112 | ``` 113 | 114 | - Saiba sobre "documentos aqui" no Bash, como em `cat <logfile 2> $1`. Muitas vezes, para garantir que um comando não deixa um arquivo aberto para manipular a entrada padrão, digitando isso no terminal que você está, é uma boa prática adicionar um ` foo: 188 | rename 's/\.bak$//' *.bak 189 | # Renomea completamente o nome dos arquivos, diretórios, e outros conteúdos foo -> bar: 190 | repren --full --preserve-case --from foo --to bar . 191 | ``` 192 | 193 | - Utilize o `shuf` para embaralhar ou selecionar linhas randoms de um arquivo. 194 | 195 | - Para as opções do `sort`. Aprenda com as chaves (`-t` e `-k`). Em particular, saiba que precisa escrever `-k1,1` para ordenar somente o primeiro campo; `-k1` significa ordenar de acordo com a linha inteira. 196 | 197 | - Ordenação estável (`sort -s`) pode ser útil. Por exemplo, para ordenar primeiramente pelo campo 2, então secundariamente pelo campo 1, você pode usar `sort -k1,1 | sort -s -k2,2`. 198 | 199 | - Se você precisa escrever literalmente um tab na linha de comando no Bash (por exemplo, para o argumento -t do `sort`), pressione **ctrl-v** **[Tab]** ou escreva `$'\t'` (o último é melhor pois você pode copiar e colar ele). 200 | 201 | - As ferramentas padrão para extrair patches de códigos fonte são `diff`e `patch`. Veja também `diffstat` para um resumo de estatísticas de um diff. Note que `diff -r` funciona para diretórios inteiros. Use `diff -r tree1 tree2 | diffstat` para um resumo das alterações. 202 | 203 | - Para arquivos binários, use `hd` para um simples dump hexadecimal e `bvi` para edição binária. 204 | 205 | - Também para arquivos binários, `strings` (mais `grep`, etc.) deixa você encontrar pedaços de texto. 206 | 207 | - Para diffs binários (compressão delta), use `xdelta3.` 208 | 209 | - Para converter a codificação de textos, tente `iconv`. Ou `uconv` para uso mais avançado; Este suporta algumas funcionalidades avançadas do Unicode. Por exemplo, este comando transforma o texto para minúsculo e remove todos os acentos (expandindo e removendo eles): 210 | ```sh 211 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt 212 | ``` 213 | 214 | - Para dividir um arquivo em pedaços, veja `split` (para dividir por tamanho) e `csplit` (para dividir por um padrão). 215 | 216 | Use `zsless`, `zmore`, `zcat`, and `zgrep` para manipular arquivos comprimidos. 217 | 218 | 219 | ## Debugando o sistema 220 | 221 | - Para web debug, `curl` e `curl -I` são úteis, ou os equivalentes `wget`, or uma alternativa mais moderna [`httpie`](https://github.com/jakubroztocil/httpie). 222 | 223 | - Para saber o status do disco/cpu/rede, use `iostat`, `netstat`, `top` (ou o `htop` como alternativa melhor), e (especialmente) `dstat`. Bom para obter uma ideia rápida do que está acontecendo em um sistema. 224 | 225 | - Para um resumo mais aprofundado do sistema, use [`glances`](https://github.com/nicolargo/glances). Este lhe apresenta vários níveis de estatísticas do sistema em uma janela do terminal. Muito útil para uma rápida verificação em vários subsistemas. 226 | 227 | - Para saber o status da memória, execute e entenda a saída do `free` `vmstat`. Em particular, esteja ciente de que o valor "cached", é mantido pelo kernel Linux como um arquivo de cache, então este efetivamente conta como um valor de memória disponível. 228 | 229 | - Debugar um sistema java é uma outra historia, mas um simples truque nas máquinas virtuais Oracle ou algum outro tipo de JVM é que você pode executar `kill -3 ` e um completo rastreamento da pilha(stack trace) e resumo do heap (incluindo detalhes geracionais do garbage collector, os quais podem ser altamente informativos) serão vazados para stderr/logs. 230 | 231 | - Use [`mtr`](http://www.bitwizard.nl/mtr/) como uma melhor alternativa ao traceroute, para identificar problemas na rede. 232 | 233 | - Para verificar o porque de um disco estar cheio, [`ncdu`](https://dev.yorhel.nl/ncdu) economiza bastante tempo em comparação aos comandos usuais como `du -sh *`. 234 | 235 | - Para procurar qual socket ou processo está utilizando a banda de rede, tente [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) ou [`nethogs`](https://github.com/raboof/nethogs). 236 | 237 | - A ferramenta `ab` (que vem com o Apache) é muito útil para verificação rápida da performance do servidor web. Para mais complexos testes de carga, tente `siege`. 238 | 239 | - Para debugs mais sérios da rede, [`wireshark`](https://wireshark.org/), [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html), ou [`ngrep`](http://ngrep.sourceforge.net/). 240 | 241 | - Aprenda a respeito do `strace`e `ltrace`. Estes podem ser úteis se um programa está falhando, travado, ou quebrando, e você não sabe o por que, ou se você quer obter uma ideia geral da performance. Note que a opção de perfil (`-c`), e a habilidade de se plugar a um processo em execução (`-p`). 242 | 243 | - Aprenda a respeito do `ldd` para verificar bibliotecas compartilhadas, e etc. 244 | 245 | - Aprenda sobre como se conectar a um processo em execução com o `gdb` e obter informações sobre a stack trace. 246 | 247 | - Utilize `/proc`. Este é incrivelmente útil em algumas vezes quando se deseja debugar problemas ao vivo. Exemplos: `/proc/cpuinfo`, `/proc/xxx/cwd`, `/proc/xxx/exe`, `/proc/xxx/fd/`, `/proc/xxx/smaps`. 248 | 249 | - Quando estiver debugando o porque de algo ter dado errado no passado, [`sar`](http://sebastien.godard.pagesperso-orange.fr/) pode ser de muita utilidade. Ele exibe as estatísticas históricas da CPU, memória, rede e etc. 250 | 251 | - Para análises de performance mais profundas do sistema, dê uma olhada em `stap` ([SystemTap](https://sourceware.org/systemtap/wiki)), [`perf`](http://en.wikipedia.org/wiki/Perf_(Linux)), e [`sysdig`](https://github.com/draios/sysdig). 252 | 253 | - Confirme qual a sua distribuição do Linux usando (funciona na maioria das distros): `lsb_release -a`. 254 | 255 | - Use `dmesg` sempre que algo estiver agindo de maneira estranha (isto pode ser um problema de hardware ou problema de driver). 256 | 257 | 258 | ## One-liners 259 | 260 | Alguns exemplos de como reunir os comandos. 261 | 262 | - O seguinte é notavelmente e frequentemente útil: muitas vezes você quer obter a interseção, união e a diferença de arquivos de texto através de `sort`/`uniq`. Suponha que `a` e `b` são arquivos de texto que são "uniqued" únicos. Esse modo é rápido, e funciona em arquivos de tamanhos arbitrários, podem até possuírem gigabytes. (Sorting não é limitado por memória, embora você possa precisar usar a opção `-T` se `/tmp` está em uma partição pequena.) Veja também a nota sobre `LC_ALL` acima e as opções `-u` do `sort`(vamos deixar isso claro abaixo). 263 | ```sh 264 | cat a b | sort | uniq > c # c is a union b 265 | cat a b | sort | uniq -d > c # c is a intersect b 266 | cat a b b | sort | uniq -u > c # c is set difference a - b 267 | ``` 268 | 269 | - Use `grep . *` para visualmente examinar todo o conteúdo de todos os arquivos de um diretório, por exemplo, para diretórios com arquivos de configurações, como `/sys`, `/proc`, `/etc`. 270 | 271 | 272 | - Somar todos os números em uma terceira coluna de um arquivo de texto (isto é provavelmente 3X mais rápido e 3X menos linhas de código do que o equivalente em Python). 273 | ```sh 274 | awk '{ x += $3 } END { print x }' myfile 275 | ``` 276 | 277 | - Se você quer visualizar tamanhos/datas em uma árvore de arquivos, isto é como um `ls -l` recursivo, mas é mais fácil de ler do que `ls -lR`: 278 | ```sh 279 | find . -type f -ls 280 | ``` 281 | 282 | - Utilize `xargs` ou `parallel` sempre que você puder. Note que você pode controlar quantos item é executado por linha (`-L`) assim como o paralelismo (`-P`). Se você não tem certeza de que esta é a coisa certa a se fazer, utilize `xargs echo` primeiro. 283 | ```sh 284 | find . -name '*.py' | xargs grep some_function 285 | cat hosts | xargs -I{} ssh root@{} hostname 286 | ``` 287 | 288 | - Digamos que você tenha um arquivo de texto, como um log do servidor web, e um certo valor que aparece em algumas linhas, como por exemplo o parâmetro `acct_id` que está presente na URL. Se você quer um cálculo de quantas requisições para este `acct_id`. 289 | ```sh 290 | cat access.log | egrep -o 'acct_id=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -rn 291 | ``` 292 | 293 | - Execute esta função para obter uma dica random deste documento (analisa a sintaxe Markdown e extrai um item) 294 | ```sh 295 | function taocl() { 296 | curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-pt.md | 297 | pandoc -f markdown -t html | 298 | xmlstarlet fo --html --dropdtd | 299 | xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 300 | xmlstarlet unesc | fmt -80 301 | } 302 | ``` 303 | 304 | 305 | ## Obscuros mas úteis 306 | 307 | - `expr`: executa operações boleanas ou aritméticas ou avalia expressões regulares. 308 | 309 | - `m4`: simples processador de macros. 310 | 311 | - `yes`: imprime uma string muitas vezes. 312 | 313 | - `cal`: calendário legal. 314 | 315 | - `env`: executa um comando (útil em scripts). 316 | 317 | - `printenv`: imprime as variáveis de ambiente (útil em debug e scripts). 318 | 319 | - `look`: procura palavras inglesas (ou linhas em um arquivo) começando com uma string. 320 | 321 | - `cut ` e `paste` e `join`: manipulação de dados. 322 | 323 | - `fmt`: formata parágrafos de texto. 324 | 325 | - `pr`: formata textos em páginas/colunas. 326 | 327 | - `fold`: envolve linhas de texto. 328 | 329 | - `column`: formata texto em colunas ou tabelas. 330 | 331 | - `expand` e `unexpand`: converte entre tabs e espaços. 332 | 333 | - `nl`: adiciona números as linhas. 334 | 335 | - `seq`: imprime números. 336 | 337 | - `bc`: calculadora. 338 | 339 | - `factor`: fatora inteiros. 340 | 341 | - `gpg`: criptografa e assina arquivos. 342 | 343 | - `toe`: tabela de entradas dos tipos de terminais. 344 | 345 | - `nc`: ferramenta de debug de rede e transferência de dados. 346 | 347 | - `socat`: socket relay e encaminhamento de portas tcp (similar ao `netcat`) 348 | 349 | - `slurm`: visualização do tráfego da rede. 350 | 351 | - `dd`: move os dados entre arquivos ou dispositivos. 352 | 353 | - `file`: identifica o tipo do arquivo. 354 | 355 | - `tree`: mostra os diretórios e subdiretórios como um árvore de dependências; como `ls` mas recursivo. 356 | 357 | - `stat`: informações do arquivo. 358 | 359 | - `tac`: imprime arquivos na ordem reversa. 360 | 361 | - `shuf`: seleção random de linhas de um arquivo. 362 | 363 | - `comm`: compara uma lista de arquivos ordenadas linha por linha. 364 | 365 | - `pv`: monitora o progresso dos dados através de um pipe. 366 | 367 | - `hd` e `bvi`: dump ou edita arquivos binários. 368 | 369 | - `strings`: extrai texto de arquivos binários. 370 | 371 | - `tr`: tradução e manipulação de caracteres. 372 | 373 | - `iconv` ou `uconv`: conversor de codificações de texto. 374 | 375 | - `split ` e `csplit`: divisão de arquivos. 376 | 377 | - `units`: conversor de unidades e cálculos; converte furlongs por quinzena para twips per blink (veja também `/usr/share/units/definitions.units`) 378 | 379 | - `7z`: Compressor de arquivos de alto desempenho. 380 | 381 | - `ldd`: informações dinâmicas das bibliotecas. 382 | 383 | - `nm`: símbolos de arquivos objetos. 384 | 385 | - `ab`: benchmarking para web servers. 386 | 387 | - `strace`: Debug para chamadas de sistema. 388 | 389 | - [`mtr`](http://www.bitwizard.nl/mtr/): melhor traceroute para debugar a rede. 390 | 391 | - `cssh`: Visualização concorrente da shell. 392 | 393 | - `rsync`: Sincroniza arquivos e pastas através do SSH. 394 | 395 | - [`wireshark`](https://wireshark.org/) e [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html): captura de pacotes e debug de rede. 396 | 397 | - [`ngrep`](http://ngrep.sourceforge.net/): grep para a camada de rede. 398 | 399 | - `host` e `dig`: Consultas DNS. 400 | 401 | - `lsof`: Arquivo de descritores dos processos e informações dos sockets. 402 | 403 | - `dstat`: Estatísticas úteis do sistema. 404 | 405 | - [`glances`](https://github.com/nicolargo/glances): Resumo de alto nível, de multi subsistemas. 406 | 407 | - `iostat`: Estatísticas de uso do CPU e do disco. 408 | 409 | - `htop`: Versão do top melhorada. 410 | 411 | - `last`: histórico de logins. 412 | 413 | - `w`: quem está logado. 414 | 415 | - `id`: Informações sobre a identidade do user/group. 416 | 417 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/): histórico dos estados do sistema. 418 | 419 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) ou [`nethogs`](https://github.com/raboof/nethogs): Utilização da rede por sockets ou processos. 420 | 421 | - `ss`: Estatísticas dos sockets. 422 | 423 | - `dmesg`: Mensagens de erro do sistema e do boot. 424 | 425 | - `hdparm`: Manipulação/performance de discos SATA/ATA. 426 | 427 | - `lsblk`: Lista os blocos dos dispositivos: uma visualização em forma de árvore dos seus discos e partições do disco. 428 | 429 | - `lshw` e `lspci`: informações do hardware, incluindo RAID, gráficos, etc. 430 | 431 | - `fortune`, `ddate`, e `sl`: um, bem, isto depende de você considerar locomotivas a vapor e citações Zippy "úteis". 432 | 433 | ## Mais conteúdo 434 | 435 | - [awesome-shell](https://github.com/alebcay/awesome-shell): Uma lista refinada de ferramentas da shell e outros recursos. 436 | - [Strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/) para escrever shell scripts melhores. 437 | 438 | ## Aviso 439 | 440 | Com a exceção de tarefas muito pequenas, código é normalmente escrito para que outros possam ler. Junto com o poder vem a responsabilidade. O fato de você *poder* fazer algo usando Bash não significa necessariamente que você deve! ;) 441 | 442 | 443 | ## Licença 444 | 445 | [![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 446 | 447 | Este trabalho está licenciado com uma [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). 448 | -------------------------------------------------------------------------------- /README-zh-Hant.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | # 命令列的藝術 5 | 6 | [![Join the chat at https://gitter.im/jlevy/the-art-of-command-line](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 7 | 8 | - [必讀](#必讀) 9 | - [基礎](#基礎) 10 | - [日常使用](#日常使用) 11 | - [檔案及資料處理](#檔案及資料處理) 12 | - [系統偵錯](#系統偵錯) 13 | - [單行指令碼](#單行指令碼) 14 | - [冷門但有用的指令](#冷門但有用的指令) 15 | - [僅限 OS X 系統](#僅限-os-x-系統) 16 | - [僅限 Windows 系統](#僅限-windows-系统) 17 | - [更多資源](#更多資源) 18 | - [免責聲明](#免責聲明) 19 | - [授權條款](#授權條款) 20 | 21 | 22 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 23 | 24 | 熟練使用命令列是一種常常被忽視,或被認為難以掌握的技能,但實際上,它會提高你作為工程師的靈活性以及生產力。本文是一份我在 Linux 上工作時,發現的一些命令列使用技巧的摘要。有些技巧非常基礎,而另一些則相當複雜,甚至晦澀難懂。這篇文章並不長,但當你能夠熟練掌握這裡列出的所有技巧時,你就學會了很多關於命令列的東西了。 25 | 26 | 這篇文章是[許多作者和譯者](AUTHORS.md)共同的成果。這裡的大部分內容 27 | [首次](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands) 28 | [出現](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix) 29 | 於 [Quora](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know),但考慮到這裡的人們都具有學習的天賦且樂於接受別人的建議,使用 Github 來做這件事是更佳的選擇。如果你在本文中發現了錯誤或者​​存在可以改善的地方,請果斷提交 Issue 或 Pull Request! (當然在提交前請看一下必讀節和已有的 PR/issue)。 30 | 31 | 32 | ## 必讀 33 | 34 | 涵蓋範圍: 35 | 36 | - 這篇文章對剛接觸命令列的新手以及具有命令列使用經驗的人都有用處。本文致力於做到*覆蓋面廣*(盡量包括一切重要的內容),*具體*(給出最常見的具體的例子)以及*簡潔*(避免不必要的,或是可以在其他地方輕鬆查到的細枝末節)。每個技巧都是在特定情境下必備的,或是能顯著減省時間的。 37 | - 本文為 Linux 所寫,除了 [僅限OS X 系統](#僅限-os-x-系統) 和 [僅限 Windows 系統](#僅限-windows-系统) 章節外,其它章節中的大部分內容都適用於其它 Unix 系統或 MacOS 系統,甚至 Cygwin。 38 | - 本文關注於互動式 Bash,儘管很多技巧也適用於其他 shell 或 Bash 指令碼。 39 | - 本文包括了“標準的” Unix 命令和需要安裝特定套件的命令,只要它們足夠重要。 40 | 41 | 注意事項: 42 | 43 | - 為了能在一頁內展示盡量多的東西,一些具體的資訊會被間接的包含在引用頁裡。聰明機智的你如果掌握了使用 Google 搜尋引擎的基本方法與命令,那麼你將可以查閱到更多的詳細資訊。使用`apt-get`,`yum`,`dnf`,`pacman`,`pip` 或`brew`(以及其它合適的包管理器)來安裝新程式。 44 | - 使用 [Explainshell](http://explainshell.com/) 去獲取相關命令、參數、管道等解釋。 45 | 46 | 47 | ## 基礎 48 | 49 | - 學習 Bash 的基礎知識。具體來說,輸入`man bash` 並至少全文瀏覽一遍; 它很簡單並且不長。其他的 shell 可能很好用,但 Bash 功能強大且幾乎所有情況下都是可用的( *只*學習 zsh,fish 或其他的 shell 的話,在你自己的電腦上會顯得很方便,但在很多情況下會限制你,比如當你需要在伺服器上工作時)。 50 | 51 | - 學習並掌握至少一個基於文字的編輯器。通常 Vim (`vi`) 會是你最好的選擇,因為在終端裡進行隨機編輯 Vim 真的毫無敵手,哪怕是Emacs、某大型IDE 甚至時下非常流行的編輯器。 52 | 53 | - 學會如何使用`man` 命令去閱讀文件。學會使用 `apropos` 去查詢文件。瞭解有些命令是不可執行,而是Bash內建的,可以使用`help` 和`help -d` 命令獲取幫助資訊。 54 | 55 | - 學會使用`>` 和`<` 來重定向輸出和輸入,學會使用`|` 來重定向管道。明白`>` 會覆蓋了輸出文件而`>>` 是在檔案末新增。瞭解標準輸出 stdout 和標準錯誤 stderr。 56 | 57 | - 學會使用通配符`*` (或許再算上`?` 和`[`...`]`) 和引用以及引用中`'` 和`"` 的區別。 58 | 59 | - 熟悉 Bash 任務管理工具:`&`,**ctrl-z**,**ctrl-c**,`jobs`,`fg`,`bg`,`kill` 等。 60 | 61 | - 瞭解`ssh`,以及學會通過使用`ssh-agent`,`ssh-add` 等命令來實現基本的無密碼認證。 62 | 63 | - 學會基本的檔案管理:`ls` 和`ls -l` (瞭解`ls -l` 中每一列代表的意義),`less`,`head`,`tail` 和`tail -f` (甚至`less +F`),`ln` 和`ln -s` (瞭解硬連結與軟連結的區別),`chown`,`chmod`,`du` (硬碟使用情況概述:`du -hs *` )。關於檔案系統的管理,學習`df`,`mount`,`fdisk`,`mkfs`,`lsblk`。知道 inode 是什麼(與`ls -i` 和`df -i` 等命令相關)。 64 | 65 | - 學習基本的網路管理:`ip` 或`ifconfig`,`dig`。 66 | 67 | - 熟悉正規表示式,以及`grep`/`egrep` 裡不同參數的作用,例如`-i`,`-o`,`-v`,`-A`,`-B` 和`-C` ,這些參數是值得學習並掌握的。 68 | 69 | - 學會使用`apt-get`,`yum`,`dnf` 或`pacman` (取決於你使用的 Linux 發行版)來查詢或安裝軟體包。並確保你的環境中有`pip` 來安裝基於 Python 的命令列工具(接下來提到的部分程式使用`pip` 來安裝會很方便)。 70 | 71 | 72 | ## 日常使用 73 | 74 | - 在 Bash 中,可以使用 **Tab** 自動補全參數,使用 **ctrl-r** 搜尋命令列歷史(在按下之後,鍵入便可以搜尋,重複按下**ctrl-r**會在更多匹配中迴圈,按下 **Enter** 會執行找到的命令,按下右方向鍵會將結果放入當前行中,使你可以進行編輯)。 75 | 76 | - 在 Bash 中,可以使用 **ctrl-w** 刪除你鍵入的最後一個單詞,使用 **ctrl-u** 刪除當前游標所在位置之前的內容,使用 **alt-b** 和 **alt-f**以單詞為單位移動游標,​​使用 **ctrl-a** 將游標移至行首,使用 **ctrl-e** 將游標移至行尾,使用 **ctrl-k** 刪除游標至行尾的所有內容,使用 **ctrl-l** 清屏。鍵入`man readline` 檢視 Bash 中的預設快捷鍵,內容很多。例如 **alt-.** 迴圈地移向前一個參數,以及 **alt-*** 展開通配符。 77 | 78 | - 你喜歡的話,可以鍵入`set -o vi` 來使用vi 風格的快捷鍵,而`set -o emacs` 可以把它改回來。 79 | 80 | - 為了方便地鍵入長命令,在設定你的編輯器後(例如`export EDITOR=vim`),鍵入 **ctrl-x** **ctrl-e** 會開啟一個編輯器來編輯當前命令。在 vi 模式下則鍵入 **escape-v** 實現相同的功能。 81 | 82 | - 鍵入 `history` 檢視命令列歷史記錄。其中有許多縮寫,例如`!$`(最後鍵入的參數)和`!!`(最後鍵入的命令),儘管通常被 **ctrl-r** 和 **alt-.** 取代。 83 | 84 | - 回到上一個工作路徑:`cd -` 85 | 86 | - 如果你輸入命令的時候改變了主意,按下 **alt-#** 來在行首新增`#`,或者依次按下 **ctrl-a**, **#**, **enter**。這樣做的話,之後你可以很方便的利用命令列歷史回到你剛才輸入到一半的命令。 87 | 88 | - 使用 `xargs` ( 或 `parallel`),他們非常強大。注意到你可以控制每行參數的個數(`-L`)和最大並行數(`-P`)。如果你不確定它們是否會按你想的那樣工作,先使用`xargs echo` 檢視一下。此外,使用 `-I{}` 會很方便。例如: 89 | ```bash 90 |       find . -name '*.py' | xargs grep some_function 91 |       cat hosts | xargs -I{} ssh root@{} hostname 92 | ``` 93 | 94 | - `pstree -p` 有助於展示程序樹。 95 | 96 | - 使用`pgrep` 和`pkill` 根據名字查詢程序或傳送訊號(`-f` 參數通常有用)。 97 | 98 | - 瞭解你可以發往程序的訊號的種類。比如,使用`kill -STOP [pid]` 停止一個程序。使用 `man 7 signal` 檢視詳細列表。 99 | 100 | - 使用`nohup` 或`disown` 使一個後臺程序持續運行。 101 | 102 | - 使用`netstat -lntp` 或`ss -plat` 檢查哪些程序在監聽埠(預設是檢查 TCP 埠; 使用參數`-u` 檢查 UDP 埠)。 103 | 104 | - 有關開啟 socket 和檔案,請參閱`lsof`。 105 | 106 | - 使用`uptime` 或`w` 來檢視系統已經運行多長時間。 107 | 108 | - 使用`alias` 來創建常用命令的快捷形式。例如:`alias ll='ls -latr'` 使你可以方便地執行`ls -latr`命令。 109 | 110 | - 在 Bash 指令碼中,使用`set -x` 去偵錯輸出,盡可能的使用嚴格模式,使用`set -e` 令指令碼在發生錯誤時退出而不是繼續運行,使用`set -u` 來檢查是否使用了未賦值的變數,使用`set -o pipefail` 嚴謹地對待錯誤(儘管問題可能很微妙)。當牽扯到很多指令碼時,使用 `trap`。一個好的習慣是在指令碼檔案開頭這樣寫,這會使它檢測一些錯誤,並在錯誤發生時中斷程式並輸出資訊: 111 | ```bash 112 |       set -euo pipefail 113 |       trap "echo 'error: Script failed: see failed command above'" ERR 114 | ``` 115 | 116 | - 在 Bash 指令碼中,子 shell(使用括號`(...)`)是一種組織參數的便捷方式。一個常見的例子是臨時地移動工作路徑,程式碼如下: 117 | ```bash 118 |       # do something in current dir 119 |       (cd /some/other/dir && other-command) 120 |       # continue in original dir 121 | ``` 122 | 123 | - 在 Bash 中,要注意其中有許多形式的擴展。檢查變數是否存在:`${name:?error message}`。例如,當 Bash 指令碼需要一個參數時,可以使用這樣的程式碼`input_file=${1:?usage: $0 input_file}`。數學表示式:`i=$(( (i + 1) % 5 ))`。序列:`{1..10}`。截斷字元串:`${var%suffix}` 和`${var#prefix}`。例如,假設`var=foo.pdf`,那麼`echo ${var%.pdf}.txt` 將輸出`foo.txt`。 124 | 125 | - 使用括號擴展(`{`...`}`)來減少輸入相似文字,並自動化文字組合。這在某些情況下會很有用,例如`mv foo.{txt,pdf} some-dir`(同時移動兩個檔案),`cp somefile{,.bak}`(會被擴展成`cp somefile somefile .bak`)或者`mkdir -p test-{a,b,c}/subtest-{1,2,3}`(會被擴展成所有可能的組合,並創建一個目錄樹)。 126 | 127 | - 通過使用`<(some command)` 可以將輸出視為檔案。例如,對比本地檔案`/etc/hosts` 和一個​​遠端檔案: 128 | ```sh 129 |       diff /etc/hosts <(ssh somehost cat /etc/hosts) 130 | ``` 131 | 132 | - 瞭解 Bash 中的“here documents”,例如`cat <logfile 2>&1`。通常,為了保證命令不會在標準輸入裡殘留一個開啟了的檔案控制代碼導致你當前所在的終端無法操作,新增` bar: 210 |       repren --full --preserve-case --from foo --to bar . 211 |       # Recover backup files whatever.bak -> whatever: 212 |       repren --renames --from '(.*)\.bak' --to '\1' *.bak 213 |       # Same as above, using rename, if available: 214 |       rename 's/\.bak$//' *.bak 215 | ``` 216 | 217 | - 根據 man 頁面的描述,`rsync` 真的是一個快速且非常靈​​活的檔案複製工具。它通常被用於機器間的同步,但在本地也同樣有用。它同時也是刪除大量檔案的[最快方法](https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove -huge-number-of-files.html)之一: 218 | ```sh 219 | mkdir empty && rsync -r --delete empty/ some-dir && rmdir some-dir 220 | ``` 221 | 222 | - 使用`shuf` 從一個檔案中隨機選取多行。 223 | 224 | - 瞭解 `sort` 的參數。處理數字方面,使用`-n` 或者`-h` 來處理可讀性數字(例如`du -h` 的輸出)。明白鍵的工作原理(`-t` 和 `-k`)。例如,注意到你需要`-k1,1` 來按照第一個欄位來排序,而`-k1` 意味著按照整行排序。穩定排序(`sort -s`)在某些情況下很有用。例如,以第二個欄位為主關鍵字,第一個欄位為次關鍵字進行排序,你可以使用`sort -k1,1 | sort -s -k2,2`。 225 | 226 | - 如果你想在 Bash 命令列中寫 tab 製表符,按下**ctrl-v** **[Tab]** 或鍵入`$'\t'` (後者可能更好,因為你可以複製貼上它)。 227 | 228 | - 標準的原始碼對比及合併工具是`diff` 和`patch`。使用 `diffstat` 檢視變更總覽資料。注意到 `diff -r` 對整個資料夾有效。使用`diff -r tree1 tree2 | diffstat` 檢視變更總覽資料。 229 | 230 | - 對於二進制檔案,使用`hd` 使其以十六進位制顯示以及使用`bvi` 來編輯二進位制。 231 | 232 | - 同樣對於二進制檔案,`strings`(包括`grep` 等等)允許你查詢一些文字。 233 | 234 | - 二進制檔案對比(Delta 壓縮),使用`xdelta3`。 235 | 236 | - 轉換文字編碼可使用 `iconv` 或 `uconv`,後者支援 Unicode 相關的進階用法。例如: 237 | ```sh 238 | # 顯示十六進制碼或字元標準名稱(有益於除錯) 239 | uconv -f utf-8 -t utf-8 -x '::Any-Hex;' < input.txt 240 | uconv -f utf-8 -t utf-8 -x '::Any-Name;' < input.txt 241 | # 將文字轉換為小寫並移除所有重音標記(展開字元並移除標記): 242 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC;' < input.txt > output.txt 243 | ``` 244 | 245 | - 拆分檔案,檢視`split`(按大小拆分)和`csplit`(按模式拆分)。 246 | 247 | - 用[`dateutils`](http://www.fresse.org/dateutils/) 中的`dateadd`, `datediff`, `strptime` 等工具操作日期和時間表示式。 248 | 249 | - 使用`zless`,`zmore`,`zcat` 和`zgrep` 對壓縮過的檔案進行操作。 250 | 251 | 252 | ## 系統偵錯 253 | 254 | - `curl` 和`curl -I` 可以便捷地被應用於 web 偵錯,它們的好兄弟`wget` 也可以,或者是更潮的[`httpie`](https://github.com/jakubroztocil /httpie)。 255 | 256 | - 使用`iostat`、`netstat`、`top` (`htop` 更佳)和`dstat` 去獲取硬碟、cpu 和網路的狀態。熟練掌握這些工具可以使你快速的對系統的當前狀態有一個大概的認識。 257 | 258 | - 使用`netstat` 和`ss` 檢視網路連線的細節。 259 | 260 | - 若要對系統有一個深度的總體認識,使用[`glances`](https://github.com/nicolargo/glances)。它在一個終端視窗中向你提供一些系統層級的資料。這對於快速的檢查各個子系統非常有幫助。 261 | 262 | - 若要了解記憶體狀態,運行並理解`free` 和`vmstat` 的輸出。尤其注意 “cached” 的值,它指的是 Linux 核心用來作為檔案快取的記憶體大小,因此它與空閒記憶體無關。 263 | 264 | - Java 系統偵錯則是一件截然不同的事,一個可以用於 Oracle 的 JVM 或其他 JVM 上的偵錯的技巧是你可以運行`kill -3 ` 同時一個完整的棧軌跡和堆概述(包括 GC 的細節)會被儲存到標準輸出/日誌檔案。 JDK 中的`jps`,`jstat`,`jstack`,`jmap` 很有用。 [SJK tools](https://github.com/aragozin/jvm-tools) 更高階. 265 | 266 | - 使用[`mtr`](http://www.bitwizard.nl/mtr/) ​​去跟蹤路由,用於確定網路問題。 267 | 268 | - 用[`ncdu`](https://dev.yorhel.nl/ncdu) 來檢視磁碟使用情況,它比常用的命令,如`du -sh *`,更節省時間。 269 | 270 | - 查詢正在使用頻寬的 socket 連線或程序,使用[`iftop`](http://www.ex-parrot.com/~pdw/iftop/) 或[`nethogs`](https://github.com/raboof/nethogs)。 271 | 272 | - `ab` 工具(內建於Apache)可以簡單粗暴地檢查 web 伺服器的效能。對於更複雜的負載測試,使用`siege`。 273 | 274 | - [`wireshark`](https://wireshark.org/),[`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html) 和[`ngrep`](http://ngrep.sourceforge.net/) 可用於復雜的網路偵錯。 275 | 276 | - 瞭解 `strace` 和 `ltrace`。這倆工具在你的程式運行失敗、掛起甚至崩潰,而你卻不知道為什麼或你想對效能有個總體的認識的時候是非常有用的。注意 profile 參數(`-c`)和附加到一個運行的程序參數(`-p`)。 277 | 278 | - 瞭解使用 `ldd` 來檢查共享庫。 279 | 280 | - 瞭解如何運用`gdb` 連線到一個運行著的程序並獲取它的堆棧軌跡。 281 | 282 | - 學會使用 `/proc`。它在偵錯正在出現的問題的時候有時會效果驚人。比如:`/proc/cpuinfo`,`/proc/meminfo`,`/proc/cmdline`,`/proc/xxx/cwd`,`/proc/xxx/exe`,`/proc/xxx/fd/` ,`/proc/xxx/smaps`(這裡的`xxx` 表示程序的 id 或 pid)。 283 | 284 | - 當偵錯一些之前出現的問題的時候,[`sar`](http://sebastien.godard.pagesperso-orange.fr/) 非常有用。它展示了 cpu、記憶體以及網路等的歷史資料。 285 | 286 | - 關於更深層次的系統分析以及效能分析,看看`stap`([SystemTap](https://sourceware.org/systemtap/wiki)),[`perf`](http://en.wikipedia.org /wiki/Perf_(Linux)),以及[`sysdig`](https://github.com/draios/sysdig)。 287 | 288 | - 檢視你當前使用的系統,使用`uname` , `uname -a` (Unix/kernel 資訊) 或者`lsb_release -a` (Linux 發行版資訊)。 289 | 290 | - 無論什麼東西工作得很歡樂時試試`dmesg`(可能是硬體或驅動問題)。 291 | 292 | 293 | ## 單行指令碼 294 | 295 | 一些命令組合的例子: 296 | 297 | - 當你需要對文字檔案做集合交、並、差運算時,結合使用`sort`/`uniq` 很有幫助。假設 `a` 與 `b` 是兩內容不同的檔案。這種方式效率很高,並且在小檔案和上G的檔案上都能運用(`sort` 不被記憶體大小約束,儘管在`/tmp` 在一個小的根分區上時你可能需要`-T ` 參數),參閱前文中關於`LC_ALL` 和`sort` 的`-u` 參數的部分。 298 | ```sh 299 |       cat a b | sort | uniq > c # c is a union b 300 |       cat ab | sort | uniq -d > c # c is a intersect b 301 |       cat abb | sort | uniq -u > c # c is set difference a - b 302 | ``` 303 | 304 | - 使用`grep . *`(每行都會附上檔名)或者`head -100 *`(每個檔案有一個標題)來閱讀檢查目錄下所有檔案的內容。這在檢查一個充滿配置檔案的目錄(如`/sys`、`/proc`、`/etc`)時特別好用。 305 | 306 | - 計算文字檔案第三列中所有數的和(可能比同等作用的Python 程式碼快三倍且程式碼量少三倍): 307 | ```sh 308 |       awk '{ x += $3 } END { print x }' myfile 309 | ``` 310 | 311 | - 如果你想在檔案樹上檢視大小/日期,這可能看起來像遞迴版的`ls -l` 但比`ls -lR` 更易於理解: 312 | ```sh 313 |       find . -type f -ls 314 | ``` 315 | 316 | - 假設你有一個類似於 web 伺服器日誌檔案的文字檔案,並且一個確定的值只會出現在某些行上,假設一個`acct_id` 參數在URI中。如果你想計算出每個`acct_id` 值有多少次請求,使用如下程式碼: 317 | ```sh 318 |       cat access.log | egrep -o 'acct_id=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -rn 319 | ``` 320 | 321 | - 運行這個函數從這篇文件中隨機獲取一條技巧(解析 Markdown 檔案並抽取項目): 322 | ```sh 323 |       function taocl() { 324 |         curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md | 325 |           pandoc -f markdown -t html | 326 |           xmlstarlet fo --html --dropdtd | 327 |           xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 328 |           xmlstarlet unesc | fmt -80 329 |       } 330 | ``` 331 | 332 | 333 | ## 冷門但有用的指令 334 | 335 | - `expr`:計算表示式或正規表示法 336 | 337 | - `m4`:簡易的巨集處理器 338 | 339 | - `yes`:列印多次字串 340 | 341 | - `cal`:漂亮的日曆 342 | 343 | - `env`:執行一個命令(指令碼中很有用) 344 | 345 | - `printenv`:列印環境變數(偵錯時或在使用指令碼時很有用) 346 | 347 | - `look`:查詢以特定字元串開頭的單詞 348 | 349 | - `cut`、`paste` 和 `join`:資料操作 350 | 351 | - `fmt`:格式化文字段落 352 | 353 | - `pr`:將文字格式化成頁/列形式 354 | 355 | - `fold`:包裹文字中的幾行 356 | 357 | - `column`:將文字格式化成多列或表格 358 | 359 | - `expand` 和`unexpand`:在 tab 與空格之間轉換 360 | 361 | - `nl`:新增行號 362 | 363 | - `seq`:列印數字 364 | 365 | - `bc`:計算機 366 | 367 | - `factor`:分解因數 368 | 369 | - [`gpg`](https://gnupg.org/):加密並針對檔案簽章 370 | 371 | - `toe`:terminfo entries 列表 372 | 373 | - `nc`:網路偵錯及資料傳輸 374 | 375 | - `socat`:socket 代理,與 `netcat` 類似 376 | 377 | - [`slurm`](https://github.com/mattthias/slurm):網路流量視覺化 378 | 379 | - `dd`:在檔案或裝置間傳輸資料 380 | 381 | - `file`:確定檔案類型 382 | 383 | - `tree`:以樹的形式顯示路徑和檔案,類似於遞迴的`ls` 384 | 385 | - `stat`:檔案資訊 386 | 387 | - `time`:執行命令,同時計算執行時間 388 | 389 | - `lockfile`:使檔案只能通過`rm -f` 移除 390 | 391 | - `logrotate`: 切換、壓縮以及傳送日誌檔案 392 | 393 | - `watch`:重複運行同一個命令,展示結果並 highlight 有更改的部分 394 | 395 | - `tac`:反向輸出文件 396 | 397 | - `shuf`:檔案中隨機選取幾行 398 | 399 | - `comm`:一行一行的比較排序過的檔案 400 | 401 | - `pv`:監視通過 pipe 的資料 402 | 403 | - `hd`,`hexdump`,`xxd`,`biew` 和`bvi`:儲存或編輯二進位檔案 404 | 405 | - `strings`:從二進位檔案中抽取文字 406 | 407 | - `tr`:轉換字母 408 | 409 | - `iconv` 或 `uconv`:簡易的檔案編碼 410 | 411 | - `split` 和 `csplit`:分割檔案 412 | 413 | - `sponge`:在寫入前讀取所有輸入,在讀取檔案後再向同一檔案寫入時比較有用,例如`grep -v something some-file | sponge some-file` 414 | 415 | - `units`:將一種計量單位轉換為另一種等效的計量單位(參閱`/usr/share/units/definitions.units`) 416 | 417 | - `apg`:隨機生成密碼 418 | 419 | - `7z`:高比例的檔案壓縮 420 | 421 | - `ldd`:動態庫資訊 422 | 423 | - `nm`:提取 obj 檔案中的符號 424 | 425 | - `ab`:效能分析 web 伺服器 426 | 427 | - `strace`:系統呼叫偵錯 428 | 429 | - [`mtr`](http://www.bitwizard.nl/mtr/):更好的網路偵錯跟蹤工具 430 | 431 | - `cssh`:視覺化的並發 shell 432 | 433 | - `rsync`:通過ssh 或本地檔案系統同步檔案和資料夾 434 | 435 | - [`wireshark`](https://wireshark.org/) 和[`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html):抓包和網路偵錯工具 436 | 437 | - [`ngrep`](http://ngrep.sourceforge.net/):網路層的 grep 438 | 439 | - `host` 和 `dig`:DNS 查詢 440 | 441 | - `lsof`:列出當前系統開啟檔案的工具以及檢視埠資訊 442 | 443 | - `dstat`:系統狀態檢視 444 | 445 | - [`glances`](https://github.com/nicolargo/glances):高層次的多子系統總覽 446 | 447 | - `iostat`:硬碟使用狀態 448 | 449 | - `mpstat`: CPU 使用狀態 450 | 451 | - `vmstat`: 記憶體使用狀態 452 | 453 | - `htop`:top 的加強版 454 | 455 | - `last`:登入記錄 456 | 457 | - `w`:檢視處於登入狀態的使用者 458 | 459 | - `id`:使用者/組 ID 資訊 460 | 461 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/):系統歷史資料 462 | 463 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) 或[`nethogs`](https://github.com/raboof/nethogs):套接字及程序的網路利用 464 | 465 | - `ss`:socket 資料 466 | 467 | - `dmesg`:引導及系統錯誤資訊 468 | 469 | - `sysctl`: 在核心運行時動態地檢視和修改內核的運行參數 470 | 471 | - `hdparm`:SATA/ATA 磁碟更改及效能分析 472 | 473 | - `lsblk`:列出塊裝置資訊:以樹形展示你的磁碟以及磁碟分區資訊 474 | 475 | - `lshw`,`lscpu`,`lspci`,`lsusb` 和`dmidecode`:檢視硬體資訊,包括CPU、BIOS、RAID、顯示卡、USB裝置等 476 | 477 | - `lsmod` 和`modinfo`:列出核心模組,並顯示其細節 478 | 479 | - `fortune`,`ddate` 和`sl`:額,這主要取決於你是否認為蒸汽火車和莫名其妙的名人名言是否“有用” 480 | 481 | ## 僅限 OS X 系統 482 | 483 | 以下是*僅限於* MacOS 系統的技巧 484 | 485 | - 用`brew` (Homebrew)或者`port` (MacPorts)進行套件管理。這些可以用來在 Mac 系統上安裝以上的大多數命令。 486 | 487 | - 用`pbcopy` 複製任何命令的輸出到桌面應用,用`pbpaste` 貼上輸入。 488 | 489 | - 若要在 Mac OS 終端中將 Option 鍵視為 alt 鍵(例如在上面介紹的**alt-b**, **alt-f** 等命令中用到),開啟偏好設定-> 描述檔案-> 鍵盤並勾選“使用 Option 鍵作為 Meta 鍵”。 490 | 491 | - 用`open` 或者`open -a /Applications/Whatever.app` 使用桌面應用開啟檔案。 492 | 493 | - Spotlight: 用`mdfind` 搜尋檔案,用`mdls` 列出後設資料(例如照片的EXIF 資訊)。 494 | 495 | - 注意 MacOS 系統是基於BSD UNIX 的,許多命令(例如`ps`,`ls`,`tail`,`awk`,`sed`)都和 Linux 中有些微的不同,這些指令主要是被 System V -style Unix 和 GNU 工具影響。你可以透過標題為"BSD General Commands Manual" 的 man 頁面發現這些不同。在有些情況下 GNU 版本的命令也可能被安裝(例如`gawk` 和`gsed` 對應GNU 中的awk 和sed )。如果要寫跨平臺的 Bash 指令碼,避免使用這些命令(例如,考慮 Python 或者`perl` )或者經過仔細的測試。 496 | 497 | - 用 `sw_vers` 獲取 MacOS 的版本資訊。 498 | 499 | 500 | ## 僅限 Windows 系统 501 | 502 | - 要在 Microsoft Windows 中使用 Unix shell,可以安装 [Cygwin](https://cygwin.com/)。本文件中介绍的大多數内容都將適用。 503 | 504 | - 透過 Cygwin 的套件管理器來安裝額外的 Unix 指令。 505 | 506 | - 使用 `mintty` 作為你的命令列視窗。 507 | 508 | - 要訪問 Windows 剪貼簿,可以透過 `/dev/clipboard`。 509 | 510 | - 執行 `cygstart` 以透過預設程式打開一個文件。 511 | 512 | - 要訪問 Windows 登錄檔,可以使用 `regtool`。 513 | 514 | - 注意 Windows 磁碟機路徑 `C:\` 在 Cygwin 中用 `/cygdrive/c` 代表,而 Cygwin 的 `/` 在 Windows 中顯示在 `C:\cygwin`。要轉換 Cygwin 和 Windows 風格的路徑可以用 `cygpath`。這在需要使用 Windows 指令的脚本裡很有用。 515 | 516 | - 學會使用 `wmic`,你就可以從命令列執行大多數 Windows 系統管理任務,並編成腳本。 517 | 518 | ## 更多資源 519 | 520 | - [awesome-shell](https://github.com/alebcay/awesome-shell):一份精美的命令列工具及資源的列表。 521 | - [awesome-osx-command-line](https://github.com/herrbischoff/awesome-osx-command-line):一份針對 Mac OS 命令列的更深入的指南。 522 | - [Strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/):為了編寫更好的指令碼檔案。 523 | - [shellcheck](https://github.com/koalaman/shellcheck):一個靜態shell 指令碼分析工具,本質上是 bash/sh/zsh 的lint。 524 | - [Filenames and Pathnames in Shell](http://www.dwheeler.com/essays/filenames-in-shell.html):有關如何在 shell 腳本里正確處理檔名的細枝末節。 525 | 526 | 527 | ## 免責聲明 528 | 529 | 除去特別微小的任務,編寫程式碼是出於方便閱讀的目的。能力往往伴隨著責任。你 *可以* 在 Bash 中做一些事並不意味著你應該去做! ;) 530 | 531 | 532 | ## 授權條款 533 | 534 | [![創作共用License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 535 | 536 | 本文使用授權協議 [知識共享署名 - 相同方式共享 4.0 國際許可](http://creativecommons.org/licenses/by-sa/4.0/)。 537 | -------------------------------------------------------------------------------- /README-zh.md: -------------------------------------------------------------------------------- 1 | 🌍 2 | *[Čeština](README-cs.md) ∙ [Deutsch](README-de.md) ∙ [Ελληνικά](README-el.md) ∙ [English](README.md) ∙ [Español](README-es.md) ∙ [Français](README-fr.md) ∙ [Indonesia](README-id.md) ∙ [Italiano](README-it.md) ∙ [日本語](README-ja.md) ∙ [한국어](README-ko.md) ∙ [polski](README-pl.md) ∙ [Português](README-pt.md) ∙ [Română](README-ro.md) ∙ [Русский](README-ru.md) ∙ [Slovenščina](README-sl.md) ∙ [Українська](README-uk.md) ∙ [简体中文](README-zh.md) ∙ [繁體中文](README-zh-Hant.md)* 3 | 4 | 5 | # 命令行的艺术 6 | 7 | [![Join the chat at https://gitter.im/jlevy/the-art-of-command-line](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 8 | 9 | - [前言](#前言) 10 | - [基础](#基础) 11 | - [日常使用](#日常使用) 12 | - [文件及数据处理](#文件及数据处理) 13 | - [系统调试](#系统调试) 14 | - [单行脚本](#单行脚本) 15 | - [冷门但有用](#冷门但有用) 16 | - [仅限 OS X 系统](#仅限-os-x-系统) 17 | - [仅限 Windows 系统](#仅限-windows-系统) 18 | - [更多资源](#更多资源) 19 | - [免责声明](#免责声明) 20 | 21 | 22 | ![curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '`\w+`' | tr -d '`' | cowsay -W50](cowsay.png) 23 | 24 | 熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时,发现的一些命令行使用技巧的摘要。有些技巧非常基础,而另一些则相当复杂,甚至晦涩难懂。这篇文章并不长,但当你能够熟练掌握这里列出的所有技巧时,你就学会了很多关于命令行的东西了。 25 | 26 | 这篇文章是[许多作者和译者](AUTHORS.md)共同的成果。 27 | 这里的部分内容 28 | [首次](http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands) 29 | [出现](http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix) 30 | 于 [Quora](http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know), 31 | 但已经迁移到了 GitHub,并由众多高手做出了许多改进。 32 | 如果你在本文中发现了错误或者存在可以改善的地方,请[**贡献你的一份力量**](/CONTRIBUTING.md)。 33 | 34 | ## 前言 35 | 36 | 涵盖范围: 37 | 38 | - 这篇文章不仅能帮助刚接触命令行的新手,而且对具有经验的人也大有裨益。本文致力于做到*覆盖面广*(涉及所有重要的内容),*具体*(给出具体的最常用的例子),以及*简洁*(避免冗余的内容,或是可以在其他地方轻松查到的细枝末节)。在特定应用场景下,本文的内容属于基本功或者能帮助您节约大量的时间。 39 | - 本文主要为 Linux 所写,但在[仅限 OS X 系统](#仅限-os-x-系统)章节和[仅限 Windows 系统](#仅限-windows-系统)章节中也包含有对应操作系统的内容。除去这两个章节外,其它的内容大部分均可在其他类 Unix 系统或 OS X,甚至 Cygwin 中得到应用。 40 | - 本文主要关注于交互式 Bash,但也有很多技巧可以应用于其他 shell 和 Bash 脚本当中。 41 | - 除去“标准的”Unix 命令,本文还包括了一些依赖于特定软件包的命令(前提是它们具有足够的价值)。 42 | 43 | 注意事项: 44 | 45 | - 为了能在一页内展示尽量多的东西,一些具体的信息可以在引用的页面中找到。我们相信机智的你知道如何使用 Google 或者其他搜索引擎来查阅到更多的详细信息。文中部分命令需要您使用 `apt-get`,`yum`,`dnf`,`pacman`, 46 | `pip` 或 `brew`(以及其它合适的包管理器)来安装依赖的程序。 47 | - 遇到问题的话,请尝试使用 [Explainshell](http://explainshell.com/) 去获取相关命令、参数、管道等内容的解释。 48 | 49 | 50 | ## 基础 51 | 52 | - 学习 Bash 的基础知识。具体地,在命令行中输入 `man bash` 并至少全文浏览一遍; 它理解起来很简单并且不冗长。其他的 shell 可能很好用,但 Bash 的功能已经足够强大并且到几乎总是可用的( 如果你*只*学习 zsh,fish 或其他的 shell 的话,在你自己的设备上会显得很方便,但过度依赖这些功能会给您带来不便,例如当你需要在服务器上工作时)。 53 | 54 | - 熟悉至少一个基于文本的编辑器。通常而言 Vim (`vi`) 会是你最好的选择,毕竟在终端中编辑文本时 Vim 是最好用的工具(甚至大部分情况下 Vim 要比 Emacs、大型 IDE 或是炫酷的编辑器更好用)。 55 | 56 | - 学会如何使用 `man` 命令去阅读文档。学会使用 `apropos` 去查找文档。知道有些命令并不对应可执行文件,而是在 Bash 内置好的,此时可以使用 `help` 和 `help -d` 命令获取帮助信息。你可以用 `type 命令` 来判断这个命令到底是可执行文件、shell 内置命令还是别名。 57 | 58 | - 学会使用 `>` 和 `<` 来重定向输出和输入,学会使用 `|` 来重定向管道。明白 `>` 会覆盖了输出文件而 `>>` 是在文件末添加。了解标准输出 stdout 和标准错误 stderr。 59 | 60 | - 学会使用通配符 `*` (或许再算上 `?` 和 `[`...`]`) 和引用以及引用中 `'` 和 `"` 的区别(后文中有一些具体的例子)。 61 | 62 | - 熟悉 Bash 中的任务管理工具:`&`,**ctrl-z**,**ctrl-c**,`jobs`,`fg`,`bg`,`kill` 等。 63 | 64 | - 学会使用 `ssh` 进行远程命令行登录,最好知道如何使用 `ssh-agent`,`ssh-add` 等命令来实现基础的无密码认证登录。 65 | 66 | - 学会基本的文件管理工具:`ls` 和 `ls -l` (了解 `ls -l` 中每一列代表的意义),`less`,`head`,`tail` 和 `tail -f` (甚至 `less +F`),`ln` 和 `ln -s` (了解硬链接与软链接的区别),`chown`,`chmod`,`du` (硬盘使用情况概述:`du -hs *`)。 关于文件系统的管理,学习 `df`,`mount`,`fdisk`,`mkfs`,`lsblk`。知道 inode 是什么(与 `ls -i` 和 `df -i` 等命令相关)。 67 | 68 | - 学习基本的网络管理工具:`ip` 或 `ifconfig`,`dig`。 69 | 70 | - 学习并使用一种版本控制管理系统,例如 `git`。 71 | 72 | - 熟悉正则表达式,学会使用 `grep`/`egrep`,它们的参数中 `-i`,`-o`,`-v`,`-A`,`-B` 和 `-C` 这些是很常用并值得认真学习的。 73 | 74 | - 学会使用 `apt-get`,`yum`,`dnf` 或 `pacman` (具体使用哪个取决于你使用的 Linux 发行版)来查找和安装软件包。并确保你的环境中有 `pip` 来安装基于 Python 的命令行工具 (接下来提到的部分程序使用 `pip` 来安装会很方便)。 75 | 76 | 77 | ## 日常使用 78 | 79 | - 在 Bash 中,可以通过按 **Tab** 键实现自动补全参数,使用 **ctrl-r** 搜索命令行历史记录(按下按键之后,输入关键字便可以搜索,重复按下 **ctrl-r** 会向后查找匹配项,按下 **Enter** 键会执行当前匹配的命令,而按下右方向键会将匹配项放入当前行中,不会直接执行,以便做出修改)。 80 | 81 | - 在 Bash 中,可以按下 **ctrl-w** 删除你键入的最后一个单词,**ctrl-u** 可以删除行内光标所在位置之前的内容,**alt-b** 和 **alt-f** 可以以单词为单位移动光标,**ctrl-a** 可以将光标移至行首,**ctrl-e** 可以将光标移至行尾,**ctrl-k** 可以删除光标至行尾的所有内容,**ctrl-l** 可以清屏。键入 `man readline` 可以查看 Bash 中的默认快捷键。内容有很多,例如 **alt-.** 循环地移向前一个参数,而 **alt-*** 可以展开通配符。 82 | 83 | 84 | - 你喜欢的话,可以执行 `set -o vi` 来使用 vi 风格的快捷键,而执行 `set -o emacs` 可以把它改回来。 85 | 86 | - 为了便于编辑长命令,在设置你的默认编辑器后(例如 `export EDITOR=vim`),**ctrl-x** **ctrl-e** 会打开一个编辑器来编辑当前输入的命令。在 vi 风格下快捷键则是 **escape-v**。 87 | 88 | - 键入 `history` 查看命令行历史记录,再用 `!n`(`n` 是命令编号)就可以再次执行。其中有许多缩写,最有用的大概就是 `!$`, 它用于指代上次键入的参数,而 `!!` 可以指代上次键入的命令了(参考 man 页面中的“HISTORY EXPANSION”)。不过这些功能,你也可以通过快捷键 **ctrl-r** 和 **alt-.** 来实现。 89 | 90 | - `cd` 命令可以切换工作路径,输入 `cd ~` 可以进入 home 目录。要访问你的 home 目录中的文件,可以使用前缀 `~`(例如 `~/.bashrc`)。在 `sh` 脚本里则用环境变量 `$HOME` 指代 home 目录的路径。 91 | 92 | - 回到前一个工作路径:`cd -`。 93 | 94 | - 如果你输入命令的时候中途改了主意,按下 **alt-#** 在行首添加 `#` 把它当做注释再按下回车执行(或者依次按下 **ctrl-a**, **#**, **enter**)。这样做的话,之后借助命令行历史记录,你可以很方便恢复你刚才输入到一半的命令。 95 | 96 | - 使用 `xargs` ( 或 `parallel`)。他们非常给力。注意到你可以控制每行参数个数(`-L`)和最大并行数(`-P`)。如果你不确定它们是否会按你想的那样工作,先使用 `xargs echo` 查看一下。此外,使用 `-I{}` 会很方便。例如: 97 | ```bash 98 | find . -name '*.py' | xargs grep some_function 99 | cat hosts | xargs -I{} ssh root@{} hostname 100 | ``` 101 | 102 | 103 | - `pstree -p` 以一种优雅的方式展示进程树。 104 | 105 | - 使用 `pgrep` 和 `pkill` 根据名字查找进程或发送信号(`-f` 参数通常有用)。 106 | 107 | - 了解你可以发往进程的信号的种类。比如,使用 `kill -STOP [pid]` 停止一个进程。使用 `man 7 signal` 查看详细列表。 108 | 109 | - 使用 `nohup` 或 `disown` 使一个后台进程持续运行。 110 | 111 | - 使用 `netstat -lntp` 或 `ss -plat` 检查哪些进程在监听端口(默认是检查 TCP 端口; 添加参数 `-u` 则检查 UDP 端口)或者 `lsof -iTCP -sTCP:LISTEN -P -n` (这也可以在 OS X 上运行)。 112 | 113 | - `lsof` 来查看开启的套接字和文件。 114 | 115 | - 使用 `uptime` 或 `w` 来查看系统已经运行多长时间。 116 | 117 | - 使用 `alias` 来创建常用命令的快捷形式。例如:`alias ll='ls -latr'` 创建了一个新的命令别名 `ll`。 118 | 119 | - 可以把别名、shell 选项和常用函数保存在 `~/.bashrc`,具体看下这篇[文章](http://superuser.com/a/183980/7106)。这样做的话你就可以在所有 shell 会话中使用你的设定。 120 | 121 | - 把环境变量的设定以及登陆时要执行的命令保存在 `~/.bash_profile`。而对于从图形界面启动的 shell 和 `cron` 启动的 shell,则需要单独配置文件。 122 | 123 | - 要想在几台电脑中同步你的配置文件(例如 `.bashrc` 和 `.bash_profile`),可以借助 Git。 124 | 125 | - 当变量和文件名中包含空格的时候要格外小心。Bash 变量要用引号括起来,比如 `"$FOO"`。尽量使用 `-0` 或 `-print0` 选项以便用 NULL 来分隔文件名,例如 `locate -0 pattern | xargs -0 ls -al` 或 `find / -print0 -type d | xargs -0 ls -al`。如果 for 循环中循环访问的文件名含有空字符(空格、tab 等字符),只需用 `IFS=$'\n'` 把内部字段分隔符设为换行符。 126 | 127 | - 在 Bash 脚本中,使用 `set -x` 去调试输出(或者使用它的变体 `set -v`,它会记录原始输入,包括多余的参数和注释)。尽可能地使用严格模式:使用 `set -e` 令脚本在发生错误时退出而不是继续运行;使用 `set -u` 来检查是否使用了未赋值的变量;试试 `set -o pipefail`,它可以监测管道中的错误。当牵扯到很多脚本时,使用 `trap` 来检测 ERR 和 EXIT。一个好的习惯是在脚本文件开头这样写,这会使它能够检测一些错误,并在错误发生时中断程序并输出信息: 128 | ```bash 129 | set -euo pipefail 130 | trap "echo 'error: Script failed: see failed command above'" ERR 131 | ``` 132 | 133 | - 在 Bash 脚本中,子 shell(使用括号 `(...)`)是一种组织参数的便捷方式。一个常见的例子是临时地移动工作路径,代码如下: 134 | ```bash 135 | # do something in current dir 136 | (cd /some/other/dir && other-command) 137 | # continue in original dir 138 | ``` 139 | 140 | - 在 Bash 中,变量有许多的扩展方式。`${name:?error message}` 用于检查变量是否存在。此外,当 Bash 脚本只需要一个参数时,可以使用这样的代码 `input_file=${1:?usage: $0 input_file}`。在变量为空时使用默认值:`${name:-default}`。如果你要在之前的例子中再加一个(可选的)参数,可以使用类似这样的代码 `output_file=${2:-logfile}`,如果省略了 $2,它的值就为空,于是 `output_file` 就会被设为 `logfile`。数学表达式:`i=$(( (i + 1) % 5 ))`。序列:`{1..10}`。截断字符串:`${var%suffix}` 和 `${var#prefix}`。例如,假设 `var=foo.pdf`,那么 `echo ${var%.pdf}.txt` 将输出 `foo.txt`。 141 | 142 | - 使用括号扩展(`{`...`}`)来减少输入相似文本,并自动化文本组合。这在某些情况下会很有用,例如 `mv foo.{txt,pdf} some-dir`(同时移动两个文件),`cp somefile{,.bak}`(会被扩展成 `cp somefile somefile.bak`)或者 `mkdir -p test-{a,b,c}/subtest-{1,2,3}`(会被扩展成所有可能的组合,并创建一个目录树)。 143 | 144 | - 通过使用 `<(some command)` 可以将输出视为文件。例如,对比本地文件 `/etc/hosts` 和一个远程文件: 145 | ```sh 146 | diff /etc/hosts <(ssh somehost cat /etc/hosts) 147 | ``` 148 | 149 | - 编写脚本时,你可能会想要把代码都放在大括号里。缺少右括号的话,代码就会因为语法错误而无法执行。如果你的脚本是要放在网上分享供他人使用的,这样的写法就体现出它的好处了,因为这样可以防止下载不完全代码被执行。 150 | ```bash 151 | { 152 | # 在这里写代码 153 | } 154 | ``` 155 | 156 | - 了解 Bash 中的“here documents”,例如 `cat <logfile 2>&1` 或者 `some-command &>logfile`。通常,为了保证命令不会在标准输入里残留一个未关闭的文件句柄捆绑在你当前所在的终端上,在命令后添加 `>> 2+3 202 | 5 203 | ``` 204 | 205 | 206 | ## 文件及数据处理 207 | 208 | - 在当前目录下通过文件名查找一个文件,使用类似于这样的命令:`find . -iname '*something*'`。在所有路径下通过文件名查找文件,使用 `locate something` (但注意到 `updatedb` 可能没有对最近新建的文件建立索引,所以你可能无法定位到这些未被索引的文件)。 209 | 210 | - 使用 [`ag`](https://github.com/ggreer/the_silver_searcher) 在源代码或数据文件里检索(`grep -r` 同样可以做到,但相比之下 `ag` 更加先进)。 211 | 212 | - 将 HTML 转为文本:`lynx -dump -stdin`。 213 | 214 | - Markdown,HTML,以及所有文档格式之间的转换,试试 [`pandoc`](http://pandoc.org/)。 215 | 216 | - 当你要处理棘手的 XML 时候,`xmlstarlet` 算是上古时代流传下来的神器。 217 | 218 | - 使用 [`jq`](http://stedolan.github.io/jq/) 处理 JSON。 219 | 220 | - 使用 [`shyaml`](https://github.com/0k/shyaml) 处理 YAML。 221 | 222 | - 要处理 Excel 或 CSV 文件的话,[csvkit](https://github.com/onyxfish/csvkit) 提供了 `in2csv`,`csvcut`,`csvjoin`,`csvgrep` 等方便易用的工具。 223 | 224 | - 当你要处理 Amazon S3 相关的工作的时候,[`s3cmd`](https://github.com/s3tools/s3cmd) 是一个很方便的工具而 [`s4cmd`](https://github.com/bloomreach/s4cmd) 的效率更高。Amazon 官方提供的 [`aws`](https://github.com/aws/aws-cli) 以及 [`saws`](https://github.com/donnemartin/saws) 是其他 AWS 相关工作的基础,值得学习。 225 | 226 | - 了解如何使用 `sort` 和 `uniq`,包括 uniq 的 `-u` 参数和 `-d` 参数,具体内容在后文单行脚本节中。另外可以了解一下 `comm`。 227 | 228 | - 了解如何使用 `cut`,`paste` 和 `join` 来更改文件。很多人都会使用 `cut`,但遗忘了 `join`。 229 | 230 | - 了解如何运用 `wc` 去计算新行数(`-l`),字符数(`-m`),单词数(`-w`)以及字节数(`-c`)。 231 | 232 | - 了解如何使用 `tee` 将标准输入复制到文件甚至标准输出,例如 `ls -al | tee file.txt`。 233 | 234 | - 要进行一些复杂的计算,比如分组、逆序和一些其他的统计分析,可以考虑使用 [`datamash`](https://www.gnu.org/software/datamash/)。 235 | 236 | - 注意到语言设置(中文或英文等)对许多命令行工具有一些微妙的影响,比如排序的顺序和性能。大多数 Linux 的安装过程会将 `LANG` 或其他有关的变量设置为符合本地的设置。要意识到当你改变语言设置时,排序的结果可能会改变。明白国际化可能会使 sort 或其他命令运行效率下降*许多倍*。某些情况下(例如集合运算)你可以放心的使用 `export LC_ALL=C` 来忽略掉国际化并按照字节来判断顺序。 237 | 238 | - 你可以单独指定某一条命令的环境,只需在调用时把环境变量设定放在命令的前面,例如 `TZ=Pacific/Fiji date` 可以获取斐济的时间。 239 | 240 | - 了解如何使用 `awk` 和 `sed` 来进行简单的数据处理。 参阅 [One-liners](#one-liners) 获取示例。 241 | 242 | - 替换一个或多个文件中出现的字符串: 243 | ```sh 244 | perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt 245 | ``` 246 | 247 | - 使用 [`repren`](https://github.com/jlevy/repren) 来批量重命名文件,或是在多个文件中搜索替换内容。(有些时候 `rename` 命令也可以批量重命名,但要注意,它在不同 Linux 发行版中的功能并不完全一样。) 248 | ```sh 249 | # 将文件、目录和内容全部重命名 foo -> bar: 250 | repren --full --preserve-case --from foo --to bar . 251 | # 还原所有备份文件 whatever.bak -> whatever: 252 | repren --renames --from '(.*)\.bak' --to '\1' *.bak 253 | # 用 rename 实现上述功能(若可用): 254 | rename 's/\.bak$//' *.bak 255 | ``` 256 | 257 | - 根据 man 页面的描述,`rsync` 是一个快速且非常灵活的文件复制工具。它闻名于设备之间的文件同步,但其实它在本地情况下也同样有用。在安全设置允许下,用 `rsync` 代替 `scp` 可以实现文件续传,而不用重新从头开始。它同时也是删除大量文件的[最快方法](https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html)之一: 258 | ```sh 259 | mkdir empty && rsync -r --delete empty/ some-dir && rmdir some-dir 260 | ``` 261 | 262 | - 若要在复制文件时获取当前进度,可使用 `pv`,[`pycp`](https://github.com/dmerejkowsky/pycp),[`progress`](https://github.com/Xfennec/progress),`rsync --progress`。若所执行的复制为block块拷贝,可以使用 `dd status=progress`。 263 | 264 | - 使用 `shuf` 可以以行为单位来打乱文件的内容或从一个文件中随机选取多行。 265 | 266 | - 了解 `sort` 的参数。显示数字时,使用 `-n` 或者 `-h` 来显示更易读的数(例如 `du -h` 的输出)。明白排序时关键字的工作原理(`-t` 和 `-k`)。例如,注意到你需要 `-k1,1` 来仅按第一个域来排序,而 `-k1` 意味着按整行排序。稳定排序(`sort -s`)在某些情况下很有用。例如,以第二个域为主关键字,第一个域为次关键字进行排序,你可以使用 `sort -k1,1 | sort -s -k2,2`。 267 | 268 | - 如果你想在 Bash 命令行中写 tab 制表符,按下 **ctrl-v** **[Tab]** 或键入 `$'\t'` (后者可能更好,因为你可以复制粘贴它)。 269 | 270 | - 标准的源代码对比及合并工具是 `diff` 和 `patch`。使用 `diffstat` 查看变更总览数据。注意到 `diff -r` 对整个文件夹有效。使用 `diff -r tree1 tree2 | diffstat` 查看变更的统计数据。`vimdiff` 用于比对并编辑文件。 271 | 272 | - 对于二进制文件,使用 `hd`,`hexdump` 或者 `xxd` 使其以十六进制显示,使用 `bvi`,`hexedit` 或者 `biew` 来进行二进制编辑。 273 | 274 | - 同样对于二进制文件,`strings`(包括 `grep` 等工具)可以帮助在二进制文件中查找特定比特。 275 | 276 | - 制作二进制差分文件(Delta 压缩),使用 `xdelta3`。 277 | 278 | - 使用 `iconv` 更改文本编码。需要更高级的功能,可以使用 `uconv`,它支持一些高级的 Unicode 功能。例如,这条命令移除了所有重音符号: 279 | ```sh 280 | uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt 281 | ``` 282 | 283 | - 拆分文件可以使用 `split`(按大小拆分)和 `csplit`(按模式拆分)。 284 | 285 | - 操作日期和时间表达式,可以用 [`dateutils`](http://www.fresse.org/dateutils/) 中的 `dateadd`、`datediff`、`strptime` 等工具。 286 | 287 | - 使用 `zless`、`zmore`、`zcat` 和 `zgrep` 对压缩过的文件进行操作。 288 | 289 | - 文件属性可以通过 `chattr` 进行设置,它比文件权限更加底层。例如,为了保护文件不被意外删除,可以使用不可修改标记:`sudo chattr +i /critical/directory/or/file` 290 | 291 | - 使用 `getfacl` 和 `setfacl` 以保存和恢复文件权限。例如: 292 | ```sh 293 | getfacl -R /some/path > permissions.txt 294 | setfacl --restore=permissions.txt 295 | ``` 296 | 297 | - 为了高效地创建空文件,请使用 `truncate`(创建[稀疏文件](https://zh.wikipedia.org/wiki/稀疏文件)),`fallocate`(用于 ext4,xfs,btrf 和 ocfs2 文件系统),`xfs_mkfile`(适用于几乎所有的文件系统,包含在 xfsprogs 包中),`mkfile`(用于类 Unix 操作系统,比如 Solaris 和 Mac OS)。 298 | 299 | ## 系统调试 300 | 301 | - `curl` 和 `curl -I` 可以被轻松地应用于 web 调试中,它们的好兄弟 `wget` 也是如此,或者也可以试试更潮的 [`httpie`](https://github.com/jkbrzt/httpie)。 302 | 303 | - 获取 CPU 和硬盘的使用状态,通常使用使用 `top`(`htop` 更佳),`iostat` 和 `iotop`。而 `iostat -mxz 15` 可以让你获悉 CPU 和每个硬盘分区的基本信息和性能表现。 304 | 305 | - 使用 `netstat` 和 `ss` 查看网络连接的细节。 306 | 307 | - `dstat` 在你想要对系统的现状有一个粗略的认识时是非常有用的。然而若要对系统有一个深度的总体认识,使用 [`glances`](https://github.com/nicolargo/glances),它会在一个终端窗口中向你提供一些系统级的数据。 308 | 309 | - 若要了解内存状态,运行并理解 `free` 和 `vmstat` 的输出。值得留意的是“cached”的值,它指的是 Linux 内核用来作为文件缓存的内存大小,而与空闲内存无关。 310 | 311 | - Java 系统调试则是一件截然不同的事,一个可以用于 Oracle 的 JVM 或其他 JVM 上的调试的技巧是你可以运行 `kill -3 ` 同时一个完整的栈轨迹和堆概述(包括 GC 的细节)会被保存到标准错误或是日志文件。JDK 中的 `jps`,`jstat`,`jstack`,`jmap` 很有用。[SJK tools](https://github.com/aragozin/jvm-tools) 更高级。 312 | 313 | - 使用 [`mtr`](http://www.bitwizard.nl/mtr/) 去跟踪路由,用于确定网络问题。 314 | 315 | - 用 [`ncdu`](https://dev.yorhel.nl/ncdu) 来查看磁盘使用情况,它比寻常的命令,如 `du -sh *`,更节省时间。 316 | 317 | - 查找正在使用带宽的套接字连接或进程,使用 [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) 或 [`nethogs`](https://github.com/raboof/nethogs)。 318 | 319 | - `ab` 工具(Apache 中自带)可以简单粗暴地检查 web 服务器的性能。对于更复杂的负载测试,使用 `siege`。 320 | 321 | - [`wireshark`](https://wireshark.org/),[`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html) 和 [`ngrep`](http://ngrep.sourceforge.net/) 可用于复杂的网络调试。 322 | 323 | - 了解 `strace` 和 `ltrace`。这俩工具在你的程序运行失败、挂起甚至崩溃,而你却不知道为什么或你想对性能有个总体的认识的时候是非常有用的。注意 profile 参数(`-c`)和附加到一个运行的进程参数 (`-p`)。 324 | 325 | - 了解使用 `ldd` 来检查共享库。但是[永远不要在不信任的文件上运行](http://www.catonmat.net/blog/ldd-arbitrary-code-execution/)。 326 | 327 | - 了解如何运用 `gdb` 连接到一个运行着的进程并获取它的堆栈轨迹。 328 | 329 | - 学会使用 `/proc`。它在调试正在出现的问题的时候有时会效果惊人。比如:`/proc/cpuinfo`,`/proc/meminfo`,`/proc/cmdline`,`/proc/xxx/cwd`,`/proc/xxx/exe`,`/proc/xxx/fd/`,`/proc/xxx/smaps`(这里的 `xxx` 表示进程的 id 或 pid)。 330 | 331 | - 当调试一些之前出现的问题的时候,[`sar`](http://sebastien.godard.pagesperso-orange.fr/) 非常有用。它展示了 cpu、内存以及网络等的历史数据。 332 | 333 | - 关于更深层次的系统分析以及性能分析,看看 `stap`([SystemTap](https://sourceware.org/systemtap/wiki)),[`perf`](https://en.wikipedia.org/wiki/Perf_(Linux)),以及[`sysdig`](https://github.com/draios/sysdig)。 334 | 335 | - 查看你当前使用的系统,使用 `uname`,`uname -a`(Unix/kernel 信息)或者 `lsb_release -a`(Linux 发行版信息)。 336 | 337 | - 无论什么东西工作得很欢乐(可能是硬件或驱动问题)时可以试试 `dmesg`。 338 | 339 | - 如果你删除了一个文件,但通过 `du` 发现没有释放预期的磁盘空间,请检查文件是否被进程占用: 340 | `lsof | grep deleted | grep "filename-of-my-big-file"` 341 | 342 | 343 | ## 单行脚本 344 | 345 | 一些命令组合的例子: 346 | 347 | - 当你需要对文本文件做集合交、并、差运算时,`sort` 和 `uniq` 会是你的好帮手。具体例子请参照代码后面的,此处假设 `a` 与 `b` 是两内容不同的文件。这种方式效率很高,并且在小文件和上 G 的文件上都能运用(注意尽管在 `/tmp` 在一个小的根分区上时你可能需要 `-T` 参数,但是实际上 `sort` 并不被内存大小约束),参阅前文中关于 `LC_ALL` 和 `sort` 的 `-u` 参数的部分。 348 | ```sh 349 | sort a b | uniq > c # c 是 a 并 b 350 | sort a b | uniq -d > c # c 是 a 交 b 351 | sort a b b | uniq -u > c # c 是 a - b 352 | ``` 353 | 354 | - 使用 `grep . *`(每行都会附上文件名)或者 `head -100 *`(每个文件有一个标题)来阅读检查目录下所有文件的内容。这在检查一个充满配置文件的目录(如 `/sys`、`/proc`、`/etc`)时特别好用。 355 | 356 | 357 | - 计算文本文件第三列中所有数的和(可能比同等作用的 Python 代码快三倍且代码量少三倍): 358 | ```sh 359 | awk '{ x += $3 } END { print x }' myfile 360 | ``` 361 | 362 | - 如果你想在文件树上查看大小/日期,这可能看起来像递归版的 `ls -l` 但比 `ls -lR` 更易于理解: 363 | ```sh 364 | find . -type f -ls 365 | ``` 366 | 367 | - 假设你有一个类似于 web 服务器日志文件的文本文件,并且一个确定的值只会出现在某些行上,假设一个 `acct_id` 参数在 URI 中。如果你想计算出每个 `acct_id` 值有多少次请求,使用如下代码: 368 | ```sh 369 | egrep -o 'acct_id=[0-9]+' access.log | cut -d= -f2 | sort | uniq -c | sort -rn 370 | ``` 371 | 372 | - 要持续监测文件改动,可以使用 `watch`,例如检查某个文件夹中文件的改变,可以用 `watch -d -n 2 'ls -rtlh | tail'`;或者在排查 WiFi 设置故障时要监测网络设置的更改,可以用 `watch -d -n 2 ifconfig`。 373 | 374 | - 运行这个函数从这篇文档中随机获取一条技巧(解析 Markdown 文件并抽取项目): 375 | ```sh 376 | function taocl() { 377 | curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-zh.md| 378 | pandoc -f markdown -t html | 379 | iconv -f 'utf-8' -t 'unicode' | 380 | xmlstarlet fo --html --dropdtd | 381 | xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" | 382 | xmlstarlet unesc | fmt -80 383 | } 384 | ``` 385 | 386 | ## 冷门但有用 387 | 388 | - `expr`:计算表达式或正则匹配 389 | 390 | - `m4`:简单的宏处理器 391 | 392 | - `yes`:多次打印字符串 393 | 394 | - `cal`:漂亮的日历 395 | 396 | - `env`:执行一个命令(脚本文件中很有用) 397 | 398 | - `printenv`:打印环境变量(调试时或在写脚本文件时很有用) 399 | 400 | - `look`:查找以特定字符串开头的单词或行 401 | 402 | - `cut`,`paste` 和 `join`:数据修改 403 | 404 | - `fmt`:格式化文本段落 405 | 406 | - `pr`:将文本格式化成页/列形式 407 | 408 | - `fold`:包裹文本中的几行 409 | 410 | - `column`:将文本格式化成多个对齐、定宽的列或表格 411 | 412 | - `expand` 和 `unexpand`:制表符与空格之间转换 413 | 414 | - `nl`:添加行号 415 | 416 | - `seq`:打印数字 417 | 418 | - `bc`:计算器 419 | 420 | - `factor`:分解因数 421 | 422 | - [`gpg`](https://gnupg.org/):加密并签名文件 423 | 424 | - `toe`:terminfo 入口列表 425 | 426 | - `nc`:网络调试及数据传输 427 | 428 | - `socat`:套接字代理,与 `netcat` 类似 429 | 430 | - [`slurm`](https://github.com/mattthias/slurm):网络流量可视化 431 | 432 | - `dd`:文件或设备间传输数据 433 | 434 | - `file`:确定文件类型 435 | 436 | - `tree`:以树的形式显示路径和文件,类似于递归的 `ls` 437 | 438 | - `stat`:文件信息 439 | 440 | - `time`:执行命令,并计算执行时间 441 | 442 | - `timeout`:在指定时长范围内执行命令,并在规定时间结束后停止进程 443 | 444 | - `lockfile`:使文件只能通过 `rm -f` 移除 445 | 446 | - `logrotate`: 切换、压缩以及发送日志文件 447 | 448 | - `watch`:重复运行同一个命令,展示结果并/或高亮有更改的部分 449 | 450 | - [`when-changed`](https://github.com/joh/when-changed):当检测到文件更改时执行指定命令。参阅 `inotifywait` 和 `entr`。 451 | 452 | - `tac`:反向输出文件 453 | 454 | - `shuf`:文件中随机选取几行 455 | 456 | - `comm`:一行一行的比较排序过的文件 457 | 458 | - `strings`:从二进制文件中抽取文本 459 | 460 | - `tr`:转换字母 461 | 462 | - `iconv` 或 `uconv`:文本编码转换 463 | 464 | - `split` 和 `csplit`:分割文件 465 | 466 | - `sponge`:在写入前读取所有输入,在读取文件后再向同一文件写入时比较有用,例如 `grep -v something some-file | sponge some-file` 467 | 468 | - `units`:将一种计量单位转换为另一种等效的计量单位(参阅 `/usr/share/units/definitions.units`) 469 | 470 | - `apg`:随机生成密码 471 | 472 | - `xz`:高比例的文件压缩 473 | 474 | - `ldd`:动态库信息 475 | 476 | - `nm`:提取 obj 文件中的符号 477 | 478 | - `ab` 或 [`wrk`](https://github.com/wg/wrk):web 服务器性能分析 479 | 480 | - `strace`:调试系统调用 481 | 482 | - [`mtr`](http://www.bitwizard.nl/mtr/):更好的网络调试跟踪工具 483 | 484 | - `cssh`:可视化的并发 shell 485 | 486 | - `rsync`:通过 ssh 或本地文件系统同步文件和文件夹 487 | 488 | - [`wireshark`](https://wireshark.org/) 和 [`tshark`](https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html):抓包和网络调试工具 489 | 490 | - [`ngrep`](http://ngrep.sourceforge.net/):网络层的 grep 491 | 492 | - `host` 和 `dig`:DNS 查找 493 | 494 | - `lsof`:列出当前系统打开文件的工具以及查看端口信息 495 | 496 | - `dstat`:系统状态查看 497 | 498 | - [`glances`](https://github.com/nicolargo/glances):高层次的多子系统总览 499 | 500 | - `iostat`:硬盘使用状态 501 | 502 | - `mpstat`: CPU 使用状态 503 | 504 | - `vmstat`: 内存使用状态 505 | 506 | - `htop`:top 的加强版 507 | 508 | - `last`:登入记录 509 | 510 | - `w`:查看处于登录状态的用户 511 | 512 | - `id`:用户/组 ID 信息 513 | 514 | - [`sar`](http://sebastien.godard.pagesperso-orange.fr/):系统历史数据 515 | 516 | - [`iftop`](http://www.ex-parrot.com/~pdw/iftop/) 或 [`nethogs`](https://github.com/raboof/nethogs):套接字及进程的网络利用情况 517 | 518 | - `ss`:套接字数据 519 | 520 | - `dmesg`:引导及系统错误信息 521 | 522 | - `sysctl`: 在内核运行时动态地查看和修改内核的运行参数 523 | 524 | - `hdparm`:SATA/ATA 磁盘更改及性能分析 525 | 526 | - `lsblk`:列出块设备信息:以树形展示你的磁盘以及磁盘分区信息 527 | 528 | - `lshw`,`lscpu`,`lspci`,`lsusb` 和 `dmidecode`:查看硬件信息,包括 CPU、BIOS、RAID、显卡、USB设备等 529 | 530 | - `lsmod` 和 `modinfo`:列出内核模块,并显示其细节 531 | 532 | - `fortune`,`ddate` 和 `sl`:额,这主要取决于你是否认为蒸汽火车和莫名其妙的名人名言是否“有用” 533 | 534 | 535 | ## 仅限 OS X 系统 536 | 537 | 以下是*仅限于* OS X 系统的技巧。 538 | 539 | - 用 `brew` (Homebrew)或者 `port` (MacPorts)进行包管理。这些可以用来在 OS X 系统上安装以上的大多数命令。 540 | 541 | - 用 `pbcopy` 复制任何命令的输出到桌面应用,用 `pbpaste` 粘贴输入。 542 | 543 | - 若要在 OS X 终端中将 Option 键视为 alt 键(例如在上面介绍的 **alt-b**、**alt-f** 等命令中用到),打开 偏好设置 -> 描述文件 -> 键盘 并勾选“使用 Option 键作为 Meta 键”。 544 | 545 | - 用 `open` 或者 `open -a /Applications/Whatever.app` 使用桌面应用打开文件。 546 | 547 | - Spotlight:用 `mdfind` 搜索文件,用 `mdls` 列出元数据(例如照片的 EXIF 信息)。 548 | 549 | - 注意 OS X 系统是基于 BSD UNIX 的,许多命令(例如 `ps`,`ls`,`tail`,`awk`,`sed`)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影响)。你可以通过标题为 "BSD General Commands Manual" 的 man 页面发现这些不同。在有些情况下 GNU 版本的命令也可能被安装(例如 `gawk` 和 `gsed` 对应 GNU 中的 awk 和 sed )。如果要写跨平台的 Bash 脚本,避免使用这些命令(例如,考虑 Python 或者 `perl` )或者经过仔细的测试。 550 | 551 | - 用 `sw_vers` 获取 OS X 的版本信息。 552 | 553 | ## 仅限 Windows 系统 554 | 555 | 以下是*仅限于* Windows 系统的技巧。 556 | 557 | ### 在 Windows 下获取 Unix 工具 558 | 559 | - 可以安装 [Cygwin](https://cygwin.com/) 允许你在 Microsoft Windows 中体验 Unix shell 的威力。这样的话,本文中介绍的大多数内容都将适用。 560 | 561 | - 在 Windows 10 上,你可以使用 [Bash on Ubuntu on Windows](https://msdn.microsoft.com/commandline/wsl/about),它提供了一个熟悉的 Bash 环境,包含了不少 Unix 命令行工具。好处是它允许 Linux 上编写的程序在 Windows 上运行,而另一方面,Windows 上编写的程序却无法在 Bash 命令行中运行。 562 | 563 | - 如果你在 Windows 上主要想用 GNU 开发者工具(例如 GCC),可以考虑 [MinGW](http://www.mingw.org/) 以及它的 [MSYS](http://www.mingw.org/wiki/msys) 包,这个包提供了例如 bash,gawk,make 和 grep 的工具。MSYS 并不包含所有可以与 Cygwin 媲美的特性。当制作 Unix 工具的原生 Windows 端口时 MinGW 将特别地有用。 564 | 565 | - 另一个在 Windows 下实现接近 Unix 环境外观效果的选项是 [Cash](https://github.com/dthree/cash)。注意在此环境下只有很少的 Unix 命令和命令行可用。 566 | 567 | ### 实用 Windows 命令行工具 568 | 569 | - 可以使用 `wmic` 在命令行环境下给大部分 Windows 系统管理任务编写脚本以及执行这些任务。 570 | 571 | - Windows 实用的原生命令行网络工具包括 `ping`,`ipconfig`,`tracert`,和 `netstat`。 572 | 573 | - 可以使用 `Rundll32` 命令来实现[许多有用的 Windows 任务](http://www.thewindowsclub.com/rundll32-shortcut-commands-windows) 。 574 | 575 | ### Cygwin 技巧 576 | 577 | - 通过 Cygwin 的包管理器来安装额外的 Unix 程序。 578 | 579 | - 使用 `mintty` 作为你的命令行窗口。 580 | 581 | - 要访问 Windows 剪贴板,可以通过 `/dev/clipboard`。 582 | 583 | - 运行 `cygstart` 以通过默认程序打开一个文件。 584 | 585 | - 要访问 Windows 注册表,可以使用 `regtool`。 586 | 587 | - 注意 Windows 驱动器路径 `C:\` 在 Cygwin 中用 `/cygdrive/c` 代表,而 Cygwin 的 `/` 代表 Windows 中的 `C:\cygwin`。要转换 Cygwin 和 Windows 风格的路径可以用 `cygpath`。这在需要调用 Windows 程序的脚本里很有用。 588 | 589 | - 学会使用 `wmic`,你就可以从命令行执行大多数 Windows 系统管理任务,并编成脚本。 590 | 591 | - 要在 Windows 下获得 Unix 的界面和体验,另一个办法是使用 [Cash](https://github.com/dthree/cash)。需要注意的是,这个环境支持的 Unix 命令和命令行参数非常少。 592 | 593 | - 要在 Windows 上获取 GNU 开发者工具(比如 GCC)的另一个办法是使用 [MinGW](http://www.mingw.org/) 以及它的 [MSYS](http://www.mingw.org/wiki/msys) 软件包,该软件包提供了 bash、gawk、make、grep 等工具。然而 MSYS 提供的功能没有 Cygwin 完善。MinGW 在创建 Unix 工具的 Windows 原生移植方面非常有用。 594 | 595 | ## 更多资源 596 | 597 | - [awesome-shell](https://github.com/alebcay/awesome-shell):一份精心组织的命令行工具及资源的列表。 598 | - [awesome-osx-command-line](https://github.com/herrbischoff/awesome-osx-command-line):一份针对 OS X 命令行的更深入的指南。 599 | - [Strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/):为了编写更好的脚本文件。 600 | - [shellcheck](https://github.com/koalaman/shellcheck):一个静态 shell 脚本分析工具,本质上是 bash/sh/zsh 的 lint。 601 | - [Filenames and Pathnames in Shell](http://www.dwheeler.com/essays/filenames-in-shell.html):有关如何在 shell 脚本里正确处理文件名的细枝末节。 602 | - [Data Science at the Command Line](http://datascienceatthecommandline.com/#tools):用于数据科学的一些命令和工具,摘自同名书籍。 603 | 604 | ## 免责声明 605 | 606 | 除去特别小的工作,你编写的代码应当方便他人阅读。能力往往伴随着责任,你 *有能力* 在 Bash 中玩一些奇技淫巧并不意味着你应该去做!;) 607 | 608 | 609 | ## 授权条款 610 | 611 | [![Creative Commons License](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/) 612 | 613 | 本文使用授权协议 [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)。 614 | -------------------------------------------------------------------------------- /admin/authors-info.yml: -------------------------------------------------------------------------------- 1 | # This file is used to configure the "ghizmo assemble-authors" command. 2 | 3 | header: | 4 | This work is the result of the effort of many people around the world. 5 | Contributors are listed in alphabetical order by GitHub login. 6 | 7 | Some contributors are also assigned roles as maintainers. 8 | They have kindly agreed to review and help update future contributions for the translation or section they own. 9 | 10 | footer: | 11 | Numbers link to commits/issues. 12 | For simplicity, this file is maintained only in English. 13 | 14 | If your name does not appear as you would like it above, verify your name on your GitHub profile. 15 | Also confirm that your commits are using the correct e-mail to it is linked to your profile. 16 | 17 | If you see inaccuracies or omissions, please file an issue, or edit the authors-info.yml file, regenerate, and file a PR. 18 | 19 | exclude: 20 | gitter-badger 21 | ReadmeCritic 22 | 23 | roles: 24 | jlevy: original author and project maintainer 25 | ceoaliongroo: translation maintainer (es) 26 | aaossa: translator (es) 27 | BishopWolf: translator (es) 28 | doublemarket: translation maintainer (ja) 29 | Ungsik-Yun: translation maintainer (ko) 30 | Snowcat8436: translator (ko) 31 | ujuc: translator (ko) 32 | hunkim: translator (ko) 33 | niltonvasques : translation maintainer (pt) 34 | vcvpaiva: translator (pt) 35 | olegberman: translation maintainer (ru) 36 | spmbt: translator (ru) 37 | osmero: translator (ru) 38 | grigory-rechistov: translator (ru) 39 | kastian: translator (ru) 40 | githubashto: translator (ru) 41 | petk: translation maintainer (sl) 42 | Psycho7: translation maintainer (zh) 43 | xuchunyang: translator (zh) 44 | stevenlordiam: translator (zh) 45 | Armour: translator (zh) 46 | stepan0904: translation (uk) 47 | dmytro: translation maintainer (uk) 48 | francescomalatesta: translation maintainer (it) 49 | lsrom: translation maintainer (cs) 50 | ericguirbal: translation maintainer (fr) 51 | rverchere: translator (fr) 52 | kevingo: translation maintainer (zh-Hant) 53 | anna-d: translation maintainer (el) 54 | S1SYPHOS: translation maintainer (de) 55 | gernd: translator (de) 56 | dspinellis: section maintainer (Windows) 57 | mihaimaruseac: translation maintainer (ro) 58 | bgdnlp: translator (ro) 59 | 23Pstars: translation maintainer (id) 60 | koh7: translator (ja) 61 | 62 | groups: 63 | - name: Maintainers 64 | members: 65 | - jlevy 66 | - ceoaliongroo 67 | - doublemarket 68 | - Ungsik-Yun 69 | - niltonvasques 70 | - olegberman 71 | - petk 72 | - Psycho7 73 | - stepan0904 74 | - dmytro 75 | - francescomalatesta 76 | - lsrom 77 | - ericguirbal 78 | - kevingo 79 | - anna-d 80 | - S1SYPHOS 81 | - dspinellis 82 | - mihaimaruseac 83 | - 23Pstars 84 | - name: Translators 85 | members: 86 | - aaossa 87 | - BishopWolf 88 | - Snowcat8436 89 | - ujuc 90 | - hunkim 91 | - vcvpaiva 92 | - spmbt 93 | - osmero 94 | - grigory-rechistov 95 | - kastian 96 | - githubashto 97 | - xuchunyang 98 | - stevenlordiam 99 | - Armour 100 | - rverchere 101 | - gernd 102 | - bgdnlp 103 | - koh7 104 | - name: Contributors 105 | 106 | -------------------------------------------------------------------------------- /cowsay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jlevy/the-art-of-command-line/6b50745d2e788add2e8f1ed29010e72659a9a074/cowsay.png --------------------------------------------------------------------------------