はじめに
最近周りでLinuxのBashを触る人が増え、意外と知られていないコマンドの使い方や、おしい所で詰まっているコマンドの記述を目にするようになってきたので、その中でもコマンド共通して参考になりそうなモノをピックアップして紹介します。
また、それぞれの詳細な説明は記事が沢山出ているので、ここでは紹介する程度に留めておきます。
LinuxでBashを触り始めて、なんとなくコマンドやパイプが使えるようになってきた人に、一歩踏み込んだ使い方として参考になれば幸いです。
なお、[Linuxで先頭行や末尾行へ文字列を追加・削除・抽出するいろんな方法]にsed
コマンドやawk
コマンド、cat
コマンドなどの応用方法を記載したので、興味のある方はそちらを参照してください。
・ショートカットが便利
Tab
での補完や、Ctrl+C
で実行したコマンドを中断する、↑↓
で実行したコマンドの履歴を表示する以外にも、コンソール上で操作をするのに便利なキーボードショートカットが用意されています。
お勧めのショートカットとしては以下3つになりますが、これ以外にも色々なショートカットが用意されており、使いこなせれば操作効率が大きく改善されると思います。
-
Ctrl+R
:過去に実行したコマンドの履歴を検索 -
Ctrl+A
:カーソルの位置を先頭に移動 -
Ctrl+E
:カーソルの位置を行末に移動
・移動する直前のディレクトリに簡単に戻れる
ディレクトリを移動した後に、移動する直前のディレクトに戻りたい時があります。その時はcd
コマンドで移動する直前のパスを指定してディレクトリを移動することもできますが、cd -
を実行すると簡単に直前にいたディレクトに戻ることができます。
$ pwd
/dirs/dir1
$ cd ../dir2
$ pwd
/dirs/dir2
$ cd ../dir1
$ pwd
/dirs/dir1
$
$ pwd
/dirs/dir1
$ cd ../dir2
$ pwd
/dirs/dir2
$ cd -
$ pwd
/dirs/dir1
$
パスが長い場合や、ディレクトリを行き来する場合は非常に便利なのでぜひ活用してください。
・作成したディレクトリに簡単に移動できる
mkdir
コマンドでディレクトリを作成した直後に作成したディレクトリに移動する場合、cd
コマンドで作成したディレクトリのパスを指定して移動することができますが、cd $_
を使用すると簡単に作成したディレクトリに移動することができます。
$ mkdir -p dirs/dir1/dir1-1
$ cd dirs/dir1/dir1-1
$ pwd
$ /dirs/dir1/dir1-1
$
$ mkdir -p dirs/dir1/dir1-1
$ cd $_
$ pwd
$ /dirs/dir1/dir1-1
$
$ mkdir -p dirs/dir1/dir1-1 && cd $_
$ pwd
$ /dirs/dir1/dir1-1
$
$_
は前回実行したコマンドの最後の引数(mkdir dirs/dir1/dir1-1
であればdirs/dir1/dir1-1
)を示します。そのためmkdir
コマンドとcd $_
の間に別なコマンドを挟む場合は作成したディレクトリを示すことが出来ないので注意してください。
$ mkdir -p dirs/dir1/dir1-1
$ echo test
test
$ cd $_
bash: cd: test: No such file or directory
$
また、mkdir
コマンドでスペースを含むディレクトリを作成した場合はスペースで引数が分割されてしまうのでcd "$_"
のように$_
をダブルクォートで囲ってください。
$ mkdir -p "dirs/dir1/dir1 1" && cd "$_"
$ pwd
$ /dirs/dir1/dir1 1
$
※そもそもディレクトリ名やファイル名にスペースや記号を含めることは推奨されないので、可能であれば別な名前を検討してください
こちらもパスが長い場合や、ディレクトリを行き来する場合は非常に便利なのでぜひ活用してください。
・コマンドの説明を表示できる
コマンドはわかるけど使い方を忘れてしまった...といった場合に、コマンドの説明をコンソール上で確認する事ができます。
代表的なのはman
コマンドで、引数にコマンドを指定して実行するとマニュアルを表示する事ができます。
標準ではlessコマンドでマニュアルが表示されるので、/(検索文字列)
で文字列検索、↑↓
で表示移動、q
で表示を終了するなど、lessコマンドでできる操作がそのまま使用できます。
(英語が苦手な方は少し手間ですが、表示を日本語化する事もできます)
$ man grep
また、多くのコマンドでは-h
や–help
オプションをつけてコマンドを実行するとusage(使い方)を表示する事ができます。
$ grep -h
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]
見方を覚えるまでは呪文のようメッセージですが、慣れてくるとコマンドのWebサイト巡りをしなくてもサクっとその場で使い方を確認できるようになります。
・コマンドに直接ファイルを指定できる
grepやawk、sedなどのテキスト処理系のコマンドを実行する際にcat
コマンドでファイルを開いてからパイプ|
で渡して処理する事もできますが、多くのコマンドでは直接ファイルを指定して実行する事ができます。
$ cat file | grep hello
$ grep hello file
また、ファイルを指定する際にワイルドカードが使用できるので複数ディレクトリの中の特定の拡張子のファイルを指定したい場合は、ワイルドカードで階層と拡張子を指定してコマンドを実行する事ができます。
$ tree .
.
├── dir1
│ ├── file.dmp
│ └── file.log
├── dir2
│ ├── file.dmp
│ └── file.log
└── dir3
├── file.dmp
└── file.log
3 directories, 6 files
$
$ grep hello */*.log
dir1/file.log:hello
dir2/file.log:hello
dir3/file.log:hello
$
find
コマンドを使ってファイルを検索してコマンドを実行しても同じ結果が得られますが、同じ階層のファイルを対象とする場合はワイルドカードを使用するとシンプルに記述することができます。
・同じオプションが複数回指定できる
コマンドによっては、条件やスクリプトなどのオプションによる指定が複数回できる場合があります。
同じコマンドをパイプ|
で連結して繰り返し記述している場合や、複数の条件を指定する方法で困っている場合は、一度コマンドのオプションを調べてみると解決策が見つかるかもしれません。
$ cat file
title
hello
world
text
$
$ grep -e hello -e world file
hello
world
$
$ sed -e 's/hello/A/' -e 's/world/B/' file
title
A
B
text
$
・コンソールで変数が使える
プログラムの記述と直接関係無いように見えるコンソール操作ですが、コマンドの引数やオプションなどに変数を使用する事ができます。
また、変数に格納された値は加工をして参照する変数展開
が使用できるので非常に便利です。
$ VAL=hello
$ echo $VAL
hello
$ echo ${VAL/e/a}
hallo
$
$ P=/home/user/tmp/file
$ echo $P
/home/user/tmp/file
$ echo ${P/%file/file.bk}
/home/user/tmp/file.bk
$ cp $P ${P/%file/file.bk}
$ ls /home/user/tmp/
file file.bk
$
また、上記では変数P
の末尾のfile
という文字列をfile.bk
に変数展開で置換しましたが(${P/%XX/YY}
で変数P
の末尾のXX
の文字列をYY
に置換)、ファイルのパスが長い場合は{}
を使用したブレース展開
を使うと、よりコンパクトに書くことができます。
$ cp /home/user/tmp/file{,bk}
$ ls /home/user/tmp/
file file.bk
$
ファイルのバックアップをとる際にはよく使われる方法ですが、簡単にいうとbashは中括弧{}
(ブレース)の中身を展開してくれるので、それを利用して長いパスを2回書かずにファイルのコピーを実現しています。
$ echo {1,2,3}
1 2 3
$ echo {1..3}
1 2 3
$
$ echo file{.txt,.bk}
file.txt file.bk
$
$ echo file{,.bk}
file file.bk
$
ブレース展開
も非常に便利なので変数展開
と一緒に使い方を調べてみる事をお勧めします。
また、ブレース展開
はデフォルト有効になっていると思いますが、もし無効になっている場合はset -B
で有効に切り替えられます。
(set +B
で無効に切り替えられます)
$ echo {1..3}
{1..3}
$ set -B
$ echo {1..3}
1 2 3
$
・コンソールでif、forが使える
変数だけでなく、コンソール上でif
やfor
などの制御文も使う事ができます。
引数やオプションの一部の文字を変えながら繰り返し同じコマンドを実行する、などの場合は、コンソール上で変数や制御文を使ってコマンドを実行すると楽に処理することができます。
$ for i in {1..3} ; do echo $i ; done
1
2
3
$
$ if grep -q hello file ; then echo HIT ; fi
HIT
$ if grep -q hallo file ; then echo HIT ; fi
$
また、制御文と同様に&&
や||
などの論理演算子もコンソール上で使う事ができます。
簡単な条件分岐であればif
をシンプルな記述に置き換えられたり、三項演算子の代わりとして使用することもできます。
$ grep -q hello file && echo HIT
HIT
$ grep -q hallo file && echo HIT
$
$ grep -q hallo file || echo NONE
NONE
$ grep -q hello file || echo NONE
$
・コマンドの実行結果を確認できる
コマンドを実行すると実行結果(終了ステータス)が$?
という特殊変数に格納され、この$?
をecho
コマンドで出力する事で実行結果が確認できます。
また、実行結果はコマンドが成功すると0
、失敗すると0
以外が格納されます。
$ grep hello file
hello
$ echo $?
0
$ grep hallo file
$ echo $?
1
$
ただ、$?
は直前に実行したコマンドの実行結果が格納されるため、パイプ|
で連結した複数のコマンドの実行結果を確認する事はできません。
その場合は${PIPESTATUS[@]}
をecho
コマンドで出力する事で実行結果を確認できます。
$ cat file | grep hello file
hello
$ echo ${PIPESTATUS[@]}
0 0
$
$ cat file | grep hallo file
$ echo ${PIPESTATUS[@]}
0 1
$
パイプ|
でコマンドを連結する数が増えてきた場合は、実行後にecho ${PIPESTATUS[@]}
で実行結果を確認することで、どこのコマンドが想定外の動きをしているか特定がしやすくなります。
おわりに
コンソールやコマンドは注意点も多いのでどこまで書くか悩みましたが、知っていれば自分で調べることが出来るのでそういうモノが存在する事を知ってもらおうと身近で見かけた事からピックアップしてみました。
数も少ないので中途半端な形になりましたが、少しでも幸せになれた人がいれば幸いです。