以下はAndrewによる記事、101 Bash Commands and Tips for Beginners to Expertsの日本語訳です。
一部を除き、上から順にコマンドを打って確かめることができるようになっています。
読むだけではなく、実際に打って試してみることで理解が早まることでしょう。
101 Bash Commands and Tips for Beginners to Experts
一年前まで、私はもっぱらMacOSとUbuntuのふたつのOSで作業をしていました。
両OSにおいて、私のデフォルトシェルはbashです。
過去6、7年ほどbashで仕事をしているため、bashがどのように動作するか、ある程度は理解しているつもりです。
従って、bashを始めたばかりの人にとって一般的で有用なコマンドについて、いくつか解説していきたいと思います。
また、bashについて知っているべきことを全て知っていると思っている人も、とりあえず見ていってください。
あなたが忘れているかもしれない、使うことで仕事がより簡単になるかもしれない、TIPSやリマインダのヒントを鏤めました。
以下のコマンドは段階を踏んで進んでいくので、bashを使い始めたばかりであっても、最初から最後まで順番に進んでいくことができます。
最初は簡単で、徐々に難しく一般的ではないコマンドを出していきます。
The Basics
First Commands, Navigating the Filesystem
最初のコマンドはファイルシステムのナビゲーション。
最近のファイルシステムはディレクトリツリー構造を持っています。
ディレクトリは親のないルートディレクトリ、もしくは一つの親を持つサブディレクトリのいずれかです。
ディレクトリツリーを逆方向(子から親へ)移動し続けると、最終的には必ずルートディレクトリに到達します。
一部のファイルシステムには複数のルートディレクトリを持つものもありますが(WindowsのC:\
、A:\
など)、UnixやUnixライクOSには単一のルートディレクトリ/
しかありません。
pwd / ls / cd
ファイルシステム内で作業する場合、ユーザは常にどこかのディレクトリ、すなわちカレントディレクトリもしくは作業ディレクトリと呼ばれる場所にいます。
カレントディレクトリはpwd
コマンドで確認することができます。
[ andrew@pc01 ~ ]$ pwd
/home/andrew
カレントディレクトリの中身、ファイルや子ディレクトリなどを参照するのはls
コマンドです。
[ andrew@pc01 ~ ]$ ls
Git TEST jdoc test test.file
おまけ
ls -a
で隠しファイル(.で始まるなど)を表示する。
ls -l
でファイルの詳細も表示する。
ls -l -a
のように複数のオプションを連ねられる。
ls -l -a
のかわりにls -la
と書くこともできる。
カレントディレクトリを変更するのはcd
コマンドです。
[ andrew@pc01 ~ ]$ cd TEST/
[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST
[ andrew@pc01 TEST ]$ cd A
[ andrew@pc01 A ]$ pwd
/home/andrew/TEST/A
cd ..
で親ディレクトリに移動することができます。
[ andrew@pc01 A ]$ cd ..
[ andrew@pc01 TEST ]$ pwd
/home/andrew/TEST
cd ~
あるいは単にcd
で、どこからでもユーザのホームディレクトリ(通常は/home/username
)に戻ってきます。
[ andrew@pc01 TEST ]$ cd
[ andrew@pc01 ~ ]$ pwd
/home/andrew
おまけ
cd ~user
は、"userのホームディレクトリにcd"という意味。
cd ../..
のように一気に多段ディレクトリ移動ができる。
ひとつ前にいたディレクトリに戻るのはcd -
。
.
はカレントディレクトリのこと。よってcd .
は何もしない。
; / && / &
コマンドラインに入力するのはコマンドと呼ばれるもので、そしてコマンドはPCのどこかに保存されているプログラムを実行させます。
このプログラムはLinuxのビルトインコマンドであることもあれば、誰かが作ったアプリであることもあり、そしてあなたが作ったコードであるかもしれません。
時折、複数のコマンドを連続して実行したいことがあります。
そのためにはセミコロン;
を使います。
[ andrew@pc01 ~ ]$ ls; pwd
Git TEST jdoc test test.file
/home/andrew
上のコマンドは、まずls
でカレントディレクトリの中身を表示し、次いでpwd
でカレントディレクトリの位置を表示します。
コマンドを連続実行するためのもうひとつ便利なツールが&&
です。
これを使うと、左側のコマンドが失敗した場合は右のコマンドが実行されません。
;
や&&
は連続で使うことができます。
# cdでtypoしたのでpwd以降は実行されない
[ andrew@pc01 ~ ]$ cd /Giit/Parser && pwd && ls && cd
-bash: cd: /Giit/Parser: No such file or directory
# 成功したので後続のコマンドも実行される
[ andrew@pc01 ~ ]$ cd Git/Parser/ && pwd && ls && cd
/home/andrew/Git/Parser
README.md doc.sh pom.xml resource run.sh shell.sh source src target
;
を使った場合は、手前のコマンドが失敗したとしても後ろのコマンドが実行されます。
# pwdに失敗したけどpwdやlsが動く
[ andrew@pc01 ~ ]$ cd /Giit/Parser ; pwd ; ls
-bash: cd: /Giit/Parser: No such file or directory
/home/andrew
Git TEST jdoc test test.file
&
は一見&&
と似たように見えますが、実際は全く異なる機能です。
実行に長い時間がかかるコマンドを実行すると、そのコマンドの実行が終了するまでコマンドラインは何もできなくなります。
コマンドの後ろに&
を書くと待ちが発生しなくなり、古いコマンドがまだ動いている状態でも、次のコマンドを実行することができるようになります。
[ andrew@pc01 ~ ]$ cd Git/Parser && mvn package & cd
[1] 9263
おまけ
&
を使ってコマンドを隠すことを、我々はジョブ(あるいはプロセス)のバックグラウンド化と呼んでいる。
現在バックグラウンド状態のジョブはjobs
コマンドで確認することができる。
[ andrew@pc01 ~ ]$ jobs
[1]+ Running cd Git/Parser/ && mvn package &
Getting Help
-h
ほとんどのコマンドは、-h
あるいは--help
でコマンドのヘルプを表示してくれます。
[ andrew@pc01 ~ ]$ du --help
Usage: du [OPTION]... [FILE]...
or: du [OPTION]... --files0-from=F
Summarize disk usage of the set of FILEs, recursively for directories.
Mandatory arguments to long options are mandatory for short options too.
-0, --null end each output line with NUL, not newline
-a, --all write counts for all files, not just directories
--apparent-size print apparent sizes, rather than disk usage; although
the apparent size is usually smaller, it may be
larger due to holes in ('sparse') files, internal
fragmentation, indirect blocks, and the like
-B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,
'-BM' prints sizes in units of 1,048,576 bytes;
see SIZE format below
...
man
大抵のコマンドは、man
コマンドに続けて打つとコマンドのマニュアルを表示することができます。
q
でマニュアルを終了します。
LS(1) User Commands LS(1)
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is speci-
fied.
Mandatory arguments to long options are mandatory for short options
too.
...
Viewing and Editing Files
head / tail / cat / less
head
はファイルの最初の数行を出力します。
出力行数のデフォルトは10で、-n
で変更できます。
# 最初の3行を表示
[ andrew@pc01 ~ ]$ head -n 3 c
this
file
has
tail
は逆にファイルの最後の数行を出力します。
出力行数はhead
と同じように指定するか、もしくは-n +N
でN行目から最後までを出力できます。
# 4行目から最後までを表示
[ andrew@pc01 ~ ]$ tail -n +4 c
exactly
six
lines
cat
は複数のファイルを連結し、その結果を標準出力(通常はターミナル)に送信します。
しかしこのコマンドは、複数のファイルや、単に1ファイルの中身をさっと確認するために使われることがしばしばあります。
そのような使い方をすると猫の無駄遣いで告発される可能性がありますが、たいした害はないので気にしなくてもかまいません。
[ andrew@pc01 ~ ]$ cat a
file a
[ andrew@pc01 ~ ]$ cat a b
file a
file b
ファイルを素早く表示するもうひとつの方法がless
で、これを使うと読み取り専用のvim
のようなウィンドウが開きます。
実はmore
というコマンドもあるのですが、less
のほうが優位なので出番はありません。
もっと詳しく(more)、いや少なく?(less)知りたい場合は、lessとmoreのmanページを参照してください。
nano / nedit
nano
は必要最小限のコマンドラインテキストエディタです。
初心者や、100万のショートカットを覚えたくないユーザにとっては最適の優れたエディタです。
私のキャリアにおいても、最初の数年間はnano
だけで十分でした。
nano
で独自のシンタックスハイライトを定義するのは大変なので、さすがにそろそろ別の強力なエディタを検討し始めていますが。
nedit
は小規模なグラフィカルテキストエディタで、X Windowを開き、クリック編集、ドラッグアンドドロップ、構文強調表示等が可能です。
スクリプトに小さな変更を加えながら何度も実行したいとき、私はよくnedit
を使用します。
その他の一般的なCLI/GUIテキストエディタとして、emacs
、vi
、vim
、gedit
、Notepad++
、Atom
、そしてその他たくさんの選択肢が存在します。
私が触った中でも特に魅力的で推奨できると感じたものは、Micro
、Light Table
、そしてVS Code
です。
最近のエディタは全て、検索、置換、構文強調表示などの便利機能を標準装備しています。
vi
やemacs
はnano
やnedit
より遙かに多くの機能がありますが、同時に学習曲線も急坂です。
エディタを色々試してみて、自分に合ったものを探してみてください。
Creating and Deleting Files and Directories
ファイル・ディレクトリの作成と削除。
touch
touch
はファイルのタイムスタンプを更新するために作られたものですが、空のファイルを作るためにも利用できます。
nano
などのテキストエディタで新規ファイルを作成してみましょう。
[ andrew@pc01 ex ]$ ls
[ andrew@pc01 ex ]$ nano a
/* ここで保存してエディタを終了 */
[ andrew@pc01 ex ]$ ls
a
touch
なら1コマンドです。
[ andrew@pc01 ex ]$ touch b && ls
a b
おまけ
Ctrl+z
で現在実行中のプロセスをバックグラウンドにできる。
fg
コマンドでプロセスに戻る。
[ andrew@pc01 ex ]$ nano a
/* ここでCtrl + z */
Use fg to return to nano
[1]+ Stopped nano a
[ andrew@pc01 ex ]$ fg
/* 編集画面に戻った */
さらにおまけ
Ctrl+c
だと現在実行中のプロセスを強制終了する。
バックグラウンドプロセスを強制終了するにはkill %N
。
Nに入れるプロセス番号はjobs
コマンドで確認できる。
mkdir / rm / rmdir
空のディレクトリを作るのはmkdir
コマンドです。
[ andrew@pc01 ex ]$ ls && mkdir c && ls
a b
a b c
rm
でファイルを削除できますが、削除すると元に戻せません。
注意してください。
[ andrew@pc01 ex ]$ rm a && ls
b c
削除確認の警告を行いたい場合は-i
オプションを追加しましょう。
[ andrew@pc01 ex ]$ rm -i b
rm: remove regular empty file 'b'? y
空のディレクトリを削除するのはrmdir
です。
空のディレクトリでls -a
すると、カレントディレクトリ.
と親ディレクトリ..
だけが表示されます。
[ andrew@pc01 ex ]$ rmdir c && ls -a
. ..
rmdir
では、空でないディレクトリは削除できません。
[ andrew@pc01 ex ]$ cd .. && ls test/
*.txt 0.txt 1.txt a a.txt b c
[ andrew@pc01 ~ ]$ rmdir test/
rmdir: failed to remove 'test/': Directory not empty
中身の入ったディレクトリを全て強制的に削除するには、rm -rf
を使います。
-r
は再帰、-f
は強制実行するオプションです。
[ andrew@pc01 ~ ]$ rm –rf test
Moving and Copying Files, Making Links, Command History
ファイルの移動、コピー、リンク、コマンド履歴。
mv / cp / ln
ファイルの移動、リネームはmv
です。
ディレクトリを移動してファイル名をそのままにする、ファイル名もついでに変更するといったことができます。
[ andrew@pc01 ex ]$ ls && mv a e && ls
a b c d
b c d e
コピーはcp
です。
[ andrew@pc01 ex ]$ cp e e2 && ls
b c d e e2
ln
はファイルへのハードリンクを作成します。
# 第一引数が対象ファイル、第二引数がリンク名
[ andrew@pc01 ex ]$ ln b f && ls
b c d e e2 f
ln -s
でシンボリックリンクが作成できます。
[ andrew@pc01 ex ]$ ln -s b g && ls
b c d e e2 f g
ハードリンクは同じメモリを参照するひとつのファイルへの別名を作ります。
シンボリックリンクは元のファイル名を追跡するだけで、ファイル実体を参照するのは元ファイルだけです。
これ以上の詳細についてはWhat is the difference between a symbolic link and a hard link?を見てください。
Command History
bashは、実行したコマンドを再実行するために役立つ機能をふたつ持っています。
ひとつめの機能はタブ補完です。
コマンドの一部を入力したところでTABを押すと、何を打とうとしているのか端末が推測してくれます。
[ andrew@pc01 dir ]$ ls <ENTER>
anotherlongfilename thisisalongfilename anewfilename
[ andrew@pc01 dir ]$ ls t <TAB>
TABを押すと、以下のようにコマンドが最後まで補完されます。
[ andrew@pc01 dir ]$ ls thisisalongfilename <ENTER>
thisisalongfilename
特定しきれない場合はTABを何度か押すことになります。
[ andrew@pc01 dir ]$ ls a <TAB>
[ andrew@pc01 dir ]$ ls an <TAB>
anewfilename anotherlongfilename
bashは以前に実行したコマンドを幾つか覚えており、Ctrl+R
でその履歴を検索することができます。
(reverse-i-search)`':
ここでanew
と入力すると、その文字が含まれるコマンドのうち最後に実行したものが出てきます。
(reverse-i-search)`anew': touch anewfilename
Directory Trees, Disk Usage, and Processes
ディレクトリツリー、ディスク使用量、プロセス。
mkdir –p / tree
mkdir
はデフォルトではひとつのディレクトリのみを作成します。
どういうことかというと、ディレクトリd/e
が存在しないときにディレクトリd/e/f
を作ることはできないということです。
[ andrew@pc01 ex ]$ ls && mkdir d/e/f
a b c
mkdir: cannot create directory 'd/e/f': No such file or directory
-p
オプションを付けることで、深い階層のディレクトリも一気に作成してくれます。
[ andrew@pc01 ex ]$ mkdir -p d/e/f && ls
a b c d
tree
コマンドはディレクトリツリーをいいかんじにビジュアル化して表示してくるので、ディレクトリ構造を把握するのに役立ちます。
デフォルトでは指定ディレクトリ以下のディレクトリツリーを全て示しますが、-L
オプションで階層を限定することもできます。
[ andrew@pc01 ex ]$ tree -L 2
.
|-- a
|-- b
|-- c
`-- d
`--e
3 directories, 2 files
空のディレクトリを表示させたくないときは--prune
オプションを使います。
このオプションは再帰的なので、空のディレクトリだけが入った空でないディレクトリも消えることに注意しましょう。
[ andrew@pc01 ex ]$ tree --prune
.
|-- a
`-- b
df / du / ps
df
はディスクおよびシステムの容量がどれだけ使用されているかを一覧表示します。
[ andrew@pc01 ex ]$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 126G 0 126G 0% /dev
tmpfs 26G 2.0G 24G 8% /run
/dev/mapper/ubuntu--vg-root 1.6T 1.3T 252G 84% /
...
このコマンドにおいては、-h
オプションは"ヘルプ表示"ではなく"人間が見てわかりやすく表示"を意味します。
いくつかのコマンドは、このオプションを使うことで、バイト数そのままではなくキロバイトK、ギガバイトGなどでファイルやディスク容量を出力してくれます。
du
は指定ディレクトリとそのサブディレクトリの使用量を表示します。
あるハードディスクの使用量を知りたい場合はdf
、あるディレクトリの使用量を知りたいときはdu
を使います。
[ andrew@pc01 ex ]$ du
4 ./d/e/f
8 ./d/e
12 ./d
4 ./c
20 .
du
は--max-depth=N
オプションを受け取り、指定した階層のディレクトリまでを表示します。
[ andrew@pc01 ex ]$ du -h --max-depth=1
12K ./d
4.0K ./c
20K .
ps
はユーザが実行中の全てのプロセス(ジョブ)を表示します。
[ andrew@pc01 ex ]$ ps
PID TTY TIME CMD
16642 pts/15 00:00:00 ps
25409 pts/15 00:00:00 bash
Miscellaneous
passwd / logout / exit
パスワード変更コマンドはpasswd
です。
確認のために現在のコマンドを一回と、変更後のパスワードを2回入力する必要があるため、入力ミスすることはないでしょう。
[ andrew@pc01 dir ]$ passwd
Changing password for andrew.
(current) UNIX password: <現在のパスワード>
Enter new UNIX password: <新パスワード>
Retype new UNIX password: <新パスワードを再入力>
passwd: password updated successfully
logout
で現在のログインシェルが終了します。
[ andrew@pc01 dir ]$ logout
──────────────────────────────────────────────────────────────────────────────
Session stopped
- Press <return> to exit tab
- Press R to restart session
- Press S to save terminal output to file
exit
はサブシェルを含め全て終了します。
[ andrew@pc01 ~ ]$ exit
logout
──────────────────────────────────────────────────────────────────────────────
Session stopped
- Press <return> to exit tab
- Press R to restart session
- Press S to save terminal output to file
clear / *
clear
を実行するとカーソルが画面の一番上に移動します。
実際やってることは現在の行の下に空白行を追加しているだけですが、ワークスペースをクリアするのに有用です。
ファイルの検索にはglob(*、ワイルドカード、Kleene Star)が便利です。
以下の2コマンドの違いについて注意してください。
[ andrew@pc01 ~ ]$ ls Git/Parser/source/
PArrayUtils.java PFile.java PSQLFile.java PWatchman.java
PDateTimeUtils.java PFixedWidthFile.java PStringUtils.java PXSVFile.java
PDelimitedFile.java PNode.java PTextFile.java Parser.java
[ andrew@pc01 ~ ]$ ls Git/Parser/source/PD*
Git/Parser/source/PDateTimeUtils.java Git/Parser/source/PDelimitedFile.java
globは1コマンド中に何度も使用することができ、"0文字以上の文字列"に一致します。
[ andrew@pc01 ~ ]$ ls Git/Parser/source/P*D*m*
Git/Parser/source/PDateTimeUtils.java Git/Parser/source/PDelimitedFile.java
Intermediate
Disk, Memory, and Processor Usage
ncdu
ncdu
(NCurses Disk Usage)はファイル使用量の概要を表示する、改善版du
のようなコマンドです。
読み取り専用のvim
のようなウィンドウが開くので、終了する際はq
を押しましょう。
[ andrew@pc01 ~ ]$ ncdu
ncdu 1.11 ~ Use the arrow keys to navigate, press ? for help
--- /home/andrew -------------------------------------------------------------
148.2 MiB [##########] /.m2
91.5 MiB [###### ] /.sbt
79.8 MiB [##### ] /.cache
64.9 MiB [#### ] /.ivy2
40.6 MiB [## ] /.sdkman
30.2 MiB [## ] /.local
27.4 MiB [# ] /.mozilla
24.4 MiB [# ] /.nanobackups
10.2 MiB [ ] .confout3.txt
8.4 MiB [ ] /.config
5.9 MiB [ ] /.nbi
5.8 MiB [ ] /.oh-my-zsh
4.3 MiB [ ] /Git
3.7 MiB [ ] /.myshell
1.7 MiB [ ] /jdoc
1.5 MiB [ ] .confout2.txt
1.5 MiB [ ] /.netbeans
1.1 MiB [ ] /.jenv
564.0 KiB [ ] /.rstudio-desktop
Total disk usage: 552.7 MiB Apparent size: 523.6 MiB Items: 14618
top / htop
top
は、現在実行されている全てのプロセスと所有者、メモリ使用量などを表示します。
そしてhtop
はインタラクティブな改良版top
です。
いずれも-u username
オプションで該当ユーザのプロセスだけを表示することができます。
REPLs and Software Versions
REPLs
REPLはRead-Eval-Print Loop
の略で、コマンドラインと同じようなものですが、通常はプログラミング言語との対話的ウィンドウに対して呼ばれます。
PythonのREPLはpython
コマンドで始めることができ、quit()
関数で終了します。
[ andrew@pc01 ~ ]$ python
Python 3.5.2 (default, Nov 12 2018, 13:43:14) ...
>>> quit()
RのREPLはR
コマンドで始まり、q()
関数で終了です。
[ andrew@pc01 ~ ]$ R
R version 3.5.2 (2018-12-20) --"Eggshell Igloo" ...
> q()
Save workspace image? [y/n/c]: n
ScalaのREPLはscala
コマンドで始まり、quit
コマンドで終了です。
[ andrew@pc01 ~ ]$ scala
Welcome to Scala 2.11.12 ...
scala> :quit
JavaのREPLはjshell
コマンドで始まり、/exit
コマンドで終了です。
[ andrew@pc01 ~ ]$ jshell
| Welcome to JShell--Version 11.0.1 ...
jshell> /exit
これらのREPLはCtrl+d
でも終了できます。
Ctrl+d
はUnixのEOFであり、入力の終端を意味します。
-version / --version / -v
ほとんどのコマンドやプログラムは、そのソフトウェアバージョンを表示する-version
もしくは--version
オプションがあります。
ほとんどのアプリケーションにも同じオプションが用意されています。
[ andrew@pc01 ~ ]$ ls --version
ls (GNU coreutils) 8.25 ...
[ andrew@pc01 ~ ]$ ncdu -version
ncdu 1.11
[ andrew@pc01 ~ ]$ python --version
Python 3.5.2
ただし、稀にあまり馴染みのないオプションも存在します。
[ andrew@pc01 ~ ]$ sbt scalaVersion
...
[info] 2.12.4
バージョンを表すオプションとして-v
を使うプログラムもあります。
しかし多くの場合-v
は'verbose'を意味し、診断情報やデバッグ情報といった多くの詳細情報も出力します。
SCP(1) BSD General Commands Manual SCP(1)
NAME
scp -- secure copy (remote file copy program)
...
-v Verbose mode. Causes scp and ssh(1) to print debugging messages
about their progress. This is helpful in debugging connection,
authentication, and configuration problems.
...
Environment Variables and Aliases
Environment Variables
環境変数("env vars"と略されることもある)は、bash
シェル上で作成・使用できる永続変数のことです。
これらは=
で定義し、$
で参照します。
pritenv
で現在定義されている全ての環境変数を確認することができます。
[ andrew@pc01 ~ ]$ printenv
SPARK_HOME=/usr/local/spark
TERM=xterm
...
新しい環境変数を定義しましょう。
=
の前後にスペースを入れてはいけません。
[ andrew@pc01 ~ ]$ myvar=hello
定義した環境変数はecho
で取得できます。
ただし変数の頭に$
を付けます。
[ andrew@pc01 ~ ]$ echo $myvar
hello
スペースやその他の空白を含む値を指定したいときは、値を"
で囲まなければなりません。
また環境変数は警告無しに上書きできるので気をつけましょう。
[ andrew@pc01 ~ ]$ myvar="hello, world!" && echo $myvar
hello, world!
環境変数をexport
コマンド付きで定義することもできます。
そうすると、サブシェル内でもその環境変数を参照することができるようになります。
[ andrew@pc01 ~ ]$ export myvar="another one" && echo $myvar
another one
環境変数の設定を解除するには、=
の右側を空欄にして決定するか、unset
コマンドを使用します。
[ andrew@pc01 ~ ]$ unset mynewvar
[ andrew@pc01 ~ ]$ echo $mynewvar
Aliases
エイリアスは環境変数に似ていますが、普通は異なる目的で利用されます。
長いコマンドを短く置き換えるために使用されます。
[ andrew@pc01 apidocs ]$ ls -l -a -h -t
total 220K
drwxr-xr-x 5 andrew andrew 4.0K Dec 21 12:37 .
-rw-r--r-- 1 andrew andrew 9.9K Dec 21 12:37 help-doc.html
-rw-r--r-- 1 andrew andrew 4.5K Dec 21 12:37 script.js
...
[ andrew@pc01 apidocs ]$ alias lc="ls -l -a -h -t"
[ andrew@pc01 apidocs ]$ lc
total 220K
drwxr-xr-x 5 andrew andrew 4.0K Dec 21 12:37 .
-rw-r--r-- 1 andrew andrew 9.9K Dec 21 12:37 help-doc.html
-rw-r--r-- 1 andrew andrew 4.5K Dec 21 12:37 script.js
...
エイリアスの削除はunalias
です。
[ andrew@pc01 apidocs ]$ unalias lc
[ andrew@pc01 apidocs ]$ lc
The program 'lc' is currently not installed. ...
おまけ
環境変数とエイリアスの違い。
一部のプログラムでは、そのプログラム専用のエイリアスを設定できる。gitの例。
Basic bash Scripting
bash Scripts
bashスクリプト(シェルスクリプト)を使うと、複雑なプロセスを自動化し、再利用可能な形にパッケージ化することができます。
拡張子は通常.sh
です。
bashスクリプトには、通常のコマンドをいくらでも詰め込むことができます。
[ andrew@pc01 ~ ]$ echo "ls && touch file && ls" > ex.sh
作成したシェルスクリプトは、source
もしくはsh
コマンドで実行可能です。
[ andrew@pc01 ~ ]$ source ex.sh
Desktop Git TEST c ex.sh project test
Desktop Git TEST c ex.sh file project test
chmod
コマンドで、シェルスクリプトを直接実行可能にすることができます。
詳しくは後で解説します。
[ andrew@pc01 ~ ]$ echo "ls && touch file2 && ls" > ex2.sh
[ andrew@pc01 ~ ]$ chmod +x ex2.sh
実行権限+x
のついたシェルスクリプトは、頭に./
を付けることで直接実行できます。
[ andrew@pc01 ~ ]$ ./ex2.sh
Desktop Git TEST c ex.sh ex2.sh file project test
Desktop Git TEST c ex.sh ex2.sh file file2 project test
長いスクリプトを書きたい場合、行の最後に\
を入れることで改行して入力できます。
[ andrew@pc01 ~ ]$ echo "for i in {1..3}; do echo \
> \"Welcome \$i times\"; done" > ex3.sh
シェルスクリプトにはもちろん、ループや関数などの複雑な構造も仕込むことができます。
[ andrew@pc01 ~ ]$ source ex3.sh
Welcome 1 times
Welcome 2 times
Welcome 3 times
Custom Prompt and ls
bashスクリプティングは、あなたの人生をずっと楽に、豊かに、カラフルにしてくれます。
この素晴らしいチートシートをご覧ください。
ところでシェルのプロンプトに出てくる文字列も環境変数で定義されていて、その名前は$PS1
です。
他にもプロンプトはあって、それらについてはこちらを見てください。
[ andrew@pc01 ~ ]$ printf "%q" $PS1
$'\\n\\[\E[1m\\]\\[\E[30m\\]\\A'$'\\[\E[37m\\]|\\[\E[36m\\]\\u\\[\E[37m\\]@\\[\E[34m\\]\\h'$'\\[\E[32m\\]\\W\\[\E[37m\\]|'$'\\[\E(B\E[m\\]‘
デフォルトのプロンプトは、export
コマンドで変更可能です。
[ andrew@pc01 ~ ]$ export PS1="\ncommand here> "
command here> echo $PS1
\ncommand here>
色を付けることもできます。
command here> export PS1="\e[1;31m\nCODE: \e[39m"
# (ここ本当は赤いんだけどMarkdownで色の付け方がわからんかった)
CODE: echo $PS1
\e[1;31m\nCODE: \e[39m
ls
が出力する色も環境変数$LS_COLORS
で変更することができます。
CODE: ls
Desktop Git TEST c ex.sh ex2.sh ex3.sh file file2 project test
CODE: export LS_COLORS='di=31:fi=0:ln=96:or=31:mi=31:ex=92'
# (ここも本当は赤い)
CODE: ls
Desktop Git TEST c ex.sh ex2.sh ex3.sh file file2 project test
Config Files
Config Files / .bashrc
色々とコマンドを実行して設定を変更しましたが、いちどログアウトして再度ログインすると、全ての変更がリセットされてしまうことに気付くでしょう。
設定ファイルを使用することで、ログインしなおしてもシェルや特定のプログラムの設定を保持することができます。
bashシェルの主な設定ファイルは~/.bashrc
です。
~/.bashrc
に追加したエイリアス、環境変数、エイリアスは、ログインするたびに使用可能になります。
~/.bashrc
に書かれたコマンドはログイン時に実行されるということです。
~/.bashrc
を更新した場合、source
コマンドでログアウトせずに最新状態にすることができます。
[ andrew@pc01 ~ ]$ nano ~/.bashrc
そして最初にecho "~/.bashrc loaded!"
という行を付け加えてみましょう。
[ andrew@pc01 ~ ]$ source ~/.bashrc
~/.bashrc loaded!
ログアウトしてログインし直してもこうなります。
Last login: Fri Jan 11 10:29:07 2019 from 111.11.11.111
~/.bashrc loaded!
[ andrew@pc01 ~ ]
Types of Shells
ログインシェルとは、ログインしたとき最初に起動するシェルです。
対話型シェルとは、コマンドを入力することができるシェルです。
シェルには対話型ログインシェル、非ログイン非対話型シェル、あるいは他の組み合わせなど様々なものがあります。
~/.bashrc
以外にも、ログインしたときやログアウトした際に自動的に実行されるスクリプトは幾つか存在します。
例を挙げると、
・/etc/profile
・~/.bash_profile
・~/.bash_login
・~/.profile
・~/.bash_logout
・/etc/bash.bash_logout
これらのスクリプトのどれが有効で、どの順番で実行されるかは、シェルのタイプによって異なります。
詳細についてはbashのmanページや、Stack Overflowのポストなどを参照してください。
bashはsource
コマンドで別のスクリプトを読み込むことも可能です。
たとえば~/.bashrc
に以下を記載することができます。
source ~/.bashrc_addl
これにより、.bashrc_addl
もsource
対象のファイルとなります。
このファイルにも独自のエイリアス、関数、環境変数などを記述することができます。
同様に、さらに別のスクリプトをsource
することもできます。
そうする場合はsource
が無限ループしないように注意してください。
機能やOS(Ubuntu、RedHat、macOS)などによってコマンドをファイルごとに分離しておくと役立つことがあります。
・~/.bash_ubuntu
…Ubuntu固有の設定
・~/.bashrc_styles
…PS1
やLS_COLORS
など外観の設定
・~/.bash_java
…言語ごとのの設定
外観やOS固有設定などをそれぞれ個別のファイルに切り出し、そしてそれらのうち必要なものをsource
するひとつの管理ファイルから構成します。
このような構成であれば、あらゆるマシンやOSで使用可能なシェルになります。
bash以外のシェルも存在することに気をつけてください。
bashは単にシェルの一種であるにすぎません。
他に一般的なシェルとしてはzsh
、csh
、fish
などが存在します。
様々なシェルを試して、自分に合ったものを見つけてください。
ただし、このチュートリアルはbashシェルで記述されているため、他のシェルでは動作しない可能性があることに注意してください。
Finding Things
whereis / which / whatis
whereis
は、あるコマンドに対して、おそらく有用であろうファイルを検索します。
そのコマンドのバイナリすなわち実行可能なコード、ソースファイル、マニュアルのmanページなどです。
[ andrew@pc01 ~ ]$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz
which
はバイナリ、すなわちコマンドの場所のみを返します。
[ andrew@pc01 ~ ]$ which ls
/bin/ls
whatis
はmanページからコマンドの概要を1行表示します。
[ andrew@pc01 ~ ]$ whatis whereis which whatis
whereis (1) - locate the binary, source, and manual page files for a command
which (1) - locate a command
whatis (1) - display one-line manual page descriptions
which
は、エイリアスで隠蔽されているコマンドのオリジナルを探すのに役立ちます。
[ andrew@pc01 ~ ]$ alias ls="ls -l"
# エイリアスのせいで元コマンドと挙動が違う
[ andrew@pc01 ~ ]$ ls
total 36
drwxr-xr-x 2 andrew andrew 4096 Jan 9 14:47 Desktop
drwxr-xr-x 4 andrew andrew 4096 Dec 6 10:43 Git
...
# whichで調べた元コマンドを直接叩けばオリジナルの結果が得られる
[ andrew@pc01 ~ ]$ /bin/ls
Desktop Git TEST c ex.sh ex2.sh ex3.sh file file2 project test
locate / find
locate
は、予め作成しておいたキャッシュリストを参照して高速にファイルを検索します。
[ andrew@pc01 ~ ]$ locate README.md
/home/andrew/.config/micro/plugins/gotham-colors/README.md
/home/andrew/.jenv/README.md
/home/andrew/.myshell/README.md
...
リストを検索するのでfind
より高速ですが、必ずしも最新の状態と一致しているとは限りません。
find
は実際のファイルシステムを検索して、探しているファイルを見つけます。
こちらは実ファイルを検索するため、常に最新のファイルを得ることができます。
[ andrew@pc01 ~ ]$ find ~/ -iname "README.md"
/home/andrew/.jenv/README.md
/home/andrew/.config/micro/plugins/gotham-colors/README.md
/home/andrew/.oh-my-zsh/plugins/ant/README.md
...
find
は1971年という最初期のUNIXから実装されているため、1994年にGNUに追加されたlocate
より遙かに広い環境で利用可能です。
find
はlocate
よりずっと多くの機能を備えていて、更新日、サイズ、所有者、ファイル/ディレクトリ、タイムスタンプ、パーミッション、ディレクトリの深さなど多様な条件で検索できます。
またファイル名を正規表現で検索し、見つかったファイルに対してコマンドを実行することもできます。
高速に検索する必要がある場合、また対象ファイルが何処にあるかわからないときはlocate
を使用します。
ファイル名以外の何らかの条件に紐付いた正確なファイル一覧が欲しい場合、取得したファイルに対して何かを行いたいときはfind
を使用します。
Downloading Things
ping / wget / curl
ping
はネットワークホストとの通信を確立しようとします。
主にインターネット接続がダウンしているかどうかを確認するために使用されます。
[ andrew@pc01 ~ ]$ ping google.com
PING google.com (74.125.193.100) 56(84) bytes of data.
Pinging 74.125.193.100 with 32 bytes of data:
Reply from 74.125.193.100: bytes=32 time<1ms TTL=64
...
wget
はインターネットからファイルを簡単にダウンロードできます。
[ andrew@pc01 ~ ]$ wget \
> http://releases.ubuntu.com/18.10/ubuntu-18.10-desktop-amd64.iso
curl
もwget
と同じように使用できます。
--output
オプションを忘れないようにしてください。
[ andrew@pc01 ~ ]$ curl \
> http://releases.ubuntu.com/18.10/ubuntu-18.10-desktop-amd64.iso \
> --output ubuntu.iso
curl
とwget
には、それぞれ長所と短所があります。
curl
はより多くのプロトコルをサポートし、様々な場面で使用可能です。
curl
はデータの送信もできますが、wget
は受信しかできません。
wget
はファイルを再帰的にダウンロードできますが、curl
はできません。
一般的には、インターネットからファイルをダウンロードするときはwget
を使います。
curl
を使ってデータを送信することはあまりありませんが、これを知っておくと、いざ必要になったときに役立ちます。
apt / gunzip / tar / gzip
Debian系のLinuxディストリビューションには、apt
という素晴らしいパッケージ管理ツールが存在します。
ソフトウェアのインストール、アップデート、削除が可能です。
何らかのソフトウェアが必要になった場合、apt search
で検索し、apt install
でインストールします。
[ andrew@pc01 ~ ]$ apt search bleachbit
...bleachbit/bionic,bionic 2.0-2 all
delete unnecessary files from the system
# インストールにはsudoが必要
[ andrew@pc01 ~ ]$ sudo apt install bleachbit
Linuxのソフトウェアは大抵tarball(.tar.gz)になっています。
[ andrew@pc01 ~ ]$ wget \
> https://github.com/atom/atom/releases/download/v1.35.0-beta0/atom-amd64.tar.gz
この拡張子のファイルはgunzip
で解凍できます。
[ andrew@pc01 ~ ]$ gunzip atom-amd64.tar.gz && ls
atom-amd64.tar
.tar.gz
ファイルをgunzip
すると.tar
ファイルになり、さらにtar -xf
で通常のファイルシステムに戻すことができます。
[ andrew@pc01 ~ ]$ tar -xf atom-amd64.tar && mv \
atom-beta-1.35.0-beta0-amd64 atom && ls
atom atom-amd64.tar
逆に圧縮するには、-c
でディレクトリから.tar
にまとめ、-z
で圧縮します。
[ andrew@pc01 ~ ]$ tar -zcf compressed.tar.gz atom && ls
atom atom-amd64.tar compressed.tar.gz
gzip
でもファイルを圧縮することができます。
[ andrew@pc01 ~ ]$ gzip atom-amd64.tar && ls
atom atom-amd64.tar.gz compressed.tar.gz
Redirecting Input and Output
| / > / < / echo / printf
デフォルトでは、シェルコマンドは標準入力ストリーム(stdin、0)から入力を読み取り、標準出力ストリーム(stdout、1)に出力を書き込みます。
エラーが発生すると、それは標準エラーストリーム(stderr、2)に出力されます。
echo
はデフォルトではstdoutに対してテキストを書き込みます。
ほとんどの環境では、それは単にターミナルに表示される、という意味です。
[ andrew@pc01 ~ ]$ echo "hello"
hello
パイプオペレータ|
は、前のコマンドの出力を、後ろのコマンドの入力にリダイレクトします。
# wcはファイルの行数、単語数、バイト数を返すコマンド
[ andrew@pc01 ~ ]$ echo "example document" | wc
1 2 17
>
によるリダイレクトは出力先をstdoutから別のものに変更します。
[ andrew@pc01 ~ ]$ echo "test" > file && head file
test
printf
はecho
の改良版で、フォーマットやエスケープシーケンスが書けます。
[ andrew@pc01 ~ ]$ printf "1\n3\n2"
1
3
2
<
はstdinではなく、別のところから入力を取得します。
# sortは入力を行単位でソートするコマンド
[ andrew@pc01 ~ ]$ sort <(printf "1\n3\n2")
1
2
3
ファイルの中身をコマンドに送る推奨された方法は、UUOCではなく<
を使うことです。
これを使った場合、データは自然に感じる左から右ではなく、右から左に流れることになるので注意してください。
[ andrew@pc01 ~ ]$ printf "1\n3\n2" > file && sort < file
1
2
3
0 / 1 / 2 / tee
0
、1
、2
は、上記のようにそれぞれ標準入力、標準出力、標準エラーストリームを表します。
各ストリームは前述のように|
、<
、>
各演算子を使ってリダイレクトできますが、それとは別に直接数値で書くこともできます。
その場合、標準出力は>&1
、標準エラーは>&2
となります。
[ andrew@pc01 ~ ]$ cat test
echo "stdout" >&1
echo "stderr" >&2
デフォルトでは標準出力も標準エラーもターミナルに出力されます。
[ andrew@pc01 ~ ]$ ./test
stderr
stdout
標準入力を/dev/null
に送ると、標準エラーだけがターミナルに表示されます。
[ andrew@pc01 ~ ]$ ./test 1>/dev/null
stderr
標準エラーを/dev/null
に送ると、標準出力だけがターミナルに表示されます。
[ andrew@pc01 ~ ]$ ./test 2>/dev/null
stdout
全てを/dev/null
に送る場合はこうです。
[ andrew@pc01 ~ ]$ ./test &>/dev/null
標準出力の出力先を変更するのではなく、複数の出力先に送りたい場合は、tee
コマンドを使います。
[ andrew@pc01 ~ ]$ ls && echo "test" | tee file1 file2 file3 && ls
file0
test
file0 file1 file2 file3
Advanced
Superuser
sudo / su
自分の名前を知りたいときはwhoami
です。
[ andrew@pc01 abc ]$ whoami
andrew
コマンドを別のユーザとして実行したい場合は、sudo -u username
というコマンドで実行できます。
ただしそのユーザのパスワードが必要です。
[ andrew@pc01 abc ]$ sudo -u test touch def && ls -l
total 0
-rw-r--r-- 1 test test 0 Jan 11 20:05 def
-u
を省いた場合のデフォルトはスーパーユーザ、通常はroot
であり、このユーザはあらゆる操作が無制限に可能です。
[ andrew@pc01 abc ]$ sudo touch ghi && ls -l
total 0
-rw-r--r-- 1 test test 0 Jan 11 20:05 def
-rw-r--r-- 1 root root 0 Jan 11 20:14 ghi
su
で一時的に別のユーザになれます。
戻るときはexit
です。
[ andrew@pc01 abc ]$ su test
Password:
test@pc01:/home/andrew/abc$ whoami
test
test@pc01:/home/andrew/abc$ exit
exit
[ andrew@pc01 abc ]$ whoami
andrew
sudo
とsu
の違いについてもっと知りたい人は、こちらの記事を読みましょう。
!!
スーパーユーザはソフトウェアのインストール、ユーザの作成などを行うことができる唯一のユーザです。
時々それを忘れてエラーを起こすことがあるでしょう。
[ andrew@pc01 ~ ]$ apt install ruby
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
頭にsudo
をつけてコマンドを再入力するとうまくいきます。
[ andrew@pc01 ~ ]$ sudo apt install ruby
Reading package lists...
!!
で同じことができます。
これは前回入力したコマンドを保持しているショートカットです。
[ andrew@pc01 ~ ]$ apt install ruby
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
[ andrew@pc01 ~ ]$ sudo !!
sudo apt install ruby
Reading package lists...
デフォルトでは、いちどsudo
でコマンド実行に成功すると、その後15分間はパスワード入力なしにsudo
コマンドを実行可能です。
15分を超えると、ふたたびパスワードを要求されるようになります。
File Permissions
File Permissions
ファイルに対して読み込み(r)、書き込み(w)、実行(x)の操作をそれぞれ可能だったりできなかったりします。
ファイルへのアクセス権はls -l
コマンドで確認することができ、10文字で表されます。
[ andrew@pc01 ~ ]$ ls -lh
total 8
drwxr-xr-x 4 andrew andrew 4.0K Jan 4 19:37 tast
-rwxr-xr-x 1 andrew andrew 40 Jan 11 16:16 test
-rw-r--r-- 1 andrew andrew 0 Jan 11 16:34 tist
各行の最初の文字は、ファイルの種類を表します。
d=ディレクトリ、l=シンボリックリンク、-=通常ファイルなど。
次の3文字はファイルの所有者(u)が持つパーミッション、次の3文字がファイル所有グループ(g)が持つパーミッション、最後の3文字が無関係なユーザ(o)の持つパーミッションです。
r
はそのファイルを読み取り可能、w
は書き込み可能、x
は実行可能であるというパーミッションを表します。
ディレクトリが実行可能であるとは、そのディレクトリの内容を一覧表示できるという意味です。
この3権限のセットを1桁の数値で表すことがよくあります。
x
が有効なら1、w
が有効なら2、r
が有効なら4というふうに2進数として計算します。
例としてr-x
であればr
とx
が有効なので5です。
従って、上記例の3ファイルは順に755、755、644のパーミッションを持つというふうに表されます。
パーミッションの次にある数値は、そのファイルを参照しているリンクの数です。
その次の2つの文字は、それぞれ所有者名と、所有者のグループ名を表します。
今回は所有者もグループも全てandrewです。
さらにその次がファイルのサイズ、更新日時、そして最後にファイル名が表示されます。
ls
の-h
オプションは人間が読み取りやすいように出力を調整します。
すなわち4096
などではなく4.0K
と表示します。
chmod / chown
chmod
で数値を与えることにより、ファイルのパーミッションを変更できます。
[ andrew@pc01 ~ ]$ chmod 777 test && chmod 000 tist && ls -lh
total 8.0K
drwxr-xr-x 4 andrew andrew 4.0K Jan 4 19:37 tast
-rwxrwxrwx 1 andrew andrew 40 Jan 11 16:16 test
---------- 1 andrew andrew 0 Jan 11 16:34 tist
あるいはプラスマイナスとrwx
で直感的操作もできます。
[ andrew@pc01 ~ ]$ chmod +rwx tist && chmod -w test && ls -lh
chmod: test: new permissions are r-xrwxrwx, not r-xr-xr-x
total 8.0K
drwxr-xr-x 4 andrew andrew 4.0K Jan 4 19:37 tast
-r-xrwxrwx 1 andrew andrew 40 Jan 11 16:16 test
-rwxr-xr-x 1 andrew andrew 0 Jan 11 16:34 tist
ファイルの所有者はchown
で変更できます。
[ andrew@pc01 ~ ]$ sudo chown marina test
グループの変更はchgrp
です。
[ andrew@pc01 ~ ]$ sudo chgrp hadoop tist && ls -lh
total 8.0K
drwxr-xr-x 4 andrew andrew 4.0K Jan 4 19:37 tast
-----w--w- 1 marina andrew 40 Jan 11 16:16 test
-rwxr-xr-x 1 andrew hadoop 0 Jan 11 16:34 tist
User and Group Management
Users
現在ログインしてる全ユーザの一覧がusers
で表示できます。
複数のSSHセッションを張ったりなどで同一ユーザが同時に何度もログインすることができます。
[ andrew@pc01 ~ ]$ users
andrew colin colin colin colin colin krishna krishna
ログインしていないユーザも含め全ユーザを確認するには、/etc/passwd
を参照します。
なお、このファイルを変更するとユーザアカウントが破損し、ログインできなくなる可能性があるため、絶対に直接編集しないでください。
[ andrew@pc01 ~ ]$ alias au="cut -d: -f1 /etc/passwd \
> | sort | uniq" && au
_apt
anaid
andrew...
ユーザの追加はuseradd
です。
[ andrew@pc01 ~ ]$ sudo useradd aardvark && au
_apt
aardvark
anaid...
ユーザの削除はuserdel
です。
[ andrew@pc01 ~ ]$ sudo userdel aardvark && au
_apt
anaid
andrew...
ユーザアカウント操作の詳細についてはこちらを参照してください。
Groups
groups
は、ユーザが属している全てのグループを表示します。
[ andrew@pc01 ~ ]$ groups
andrew adm cdrom sudo dip plugdev lpadmin sambashare hadoop
システム上の全てのグループを確認するには、/etc/group
を参照します。
このファイルを理解していないかぎり、直接変更はしないでください。
[ andrew@pc01 ~ ]$ alias ag=“cut -d: -f1 /etc/group \
> | sort” && ag
adm
anaid
andrew...
グループの追加はgroupadd
です。
[ andrew@pc01 ~ ]$ sudo groupadd aardvark && ag
aardvark
adm
anaid...
グループの削除はgroupdel
です。
[ andrew@pc01 ~ ]$ sudo groupdel aardvark && ag
adm
anaid
andrew...
グループ操作の詳細についてはこちらを参照してください。
Text Processing
uniq / sort / diff / cmp
uniq
コマンドは、連続した重複行を削除して表示します。
[ andrew@pc01 man ]$ printf "1\n2\n2" > a && \> printf "1\n3\n2" > b
[ andrew@pc01 man ]$ uniq a
1
2
sort
は行をアルファベット順、もしくは数値順に並び替えます。
[ andrew@pc01 man ]$ sort b
1
2
3
diff
は、2つのファイルでどの行が異なるかを表示します。
[ andrew@pc01 man ]$ diff a b
2c2
< 2
---
> 3
cmp
は、2つのファイルで最初に異なる場所のバイト数を表示します。
[ andrew@pc01 man ]$ cmp a b
a b differ: char 3, line 2
cut / sed
cut
は、文字列をなんらかの区切り文字で分割するコマンドで、CSV処理などに向いています。
-d
で区切り文字を指定し、-f
は出力するインデックス(1始まり)を指定します。
[ andrew@pc01 man ]$ printf "137.99.234.23" > c
[ andrew@pc01 man ]$ cut -d'.' c -f1
137
sed
は、ファイル内の文字列を別の文字列に置換するためによく使われます。
[ andrew@pc01 man ]$ echo "old" | sed s/old/new/
new
実のところsed
は非常に強力なユーティリティであり、この狭いスペースでは到底解説することができません。
sed
はチューリング完全であり、他のプログラミング言語でできることなら何でもできます。
sed
は、正規表現に基づいてテキストを検索・置換し、特定パターンに一致する、あるいは含む行を抽出したり、テキストファイルを非対話式にIn-place編集したり、その他様々なことが行えます。
詳しくは以下のようなチュートリアルを参照してください。
・https://www.tutorialspoint.com/sed/
・http://www.grymoire.com/Unix/Sed.html
・https://www.computerhope.com/unix/used.htm
Pattern Matching
grep
grep
の名前はsearch Globally for a Regular Expression and Print it
に由来します。
ファイルから、特定のパターンに一致するテキストを見つけるために使用されます。
[ andrew@pc01 ~ ]$ grep -e ".*fi.*" /etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# The file bash.bashrc already sets the default PS1.
fi
fi
...
普通に単語検索もできます。
[ andrew@pc01 ~ ]$ grep "andrew" /etc/passwd
andrew:x:1000:1000:andrew,,,:/home/andrew:/bin/bash
ファイル内の一致する行を見つけた後、他のプログラムでその行を処理させたい場合などに、grep
は最適な選択です。
grep
では、正規表現-E
、複数文字列のいずれかとマッチさせる-F
、ディレクトリ内のファイルを再帰的に検索する-r
などのオプションが存在します。
これらのオプションは元々個別コマンドegrep
、fgrep
、rgrep
として実装されていましたが、個別コマンドは非推奨になりました。
おまけ
いろいろなコマンド名の由来を見てみよう。
awk
awk
は、CSVなどのデリミタで区切られたデータファイルを読み取り、操作することを念頭に作られた言語です。
経験的に、grep
はファイルから特定の文字列やパターンを見つけるのに適していて、sed
はファイル内の文字列を1対1で置換するのに適しています。
そしてawk
は、ファイルからパターンを抽出して分析するのに適しています。
awk
ができることの例として、2列のデータを含むファイルを処理してみます。
[ andrew@pc01 ~ ]$ printf "A 10\nB 20\nC 60" > file
行ごとにループし、数値を合計し、平均を出力するコードは以下のようになります。
[ andrew@pc01 ~ ]$ awk 'BEGIN {sum=0; count=0; OFS=" "} {sum+=$2; count++} END {print "Average:", sum/count}' file
Average: 30
sed
とawk
はどちらもチューリング完全な言語です。
これらはパターンマッチングとテキスト処理に非常に役立つ言語で、そしてそれぞれについて書かれた本もたくさんあります。
それらについて書き記すにはここには余白が足りません。
もっと調べてみてください。
Copying Files Over ssh
ssh / scp
ssh
は、Unixベースのマシン同士がネットワークを介して接続する方法です。
[ andrew@pc01 ~ ]$ ssh –p <port> andrew@137.xxx.xxx.89
Last login: Fri Jan 11 12:30:52 2019 from 137.xxx.xxx.199
別のマシンに入ったのでプロンプトが変わりました。
[ andrew@pc02 ~ ]$ exit
logout
Connection to 137.xxx.xxx.89 closed.
マシン1でファイルを作成します。
[ andrew@pc01 ~ ]$ echo "hello" > hello
これをマシン2にコピーするにはscp
コマンドを使用します。
ssh
はポート番号を-p
で指定するのに対し、scp
は-P
で指定するのに注意しましょう。
[ andrew@pc01 ~ ]$ scp –P <port> hello andrew@137.xxx.xxx.89:~
hello 100% 0 0.0KB/s 00:00
確認のため、ssh
でマシン2に入りましょう。
[ andrew@pc02 ~ ]$ ssh –p <port> andrew@137.xxx.xxx.89
Last login: Fri Jan 11 22:47:37 2019 from 137.xxx.xxx.79
そこにファイルが存在しているはずです。
[ andrew@pc02 ~ ]$ ls
hello multi xargs
[ andrew@pc02 ~ ]$ cat hello
hello
rsync
rsync
は、ファイル間の差分を調べることにより、コピーされるデータ量を少なく抑えるファイルコピーツールです。
2つのディレクトリd
とs
が存在し、d
にはファイルがひとつ、s
にはふたつ存在するとします。
[ andrew@pc01 d ]$ ls && ls ../s
f0
f0 f1
ディレクトリをrsync
で同期すると、不足しているファイルだけがコピーされます。
[ andrew@pc01 d ]$ rsync -av ../s/* .
sending incremental file list...
最終的にd
ディレクトリには、s
ディレクトリに存在する全てのファイルが集まります。
[ andrew@pc01 d ]$ ls
f0 f1
rsync
はssh
経由でも実行できます。
[ andrew@pc02 r ]$ ls
[ andrew@pc02 r ]$ rsync -avz -e "ssh -p <port>" andrew@137.xxx.xxx.79:~/s/* .
receiving incremental file list
f0
f1
sent 62 bytes received 150 bytes 141.33 bytes/sec
total size is 0 speedup is 0.00
Long-Running Processes
yes / nohup / ps / kill
ネットワークやハードウェアの問題によって、SSH接続が切断されることがよくあります。
その際、そのSSH接続から起動されていたプロセスには全てHUPシグナルが送られ、プロセスは強制終了されます。
yes
コマンドは、停止されるまで"y"を出力し続けます。
これをnohup
と一緒に実行しましょう。
[ andrew@pc01 ~ ]$ nohup yes &
[1] 13173
ps
は、現在のユーザが実行しているプロセスを一覧表示します。
以下の例では、yes
コマンドのPIDは13713です。
[ andrew@pc01 ~ ]$ ps | sed -n '/yes/p'
13173 pts/10 00:00:12 yes
ログアウトして再度ログインしてみましょう。
[ andrew@pc01 ~ ]$ ps | sed -n '/yes/p'
表示されなくなりました。
が、実際は裏で実行され続けていてtop
やhtop
には出てきます。
[ andrew@pc01 ~ ]$ top -bn 1 | sed -n '/yes/p'
13173 andrew 20 0 4372 704 636 D 25.0 0.0 0:35.99 yes
kill
コマンドに-9
オプションを付けて、このプロセスを強制終了しましょう。
[ andrew@pc01 ~ ]$ kill -9 13173
これでプロセスが終了したため、もうtop
にも出てきません。
[ andrew@pc01 ~ ]$ top -bn 1 | sed -n '/yes/p'
cron / crontab / >>
cronはタスクを定期的に実行する簡単な方法を提供します。
crontab –e
コマンドでテキストエディタが開き、cronを編集することができます。
以下の行を追加しましょう。
* * * * * date >> ~/datefile.txt
毎分date
コマンドを実行し、出力をファイルに保存します。
[ andrew@pc02 ~ ]$ head ~/datefile.txt
Sat Jan 12 14:37:01 GMT 2019
Sat Jan 12 14:38:01 GMT 2019
Sat Jan 12 14:39:01 GMT 2019...
再びcrontab
を編集し、該当行を削除すると、このジョブは停止します。
ジョブの頭にある* * * * *
は順に分(0-59)、時間(0-23)、日(1-31)、月(1-12)、曜日(0-6もしくはSun-Sat)を表します。
各*
を数値に置き換えることで、特定の日や特定の時間にのみジョブを実行することができるようになります。
曜日に関係なくジョブを実行したい場合は、5番目の*
を*
のままにしておきます。
全ての項目を*
にすると毎分実行されるようになり、これが利用可能な最小間隔になります。
システムが再起動されたときだけ実行するように設定することもでき、これは* * * * *
のかわりに@reboot
と記載します。
また、1時間あるいは一日のうち特定の回数だけ実行するようにしたり、月や曜日や日など複数項目の組み合わせで指定することも可能です。
もっと詳しく知るにはこちらを参照してください。
Miscellaneous
pushd / popd
ディレクトリの移動をスタックするには、cd
ではなくpushd
とpopd
を使います。
以下の例ではホームディレクトリから開始します。
[ andrew@pc01 ~ ]$ pwd
/home/andrew
フルパスのpushd
でディレクトリを移動します。
[ andrew@pc01 ~ ]$ pushd /etc/java/security/security.d/
/etc/java/security/security.d ~
pushd
でサブディレクトリに移動します。
[ andrew@pc01 security.d ]$ pushd ~/test/
~/test /etc/java/security/security.d ~
pushd
によって積まれたスタックは、表示の一番左側に追加されます。
popd
すると一番最後に追加されたディレクトリに戻ります。
[ andrew@pc01 test ]$ popd
/etc/java/security/security.d ~
[ andrew@pc01 security.d ]$ pwd
/etc/java/security/security.d
何度もpopd
すると、最終的にpushd
を始めたディレクトリに戻ります。
[ andrew@pc01 security.d ]$ popd
~
xdg-open
xdg-open
は、ファイルをデフォルトのアプリケーションで開くコマンドです。
HTMLファイルをブラウザで開きたい場合などに便利です。
MacOSで言うopen
コマンドに相当します。
[ andrew@pc01 security.d ]$ xdg-open index.html
xargs
xargs
引数のリストに対して、ループ的にコマンドを実行します。
以下はカレントディレクトリ、親ディレクトリ、親の親ディレクトリに対してls
を実行する例です。
[ andrew@pc01 ~ ]$ export lv=".\n..\n../.."
[ andrew@pc01 ~ ]$ printf $lv | xargs ls
.:
multi file
..:
anaid andrew colin...
../..:
bin dev index...
引数は、–I
オプションを使うことで次のコマンドの引数に割り当てることができます。
以下はカレントディレクトリ、親ディレクトリ、親の親ディレクトリに対してcd
とpwd
を実行する例です。
[ andrew@pc01 ~ ]$ printf $lv | xargs -I % sh -c 'cd %; pwd %'
/home/andrew
/home
/
もっと詳しく知るには、この素晴らしいチュートリアルをご覧ください。
Bonus: Fun-But-Mostly-Useless Things
楽しいけど役に立たないもの。
w / write / wall / lynx
w
は誰がログインしていてさらに何をしているかを表示する、who
の詳細版です。
[ andrew@pc01 ~ ]$ w
17:32:42 up 434 days, 3:11, 8 users, load average: 2.32, 2.46, 2.57
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
colin pts/9 137.xx.xx.210 03Jan19 5:28m 1:12 0.00s sshd: colin [priv]
andrew pts/10 137.xx.xx.199 11:05 1.00s 0.15s 0.04s sshd: andrew [priv]
colin pts/12 137.xx.xx.210 03Jan19 34:32 1.59s 1.59s –bash
...
別のユーザに対してwrite
でメッセージを送信することができます。
[ andrew@pc01 ~ ]$ echo "hello" | write andrew pts/10
Message from andrew@pc01 on pts/10 at 17:34 ...
hello
EOF
wall
はwrite
と似ていますが、ログイン中の全ユーザに同じメッセージを送信します。
メールやTwitterやWhatsAppといったアプリが普及する前は、メッセージを送るためにwrite
やwall
がよく使われていました。
lynx
はテキストベースの、完全に機能するWebブラウザです。
nautilus / date / cal / bc
nautilus
は新しいセッションを開き、GUIのファイルマネージャをオープンします。
date
は現在の日付と時刻を表示します。
[ andrew@pc01 ~ ]$ date
Fri Jan 11 17:40:30 GMT 2019
cal
は今月のカレンダーをテキストで表示します。
本日の日付は強調表示されます。
[ andrew@pc01 ~ ]$ cal
January 2019
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
bc
は簡易的な電卓です。
かわりにPythonを使いましょう。
[ andrew@pc01 ~ ]$ bc
bc 1.06.95 ...
20/4
5
これでおしまいです!
このリストに追加する必要のある機能や、クールなコマンドを知っていたら教えてください。
またタイプミスや間違いがあったときも教えてください。
ベストを尽くしたつもりですが、きっとたくさんあると思います。
この投稿が参考になったのであれば、ぜひコーヒーを買ってください。
Update 8 July 2019
2年前に書かれた、とてもよく似た記事を発見しました。
フランス語がわかるのであれば、私の記事の補完に最適だと思います。
コメント欄
「素晴らしいポスト!Andrewサンクス!」
「同じ投稿をPowerShellでやってくれたら思い残すことはない。」
「screen
。新しいSSH接続を開く。そのセッションはログオフしてもプログラムはずっと実行されたままで、さらに再接続して続きもできる。」「tmux
はいいぞ。screen
と似てるけどもっと便利。」
「disown
。既に動かした後のプログラムを、後からバックグラウンドに持っていける。」
「ipython
とtrash-cli
を是非。」
「date +%s
でUNIXタイムを表示できるよ。」
「ncdu
初めて知った。これ便利!」
「MacとFreeBSDではtop
のユーザ名オプションは-U
だったよ。」
「kill -9
はいかん、kill -15
か単にkill
ってするんだ。-15
はOSに通知が行く、-9
はいきなり電源押して切るようなものだ。」
「source
とsh
は同じ結果になることもあるけど全く同じではない。source
は現在のbash
上で実行されてexport
した変数も使える。sh
は新たなシェルを起動するしexport
した変数は使えない。」
「bash
コマンドって言うけど実際はbashコマンドではなくてUnix/Posixコマンドが多いぞ。」
「xdg-open
の画像がWindowsっぽいんだけどどゆこと?」「MobaXTermを使ってWindowsからUbuntuにログインしてるからなのだ。」
「コマンドプロンプトに|
を使っててパイプとわかりにくいのでプロンプトは$
にしてほしい。」「ありがとう更新したよ!」
「聖なる牛!」
感想
チュートリアル形式でわかりやすい、bashコマンド入門記事です。
最後まで読めばbashスクリプトをバリバリ組めるようなエキスパートになれるかというと怪しいですが、汎用的なbashコマンドについてはひととおり使えるようになっていることでしょう。
LPICのLevel3まで持ってたらよゆーよゆーとか思ってたけど、わりと知らないコマンドも多かった。
知っていると知らないとでは大違いなので、コマンドや機能が存在していることそのものを認識しておくと、今後役に立つことでしょう。
いきなり詳しく知る必要はありません。
詳細は必要になったときにman
なりググるなりすればいいんですよ。
あと原文は、こうすればこうなりますよというのは書かれているんだけど、"何故"そうなるかが書かれていないところがあってちょっと躓く感じがありました。
和訳にあたりそのあたりを一部補完しています。
トップコメのHoly cow!はどう捉えたらいいのかよくわからなかった。