ワークショップ シェルの基礎(2) 「pythonかんたんプログラム」 を通して学ぶシェルの基本操作 2017.10.3 小川猛志
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
1. 本演習の目的 python による"数当てゲーム"の作成を例題として、シェルの基本的なコマンドの使い方を習得する。 コマンド 書式例 書式例の意味 set set n=1 シェルの設定値を全て表示 シェルの変数nを定義して、1を代入 echo echo $n 変数nの値を表示 pwd shellが表示しているディレクトリ(カレントディレクトリ)名を表示 ls ls -l カレントディレクトリ内のファイル名を表示 -l で各ファイルの属性(読込、書込、実行の権利など)も表示 cd cd .. など 1つ上位のディレクトリに移動 > ls > log.txt コマンド(ls)の実施結果をファイルに出力(上書き) (">"はリダイレクト、と読む) >> ls >> log.txt コマンド(ls)の実施結果をファイルに出力(追記) | ls | grep log コマンドの実施結果を次のコマンドの入力に接続 (" | "はパイプ、と読む) tee ls |tee –a log.txt コマンド(ls)の実施結果を標準出力(画面)に出力するとともにファイルに出力(-a があると追記、無いと上書き) date その時の日時を出力
1. 本演習の目的(続き) コマンド 書式例 書式例の意味 cat cat log.txt ファイル(log.txt)の内容を画面に出力 more more log.txt ファイル(log.txt)の内容を1画面に入る分ずつ出力 tail tail -4 log.txt ファイル(log.txt)の末尾から指定した行数だけ画面に出力 mkdir mkdir py ディレクトリを作成 diff diff log1.txt log2.txt 2つのファイルの差分を表示 grep grep ogawa log.txt キーワードを含む行をファイルから抽出して表示 cp cp log.txt tmp/log.bak ファイルを指定したディレクトリにコピー mv mv log.txt tmp/log.bak ファイルを指定したディレクトリに移動 rm rm log.txt, rm -R tmp 指定したファイルやディレクトリを削除 chmod chmod 755 py.py 3桁の数字でファイルへのアクセス権を設定(先頭から1桁づつ、ユーザ、グループ、その他について、以下のアクセス権を意味)。 bit 1 実行権、bit2 書込権、bit3読込権(0:権利なし、1:権利あり) 例 5 = 4+1 =101b→実行と読込は可能、書込は不可 man man cd コマンド(cd) の使い方、オプションを表示 history コマンド履歴を表示 !12 など,!の後に行番号を投入すると,そのコマンドを実行
2. シェルってなに? シェル ユーザがOSのカーネル機能を操作するために使う コマンドライン型のインタフェース ユーザから見るとカーネルを包み込んでいるように見える ので、shell(貝殻)と呼ばれる windowsではコマンドプロンプト、 linuxやMacOS(Unix系) ではTerminal. コマンド 出力 シェル
2. シェルってなに? $ echo $SHELL 色んな種類がある。RaspbianではBashが一般的。 複数言語対応や、ライン補完(後ほどトライ)などが得意 確認しよう $ echo $SHELL linux やMacOSでもBashが一般的.BSDではtcshが主流. 最近,windowsでも使用できるようになった. ogawa@pi:~ $ echo $SHELL /bin/bash ogawa@pi:~ $
2. シェルってなに? シェルだけでもちょっとしたプログラムが書ける 例: n<m なら、ある文章を表示 $ n=3 $ echo $n $ m=4 $ echo $m $ if(test $n -lt $m);then echo "n is 'smaller' than m";fi $ $ if(test $n -lt $m);then echo "n is 'smaller' than m $> and 'poor' $> and ‘gray’ ";fi 変数nの値を表示 " で囲んだ文章を表示 複数行の 表示も可能 改行 改行 ">"は行が続いている,の意味 注:引用符( “ や ‘ )の使い方や、改行の仕方はシェルの種類により大きく異なる
実行結果の例 ogawa@pi:~ $ n=3 ogawa@pi:~ $ echo $n 3 ogawa@pi:~ $ m=4 ogawa@pi:~ $ echo $m 4 ogawa@pi:~ $ ogawa@pi:~ $ if(test $n -lt $m);then echo "n is 'smaller' than m";fi n is "smaller" than m ogawa@pi:~ $ if(test $n -lt $m);then echo "n is 'smaller' than m > and 'poor' > and 'gray' ";fi n is 'smaller' than m and 'poor' and 'gray'
3. Pythonってなに? Raspberrypiでの推奨言語の一つ. 動的プログラミング言語.コンパイルせずに実行可能 (インタープリタ型とも言う) JavaScript,Perl,PHP, Rubyなども仲間 プログラムの構造が目で見て分かりやすい インデントでブロックを識別 初心者でも書きやすい、読みやすい 対話モードで1行づつ動作確認もできる 名前の由来はイギリスのTVコメディ "空飛ぶモンティ・パイソン" 今回は時間の都合のため、 プログラムの手段として使うだけ。 Pythonに詳しくなることは目指しません。 http://ja.wikipedia.org/wiki/wiki/空飛ぶモンティ・パイソン
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
(1) ファイル名を控える ユーザでのlogin直後は、/home/userディレクトリ内がshellで見える。 今見えているディレクトリ(カレントディレクトリ)の名前を調べよう $ pwd shellでの操作は、カレントディレクトリの内部が基本 ディレクトリを最上位のディレクトリ(ルートディレクトリ) に移動しよう $cd / ディレクトリ内のファイル名を見よう $ ls -alt ホームに戻ろう $ cd ogawa@pi:~ $ pwd /home/ogawa ogawa@pi:~ $ ls ogawa@pi:~ $ cd / ogawa@pi:/ $ ls -al total 92 drwxr-xr-x 21 root root 4096 Sep 17 11:46 . drwxr-xr-x 21 root root 4096 Sep 17 11:46 .. drwxr-xr-x 2 root root 4096 May 27 11:22 bin drwxr-xr-x 4 root root 16384 Jan 1 1970 boot 略 ogawa@pi:/ $ cd ogawa@pi:~ $
<参考> プロンプトでのディレクトリ表示 <参考> プロンプトでのディレクトリ表示 bashでは、プロンプトでカレントディレクトリが表示される。 ~ は、ユーザのホームディレクトリ(ログイン時に最初に見えるディレクトリ。アカウント作成時にユーザ毎に作成される) root(管理者)でログインすると、/rootが該当する。 /は、最上位のディレクトリの意味。これもルート、と呼ぶ。 プロンプト ogawa@pi:~ $ cd / ogawa@pi:/ $ ls bin dev home lost+found mnt proc run srv tmp var boot etc lib media opt root sbin sys usr ogawa@pi:/ $ cd bin ogawa@pi:/bin $ カレントディレクトリ
(1) ファイル名を控える ~ 内のファイル名を控えよう shellのコマンドの実行結果は通常画面に出てくる(標準出力) ~ 内のファイル名を控えよう shellのコマンドの実行結果は通常画面に出てくる(標準出力) 実行結果をファイルに出力することができる 方法1: リダイレクト 記号 を使う ファイルへの、上書き " >", 追記 ">>" 方法2: パイプとtee を使う ファイルへの、上書き " |tee", 追記 "|tee -a" ホームに戻ろう $cd 現時刻を画面に出力しよう。 $ date 出力先をファイルにしよう $ date > tmp.txt ファイルの中身を見よう $ cat tmp.txt パイプ
(1) ファイル名を控える 演習 各自のホームディレクトリ内のファイル名を、新しいファイルから順に並べて,logtmp1.txt に出力しよう :~ $ ls –alt >logtmp1.txt ogawa@pi:~ $ ls -alt total 32 drwxr-xr-x 2 ogawa ogawa 4096 Sep 23 08:55 . -rw-r--r-- 1 ogawa ogawa 29 Sep 23 08:53 tmp.txt 略 ogawa@pi:~ $ ls -alt >logtmp1.txt ogawa@pi:~ $ cat logtmp1.txt total 28 -rw-r--r-- 1 ogawa ogawa 0 Sep 23 08:56 logtmp1.txt ogawa@pi:~ $
(1) ファイル名を控える 演習 /tmp 内のファイル名を、新しいファイルから順に並べて,logtmp1.txt に出力しよう :/tmp $ ls –alt >logtmp1.txt ogawa@pi:~ $ ls -alt total 32 drwxr-xr-x 2 ogawa ogawa 4096 Sep 23 08:55 . -rw-r--r-- 1 ogawa ogawa 29 Sep 23 08:53 tmp.txt 略 ogawa@pi:~ $ ls -alt >logtmp1.txt ogawa@pi:~ $ cat logtmp1.txt total 28 -rw-r--r-- 1 ogawa ogawa 0 Sep 23 08:56 logtmp1.txt ogawa@pi:~ $
"l"(エル)だけ入力してtabを押すと補完してくれる (1) ファイル名を控える logtmp1.txtにファイル名が記入できたことを確認する 先頭から少しづつ見る $ more logtmp1.txt 末尾から指定した行数見る $ tail -2 logtmp1.txt "l"(エル)だけ入力してtabを押すと補完してくれる
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
(2) 作業用ディレクトリを作る ~(ホーム) 内に作業用ディレクトリ py を作ろう ディレクトリを新たに作る $ mkdir py 念のため、できたか確認 $ ls 一旦消してみる $ rm -R py もう一度作る $ mkdir py ホームフォルダ 内のファイル名を、今度は logtmp2.txt に出力しよう $ ls -alt >logtmp2.txt
(2) 作業用ディレクトリを作る ファイルの変化を確認しよう 2つのファイルの違いを、diff で見ることができる $ diff logtmp1.txt logtmp2.txt grepを組み合わせると、diffの出力の中で特定のキーワードを含む行のみを見ることもできる。 $ diff logtmp1.txt logtmp2.txt | grep "py"
ogawa@pi:~ $ mkdir py ogawa@pi:~ $ ls -alt >logtmp2.txt ogawa@pi:~ $ diff logtmp1.txt logtmp2.txt 1,3c1,5 < total 28 < -rw-r--r-- 1 ogawa ogawa 0 Sep 23 08:56 logtmp1.txt < drwxr-xr-x 2 ogawa ogawa 4096 Sep 23 08:55 . --- > total 36 > drwxr-xr-x 3 ogawa ogawa 4096 Sep 23 09:01 . > -rw-r--r-- 1 ogawa ogawa 0 Sep 23 09:01 logtmp2.txt > drwxr-xr-x 2 ogawa ogawa 4096 Sep 23 09:01 py > -rw-r--r-- 1 ogawa ogawa 422 Sep 23 08:56 logtmp1.txt ogawa@pi:~ $ diff logtmp1.txt logtmp2.txt |grep "py" ogawa@pi:~ $ ← logtmp1の1〜3行目がlogtmp2の1〜5行に入れ替わった
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
(3) "Hello World" py 内にプログラムファイル を作ろう 作業用ディレクトリに移動する $ cd py (注: $ cd /home/user/pyでも良い.次スライド参照) 次の一行だけのファイルを作りたい。ファイル名は "hello.py" print 'Hello Takeshi' シェルでこのファイルを実行すれば、画面にprint の引数が出力される, $ python hello.py 演習 hello.py を作って実行してみよう! $ echo "print 'Hello Takeshi'" > hello.py ogawa@pi:~ $ cd py ogawa@pi:~/py $ pwd /home/ogawa/py ogawa@pi:~/py $ echo "print 'Hello Takeshi'" > hello.py ogawa@pi:~/py $ python hello.py Hello Takeshi ogawa@pi:~/py $
<参考> cd ディレクトリ間を移動するには「cd」コマンドを使用。cdの後ろに,移動先のディレクトリを記述。記述方法には2種類ある。 相対パス:カレント・ディレクトリ(root)から目的のディレクトリに至るパスを指定 $ cd tmp ←ディレクトリをそのまま指定 $ pwd /root/tmp 絶対パス:ルート(ディレクトリ構造の最も上)を表す「/」からのパスを指定。 $ cd /root/tmp ←「/」からのパスを指定 ショートカット 1つ上のディレクトリに移動 $ cd .. ホーム・ディレクトリに移動(管理者の場合は/root) $ cd
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
(3) "数当てゲーム" の作成 Webのtopページにある"pygame.py"ファイルをノートPCにダウンロードし,テキストをコピーして,raspiのシェルのプロンプトにペーストしよう. echo "import random n=random.randint(1,4) m=0 while(n!=m): print 'Guess n, 1 to 4' m=input() if n == m: print 'Right'" > pygame.py 1,2,3,4のいずれかをランダムにnに代入 mがnに一致するまでループ インデント (半角スペース) に注意 mがnに一致すると、Rightと出力
レジュメ 1. 本演習の目的 2. シェルってなに? 3. Pythonってなに? 4. 演習内容 ファイル名を控える 作業用ディレクトリを作る "Hello world!" の作成 "数当てゲーム" の作成 ゲームの改良
(3) ゲームの改良 ソースを直す前にbackupディレクトリを作って控えを取ろう backupディレクトリを作る。 $ mkdir backup コピーする $ cp pygame.py backup/pygame.bak 属性を見てみよう $ cd backup $ ls -l pygame.bak (注:小文字の L ) 書き換えられないようにしよう $chmod 444 pygame.bak ogawa@pi:~/py $ mkdir backup ogawa@pi:~/py $ ls backup hello.py pygane.py ogawa@pi:~/py $ cp pygane.py backup/pygame.bak ogawa@pi:~/py $ cd backup/ ogawa@pi:~/py/backup $ ls -l total 4 -rw-r--r-- 1 ogawa ogawa 118 Sep 23 10:00 pygame.bak ogawa@pi:~/py/backup $ chmod 444 pygame.bak -r--r--r-- 1 ogawa ogawa 118 Sep 23 10:00 pygame.bak 444
演習 pygame.bak をrmして、何が起こるか確認しよう ogawa@pi:~/py/backup $ rm pygame.bak rm: remove write-protected regular file ‘pygame.bak’? yes
応用1 テキストのコピペをせずに. 当たらなかった場合のメッセージを追加しよう import random n=random.randint(1,4) m=0 while(n!=m): print 'Guess n, 1 to 4' m=input() if n == m: print 'Right' else: print 'Wrong' この部分を再度コピペ,は禁止! ヒント:echo と リダイレクトを活用!
応用2 テキストのコピペをせずに. 起動時のメッセージを追加しよう print 'Hello Takeshi' import random n=random.randint(1,4) m=0 while(n!=m): print 'Guess n, 1 to 4' m=input() if n == m: print 'Right' else: print 'Wrong' この部分を再度コピペ,は禁止! ヒント:cat と リダイレクトを活用!
解答の例 応用1 $ echo " else:print 'Wrong'">>pygame.py 応用2 $ cat pygame.py >> hello.py または $ cat hello.py pygame.py > new_pygame.py
受講者による解答例