はじめに
これから何回かにわけて、Windows上でプログラミングをしたりRaspberry piにネットワーク接続して遊ぶために必要な環境の構築や基本技について書いていきます。どの記事も”コマンドライフ”というカテゴリーでくくる予定です。
今日現在頭の中にある記事構想は以下の通りです。実際書き始めてみて気が変わる可能性が大きいので、時々サイトをのぞいてみてくださいまし。
- terminal emulator, gitbashの導入と基本コマンド(👈この記事)
- python環境構築:minicondaの導入とenvの作り方と使い方
- Raspberry piにssh接続:パスワード接続と鍵接続
- gpgライフ:鍵の基本、署名と暗号化
それでは始めましょう。
Jun20, 2024追記
関連記事を追加しました:pythonを始めるための三種の神器とその先
gitbashの導入
Windows OSにはcommand promptやpowershelというものがあらかじめ付属しているのですが、汎用のUnixコマンドが使えなくて困ります。Linuxの普及と、MacOSがUnix-basedのOSに移行して久しい(OSX<-tenってやつです。OS6のときから[Machintosh classic、リンゴはカラフルだった!]のユーザーとしてはOS9からOSXへの移行は革命でした)ことから、コマンドラインツールについて調べるとUnixに基づくものがほとんどのはずです。例えば、ディレクトリ内のファイル一覧を見るにはls
コマンドです。dir
と打ってしまう人は少ないはず。そこで、gitbashを導入します。
gitbashはgitコマンドを使うためのツールで、terminal emulatorとともに主なUnixコマンドが一緒についてきます。そこがみそです。
- https://git-scm.com/downloadsにアクセスします。
- Download for Windowsをクリック。
- 今回はinstallerではなく、portable版のほうをとります。Installerのほうではあれこれoptionに関する質問が多く、判断に迷うものも多いので、展開したらフォルダ一つがでてくるだけで簡単な、portable版のほうでいきましょう。
- これがダウンロードされてきますので、ダブルクリック。
- どこにinstallしますか、と聞かれますが、後で移動できますので、ダウンロードフォルダそのものを指定しました。
- PortableGitという名前のフォルダができてきます。これを好きな場所に移動しましょう。私はこのようにinstallするものはたいていCドライブの直下に作ったlocalという名前のフォルダに入れています。必要がなくなったときにはこのPortableGitフォルダごと捨てます。
git-bashの起動
PortableGitフォルダの中に、git-bash.exeがあります。それをダブルクリックするとterminal emulatorのウインドウが開きます。いわゆる黒いウインドウです。表示が異なると思いますが、これはプロンプトをカスタマイズしてあるためです(環境変数PS1に書式をセットする)。これについては後述します。
pathとcurrent directory
コンピューター上のファイルやフォルダは、階層構造をなして配置されています(ファイルシステム)。例えば、デスクトップにあるフォルダ1の中にフォルダ2とフォルダ3があって、フォルダ3の中にファイル1がある、というように。デスクトップもフォルダの一つで、ユーザーのホームディレクトリの中にあります(C:\Users\USERNAME\Desktop)。フォルダとディレクトリとは同じものとして考えます。
Current directoryとは、コマンドライン上での立ち位置だと思うとわかりやすいかもしれません。コマンドラインでは、GUIでいうところの、フォルダを選んで開く、の代わりにそのdirectoryにフォーカスを移動する、あるいは単に移動する、といいます。たとえば自分のホームディレクトリ(C:\Usersの下にある、自分のユーザー名がついたフォルダのこと)からDesktopへ移動する、など。視点あるいは立ち位置を移動しながら作業をしていきます。この、いま自分の視点があるdirectoryのことをcurrent directoryと呼びます。
Path。ある場所からある場所へ続く道のことです。ファイルシステム上でのもののありかを指し示すのに使われます。ここで、二通りのやり方があります。ひとつはabsolute(絶対) path、もう一つはrelative(相対) pathといいます。こんな風に考えるとわかりやすいと思います。自宅の居間にいて、隣の部屋(キッチン)のテーブルの上に携帯電話があるとします。この携帯電話のありかを指し示す方法を考えます。
Absolute pathではこうします。
地球/国名/自宅の住所/キッチン/テーブル/携帯電話
Relative pathではこうします。
隣の部屋/テーブル/携帯電話
Absoluteの方は日常的には不自然ですが、火星にいる友人も、二階にいる子供たちも正しく携帯電話にたどりつけます。Relative pathではそうはいきません。居間にいる人だけが正しく携帯電話にたどりつくことができ、いったん自分が二階へあがったりしてしまった瞬間に正しくたどり着けなくなってしまいます。しかし、日常的にはrelative pathの方が短くて自然ですし、(これは想像しにくいですが)家を丸ごと月へ移動しても、居間にいる人には有効であり続けます。pathの基本説明は以上です。
追記:absolute pathはfull pathと言われることもあります。
Windows上では、absolute pathはCドライブから書き始め、例えばC:\Program Files\Windows Defender\en-US\OfficeScannerShell.exe.muiといった感じです。
同じものをC:\Program Files\Windows Defender\ja-JPをcurrent directoryとした状態からrelative pathで書くと、../en-US/OfficeScannerShell.exe.muiとなります。ここで”../”は、一つ上のdirectoryを表します。”../../”とすれば二つ上の、になります。また、”./”はcurrent directoryを表します。
どうでしょう。Pathとcurrent directory、おわかりいただけましたか?それでは次へすすみましょう。
基本コマンド
directory and file manipulations
cd: change directory
まずはなんといってもcurrent directoryの移動から。
# cdのあとにスペースひとつ、行き先のpathを書いてリターン(以下同様)。
cd DESTINATION_PATH
# current directory内にあるjpeg directoryへ
cd jpeg
# あるいは
cd ./jpeg
# pathを省くとhome directoryに移動できて便利です。
cd
# tilde "~"はhome directoryを表すショートカットです。
cd ~
# home directoryに作ったmyWorks directoryへ
cd ~/myWorks
# 一つ上へ。
cd ../
pwd: print working directory
どこにいるんだいま?と思ったら。
# current directoryをabsolute (full) pathで表示してくれます。
pwd
ls: list directory contents
directoryの内容を表示します。
# 対象とするdirectoryを与えます。
ls DIRECTORY_OF_INTEREST
# 対象directoryを省くと、current directoryの内容がリストされます。
ls
# これも同じ意味です。
ls ./
# /etc directoryの内容を見たい。
ls /etc
# 二つ上のdirectory内容
ls ../../
# -a オプション。allの略。dotで始まる隠しファイルもリストされます。
ls -a
# -l オプション。longer description。1行1アイテム。詳細情報も表示。
ls -l
# -a と -l を組み合わせることも可能。
ls -al
cp: copy
mv: move
rm: remove
# copy
cp TARGET DESTINATION
# current directoryにあるfile1.jpgを一つ上の階層にあるkeep directoryにコピー
# (以後、”current directoryにある”という言い方はpathで表記します)
cp file1.jpg ../keep
# folderをcopyする場合には -r オプションを付ける
cp -r FOLDER1 FOLDER1-copy
# tables directoryを/tmpにコピー
cp -r tables /tmp
# move。移動。
mv TARGET DESTINATION
# file1.jpgを一つ上の階層にあるkeep directoryへ移動
mv ./file1.jpg ../keep
# .jpg拡張子をもつすべてのファイルを./stock directoryへ移動
mv *.jpg ./stock
# renameはmoveで行うことができる。
mv BEFORE AFTER
# record_1.txtをrecord_01.txtに変更
mv record_1.txt record_01.txt
# today directoryをwas_todayに名称変更して、一つ上のdirectoryへ移動
mv today ../was_today
# remove。削除。
rm TARGET
# 01_で始まるすべての.txtファイルを削除
rm 01_*.txt
# folderをremoveする場合には -r オプションを付ける
rm -r TARGET_FOLDER
# not_needed directoryを削除
rm -r not_needed
creating directory and empty file
mkdir: make directory
touch: timestampを操作するコマンドですが、空のfileを作るのにも使えます。
# 今日の作業フォルダを作るとします
mkdir work-Sep04-2022
# 複数を一度につくることもできます
mkdir data01 data02 data03
# 渡すのはpathなので、current directory内でなくてもok
mkdir ../../backup_dir
# からのファイル, todays-memo.txtをつくります
touch todays-memo.txt
# 複数を一度に。
touch memo1.txt memo2.txt memo3.txt
text file browsing and inspecting
cat: fileの内容をterminal画面上(STDOUT, standard out)に流し込みます。あとで説明するre-directと組み合わせて使うことが多い。
less: pagerの一つ。spaceで1ページ進む、bで1ページ戻る。リターンか下矢印で一行進む。qで終了。
head: fileの最初の数行(指定可能。defaultは5行(だったと思う))を表示する。大きなCSVファイルの最初の行にある、カラム名を見たりするのに使う。ダブルクリックしたら最後、みたいな大きなサイズ(数GB)のファイルのちょい見ができるので便利。
tail: headがあればtail。fileの後ろから数行を表示する。ログファイルの最新行を見たりするのに使う。
wc: トイレの場所を調べるのではない。-l optionで行数、-w optionでword countsを調べることができる。
grep: これはパワフル、検索コマンド。与えられた検索ワードやフレーズを含む行を抜き出して表示。
- -c hit line countのみを表示
- -i case insensitiveにする
- -A hit lineの後(after)何行を表示するか指定する
- -B hit lineの前(before)何行を表示するか指定する
diff: 二つのファイルの相違点を表示する。見方が難しいが、完全に一致しているのかどうか、を調べるのには便利。
# ファイルの内容を全表示
cat not_very_long.txt
# ファイルの内容を最初の行から順にみていく。qでコマンドプロンプトにもどる。
less relatively_long.txt
# 最初の2行を表示
head -n 2 super-big-rile-10GB.csv
# 最後の1行を表示
tail -n 1 log-since-1998.log
# ファイルの行数をチェック
wc -l all_data.txt
# Japanを含む行を抜き出す
grep "Japan" COVID-data.csv
# Japanを含む行がいくつあるかを調べる
grep -c "Japan" boost-stats.csv
# omicronを含む行の前後1行ずつも併せて表示する。omicronは大文字小文字を問わない
grep -A 1 -B 1 -i "omicron" variants-data.csv
# 昨日作ったファイルと、それをコピーして名前を変えたファイル、どっちも同じなのか知りたい。
diff yesterday.txt copied.txt
text file editing
nano: 設定ファイルなどをちょちょいとコマンドライン上で編集するのに使うコマンド
# ファイルを開いて編集開始
nano myProgram.config
# これで編集ウインドウに突入します。
# カーソルを注意深く移動して、編集を行います。
# 行った編集をファイルに書き込むには
Ctrl + O
# 書き込むけどいい?ときかれるのでリターン
# nanoを閉じるには
Ctrl + X
# ここで保存していない変更や、知らずにしてしまった変更があった場合には
# どうする?みたいにきかれますのでY, Nで答えて下さい。画面を見ればわかります。
network setting inspection
ipconfig: network interfaceに関する情報がでます。今割り当てられているIPアドレスを調べたりするのに便利。
downloader
これらは別途インストールが必要です(git-bashにはついてきません)が、紹介しておきます。これらがavailableかどうかはwhichコマンドで調べてみてください。コマンドへのpathが表示されればあるということです。which: no COMMANDNAME in … でどばーっとよくわからないpathたちが表示される場合、そのコマンドが存在しないか、コマンドのありかまでのpathがsearch pathに登録されていません。Windowsの場合、.bashrcに書いたりするよりは、Sytem Properties > Environment Variablesとたどって、User variablesのところにあるPathにコマンドのありかを追記するのがいいと思います。検索して調べてみてください。
curl: -O option: write output to a file with the same name as remote file
wget: ファイルのありかのURL(これも広義のpathです)をarumentとして与えます。
zip and tar
unzip: .zip拡張子のついたファイルへのpathを与えて展開します。
tar: tape archive。.tgz, .tar.gzを扱うことができて便利です。
# to de-compress and de-archive in one shot
tar zxvf FILE.tar.gz
tar zxvf FILE.tgz
# to archive and compress
tar zcvf OUTFILE.tar.gz FILE1 FILE2 ...
tar zcvf OUTFILE.tar.gz DIR-PATH
other useful commands
clear: 気分一新。
explorer: explorer DIR-PATHとして使います。
stream
|(vertical line): pipe あるコマンドからの出力を次のコマンドに渡すことができます。
# grepの結果がものすごく長いとします。それをlessに渡して1ページづつ落ち着いてみます。
grep -i "omicron" variants.txt | less
# headからの最初の100行のうち、dogを含む行だけlessで見たい。
head -n 100 so-many-kind-of-animals.csv | grep "dog" | less
>, >>: redirection コマンドからの出力をファイルへ振ります。
# 二つのファイルをまとめて一つにする。
cat file1.txt file2.txt > one-and-two.txt
# grepの結果をファイルに保存。
grep -i "dog" animals.txt > only-dogs.txt
# さっき作ったonly-dogs.txtに追記したい。
grep -i "dog" animals2.txt >> only-dogs.txt
Useful keys
以下のキー操作も便利です。
- TAB (auto completion)
長いファイル名やディレクトリ名をすべて打つ必要はありません。何文字か打ったところでTABを使ってみましょう。自動補完してくれます。あるいは候補を表示してくれますので、何文字か追加して確定させましょう。 - up, down, arrows
矢印キーです。コマンドヒストリからさっき打った、昨日使ったコマンドを表示してくれます。繰り返す、少し変えて使う、どこへコピーしたのか見直す、など、いろいろな場面で便利です。 - Ctrl + C
よくわからないことが起こってしまった場合、これを試しましょう。何か走っているものを止めるためのコマンドです。
コマンドライン上でのspaceについて
コマンドラインでは、スペースは区切り文字としての特別な意味を持ちます。上にいくつも例を示しましたが、例えばcpコマンドは、cp TARGET DESTINATIONのようにして使います。この、cp, TARGET, DESTINATIONがすべてspaceで区切られることで意味を持ちます。TARGET, DESTINATION部分はargumentとしてcpコマンドがこの順で解釈します。与える順序で解釈されるargumentをpositional argumentといいます。場所が大事ということですね。
普段、ファイルやフォルダの名前にスペースを入れることがあるかと思いますが、あれは曲者です。たとえば、”result 1.csv”というファイルがあって、これをどこかへコピーするとしましょう。コマンドはこうなります。
cp result 1.txt SOMEWHERE
# errorがでます。
cp: cannot stat 'result': No such file or directory
cp: cannot stat '1.csv' No such file or directory
‘file’とか、’1.csv’、そんなファイルはありません、といっています。”result 1.csv”という名前にスペースが入ってしまっているので、そこで前後に分断されてしまったわけです。これを防ぐには、”result 1.txt”として””で両側をくくってこれはひとかたまりです、を伝えます。
コマンドライン上で操作したいファイルやフォルダの名前にはスペースを使わない(使わせない)、これが基本です。スペースを使わずに、かつ読みやすい名前を付けるには以下のようにします。
- アンダースコアでresut_summary.txt (半角のアンダースコアで!)
- ハイフンでresult-summary.txt(半角のハイフンで!)
- caseを使ってresultSummary.txt or ResultSummary.txt
- あと、日本語文字は使わないでくださいとお願いすると、hachigatsubunn-kekka-matome-shitagaki.txtみたいなのが来ることがありますが、sonnaninagaito-yominikuijyanaika-geka-igoyametene.txtで返事したくなりますので、英語で付けるとすっきりしますし日本語nativeではないスタッフにも喜ばれます。
日本語を使う私たちには全角スペースというものもあって、さらに厄介さとイライラが増します。どうしてもスペースを含んだものをコマンドライン上で扱いたい時には上に書いたようにpathを””でくくりましょう。実際Windowsには”Program Files”など、最初からスペースを含んだチャレンジングなdirectoryが多々あり、また、directory区切りが¥(back slash、メタ文字のエスケープに使われる)であることから、pathの扱いでの混乱にはさらに拍車がかかります。だからプログラミングやコマンドライン仕事はMacやLinuxでやりましょう、といいたいところですが、だからこそ、Windowsでコマンドライフを書いているのです。
余談ですが、Windows Subsystem for Linux (WSL)が粛々と進化をしています。Windowsではインストールも難しいツールなどをチョイ使いするにはものすごく便利です。未来のWindowsOSはLinux basedになるといいなと期待しています。興味のある方は調べてみてください。
プロンプトのカスタマイズ
プロンプトのカスタマイズは必須ではないのですが、プロンプトが戻った時間やcurrent directoryが常に表示されるようにしておくとなにかと便利です。また、少し色付けがあるだけで、見やすい気分になります。私の例は、以下のようになっています。
左からAM, PM付きの時刻、user name + @ + host(PC) name、current directoryの順になっていて、promptが次の行頭に来るようにしてあります。
さて、これをどう実現するか、ですが、まず、home directoryに.bashrcというファイルがあるかどうかを確認します。
ls -a ~/
ない場合には、home directoryへcdして(ここまで読んでくれた方には通じると信じます)、touch .bashrcで空のファイルを用意しましょう。ドットbashrcですよ。最初の.を忘れずに。ls -aで確かにそのファイルがあることを確認しましょう。
# move to home
cd
# create an empty .bashrc
touch .bashrc
# list all files
ls -a
さて、いま、home directoryにいて、.bashrcがそこにある状況です。nanoを使って.bashrcを開きましょう。
nano .bashrc
次の行をコピーします。なんじゃこりゃですね。そうです、なんじゃこりゃです。まずは気にせずに進みましょう。
export PS1="\[\033[36m\]\@ \[\033[33m\]\u@\h \[\033[37m\]\w\n$ \[\033[0m\]"
いまコピーしたものを.bashrcにペーストするのですが、nanoはCtrl + Vを受け付けません。カーソルをどこかの行頭に来るようにした状態で、Shift + Inert。Insert keyはbackspaceの上か右にあります。もし見つからない場合には、右クリック、pasteでも同じことができます。
ここまでできたら.bashrcをCtrl + Oで保存。Ctrl + Xで終了します。
コマンドプロンプトが戻りますので、source .bashrcと打ってみてください。
変わりましたか?
さて、さっきの行は何だったんだということになりますが、ほとんどの部分は色の指定開始と終了タグです。実質的な仕事をしているのは以下の部分です。
- \@
- 現在時刻を12時間表記、AM PM付きで表示します。以下のチョイスも使えます。試してみてください。
- \t: 24 hour in HH:MM:SS format
- \T: 12 hour in HH:MM:SS format
- \A: 24 hour in HH:MM format (秒を表示しない)
- \u: user name
- \h: host name
- \w: current working directory
- \n$: 改行と行頭に$マーク。
色付けタグにつては複雑すぎて手に負えませんので、検索して調べてください。ここに紹介したのはbashというshellを使う場合です。近年、zshという名前の洗練されたshellもよく使われるようになり、macosではdefaultのlogin shellとして採用されています。zshでのプロンプトカスタマイズは、もっとあか抜けています。こちらも興味のある方は調べてみてください。git-bashには、zshはついてきていません。別途インストールの必要あり。
ファイルの拡張子をすべて表示するようにする
コマンドライフではファイルの拡張子を重視します。例えば、memo.md、memo.txt、memo.jpgは拡張子で区別されますが、Windowsの初期設定ではいくつかの拡張子が表示されないようになっています。コマンドライン上では拡張子がファイルの種類を表す重要な手がかりとなります。普段のGUI上(エクスプローラー)でもすべての拡張子が表示されるように設定しましょう。
- “folder options”で検索。(以前はそんな名前の項目がcontrol panelsにありました。)
- File Explorer Optionsがでました。たぶんこれです。クリック。
- View tabをクリック
- “Hide extensions for known file types”という項目があります。チェックを外します。
- Apply, OK。
これで完了です。