Bashプログラミング
 Computer >> コンピューター >  >> プログラミング >> Bashプログラミング

Bashの代わりにPythonを使おう——コマンドライン言語として頼れる相棒にする方法

私とBashの関係は、愛憎半ばするものです。ターミナルで過ごす時間が長いせいか、Bashはいつの間にか私のデフォルトの「プログラミング言語」になっていました。時々「find、grep、xargsこそがインフラを動かしているんだ」と人に話すと、みんな大笑いします。そして、私が本気だと気づくのです。

システム管理者にとってPythonを身につけるのは完璧な選択です。さらに、ターミナルでの作業が必要だけれどBashは使いたくない人や、Bashでは複雑すぎる処理を抱えている人にとっても最適です。タスクが次のようなワンライナーを超えたら——

find $(pwd) -name "*.txt" | xargs -I {} echo "do stuff with {}"

——それはPythonの出番です!

コマンドライン言語としてPythonを使うことには、多くのメリットがあります。

  • 豊富なライブラリ: ほぼあらゆる用途に対応する便利なライブラリが揃っています。システム操作、ファイルの読み書き、ディレクトリの一覧表示、forループ、終了コードのチェックなども含まれます。
  • IDEによる自動補完: 本当に強力です。わざわざ暗記したい人はいないはず。
  • 堅牢なテストスイート: テストを書く習慣がない方も、これを機に始めてみてはいかがでしょうか。
  • iPythonコンソール: これは本当に素晴らしい。大好きです!
  • 高い可用性: Pythonはほとんどのシステムで利用可能で、なければMinicondaで簡単に入手できます。
  • try/exceptによる堅牢なエラー処理: 予期しない失敗にも优雅に対処できます。
  • クロスプラットフォーム対応: 異なるOSで作業しても、Pythonライブラリがその違いを内部で吸収してくれます。
  • 初心者に優しい: プログラミング経験がゼロでも、Pythonは始めやすい言語です。

さあ、始めよう

まずは、Pythonがインストール済みであることを確認するか、Minicondaでインストールしましょう。

iPythonがインストールされているか確認する

which python
which ipython

両方のコマンドが成功すれば準備完了です!PythonはあるけれどiPythonがない場合は、インストールが必要です。システムパッケージとして入れることもできますが、Miniconda経由でのインストールを強くおすすめします。

Minicondaをインストールする

公式サイトから自分のOSに合ったインストーラーをダウンロードしてください。Python3版を選ぶのがおすすめです。

あとはシンプルなインストール作業だけです。

bash Miniconda3-latest-Linux-x86_64.sh

プロンプトに従えばMiniconda3のインストールは完了です。インストール後は必ずアップデートを実行しましょう。これぞ技術というもの、アップデートは欠かせませんよね ;-)

conda update conda
conda config --add channels conda-forge
conda update -y --all
conda install -y ipython

トラブルシューティング

パッケージのインストールで問題が起きた場合は、次のヒントを試してみてください。

  • conda clean --all を実行してから再試行する。
  • 正しいチャンネルを指定しているか確認する。
  • conda update -y --all を実行する。
  • グローバルのconda環境には必要最小限のパッケージだけを入れる。代わりに、タスクやプロジェクトごとに個別の環境を作成しましょう(後述します)。

Condaで環境を作成する

virtualenv、pipenv、Rbenv、plenv、anyenvなど、ここ数年登場したさまざまな「〜env」系ツールを使ったことがあれば、この考え方はとても馴染み深いはずです。「プロジェクトごとに独立した分離環境を持たせるべき」という発想です。

conda create -n my-project ipython package1 package2 package2

私のようにiPythonをいつでも使える状態にしておきたい方は、新しい環境を作るたびに必ずiPythonも一緒にインストールしておきましょう!

システム管理に便利なPythonライブラリ

実例に入る前に、役立つパッケージをいくつか紹介しておきます。

まず筆頭のお気に入りは os パッケージです。ディレクトリの一覧表示、ファイルの存在確認、シンボリックリンクの確認、ディレクトリの作成、システムコマンドの実行、環境変数の取得・設定など、何でもこなせます。本当に便利です!

2番目は subprocess モジュールです。Pythonライブラリとして用意されていないシステムコマンドを実行するときに活躍します。

shutil には、osライブラリにはないファイル操作機能が含まれています。

pprint ライブラリは、複雑なデータ構造を見やすいインデント付きで整形出力してくれます。

pytest ライブラリを使えばPythonコードをテストできます。正直なところ、何事も最初(の数回)は思い通りに動かないものですからね。

コードはどうやって実行する?

ついにコードの時間です!

Bashの代わりにPythonを使おう——コマンドライン言語として頼れる相棒にする方法

システム管理にPythonを使う場合、iPythonコンソールに直接飛び込むこともできますし、スクリプトを書いて python スクリプト名.py のように実行することもできます。

スクリプトを書くスタイルが好みなら、選択肢はたくさんあり、完全に個人の好みの問題です。私は有料のPyCharmを使っていますが、Visual Studio CodeやAtomも同じくらい優れた無料の選択肢です。

私の場合、取り組んでいる内容によって使い分けています。iPythonコンソールを開いてそのまま打ち込み始めることもあれば、テストなどを含むもっと堅牢な構成が必要なこともあります。

iPythonコンソールでも、上記のエディタでも自動補完が使えます。自動補完は最高です!iPythonでは、関数名を打ち込み始めてTabキーを押せば、候補となる関数の一覧が表示されます。

Bashの代わりにPythonを使おう——コマンドライン言語として頼れる相棒にする方法

自動補完をどれほど愛しているか、言葉では表しきれません ;-)

ヘルプの引き方

各ライブラリのドキュメントページを見てもいいのですが、ライブラリ名や関数名が分かっていれば、iPython内で直接ヘルプを呼び出せます。

Bashの代わりにPythonを使おう——コマンドライン言語として頼れる相棒にする方法

Bashの代わりにPythonを使おう——コマンドライン言語として頼れる相棒にする方法

多くのIDEやテキストエディタにもヘルプ機能がありますが、その操作方法はエディタごとに異なります。

実例集

まず、必要なパッケージをインポートします。

import os
import subprocess
import shutil
from pprint import pprint

以下は、よく使うファイル・ディレクトリ操作の例です。

# カレントワーキングディレクトリを取得
# 文字列が返される
my_cwd = os.getcwd()
print(my_cwd)
# ディレクトリの中身を一覧表示
# リストが返される
dir_list = os.listdir()
for item in dir_list:
    print(item)
# ファイルの絶対パスを取得(ファイル名 + カレントワーキングディレクトリ)
os.path.abspath('some-file')
# ベースネームを取得 - ファイル名が返される
os.path.basename('/path/to/file')
# ディレクトリパスを分割 - プラットフォーム非依存
os.path.split(os.getcwd())
# Out[17]: ('/Users', 'jillian')
# パスが存在するかどうか確認
os.path.exists('/path/on/filesystem')
# パスがシンボリックリンクかどうか確認
os.path.islink()

続いて、ファイルやディレクトリのコピー・移動です。

# ディレクトリをコピー(cp -rf 相当)
shutil.copytree('src', 'dest')
# ファイルをコピー
shutil.copyfile('file1', 'file2')
# ディレクトリを移動(mv 相当)
shutil.move('src', 'dest')

すべてがPythonライブラリで賄えるわけではありません。たとえばシステムライブラリのインストールなどは、システムコマンドを実行しましょう!

# 任意のシステムコマンドを実行
command = "echo 'hello'"
result = subprocess.run(command.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 標準出力と標準エラー出力を表示
print(result.stdout)
print(result.stderr)

もちろん、ファイルへの書き込みもできます!

# ファイルに書き込む(存在しなければ新規作成)
# echo "hello" > hello.txt 相当
f = open("hello.txt","w+")
f.write("hello!")
f.close()
# ファイルに追記する
# echo "hello" >> hello.txt 相当
f = open("hello.txt", "a+")
f.write("hello again!")
f.close()

テストを書いてみよう!

テストは主に assert という関数を使って動作します。これは「この条件が真であることを保証し、偽なら大声でエラーを吐いて止まる」という意味です。

def test_system_command():
    """システムコマンドの終了コードをテスト"""
    command = "echo 'hello'"
    result = subprocess.run(command.split(' '), stdout=subprocess.PIPE)
    assert result.returncode == 0

この関数を test_my_code.py というファイルに保存し、pytest test_my_code.py として実行すればOKです。

まとめ

以上が、Pythonを頼れるBash代替として使いこなすための主なヒントとコツでした。次にBashでループを書きたくなったときは、ぜひiPythonコンソールを開いて、何ができるか試してみてください。きっと新しい発見があるはずです!

  1. コマンドラインから操作するPython Matplotlibのインタラクティブプロット入門

    Matplotlibでインタラクティブなプロットを実現するには、図(figure)をアクティブな状態にしておく必要があります。plt.ioff() と plt.ion() を使い分けることで、プロットに対するインタラクティブな操作の有効・無効を自由に切り替えることができます。 それでは、IPython シェルを起動し、以下のコマンドを順番に入力して動作を確認してみましょう。 実行例 In [1]: %matplotlib auto Using matplotlib backend: GTK3Agg In [2]: import matplotlib.pyplot as In [3]: fi

  2. AndroidのCyanogenModをLineageOSに置き換える方法|移行手順を徹底解説

    開発終了が決まったCyanogenModから、その後継とも言うべきLineageOSへの大規模な移行が進んでいます。ルート化済みのAndroidユーザー数十万人規模が、CyanogenModと同じく、不要なプリインストールアプリ(ブロートウェア)を排除した柔軟なストックAndroid体験を提供するオープンソースプロジェクトへと乗り換えつつあります。 朗報なのは、LineageOSの実験的ビルド(experimental build)を使えば、比較的スムーズに移行できるという点です。ここではTWRPリカバリーを使用しますが、他のリカバリーツールでも基本的な流れはほぼ同様です。 1. Linea