Pythonでシェルスクリプトを作成し、それをBashに置き換えることは可能ですか

この短い記事では、Bash / Shの代わりにPythonを使用してスクリプトを簡単に作成できるかどうかについて説明します。 読者が最初に疑問視するのは、おそらく、実際にBash / Shを使用してみませんか。 それらはずっと前に作成されたもので、私の意見では、他の言語とあまり似ていないかなり具体的な構文を持っています。 簡単なifの書き方を覚えていますか?

if [ $# -ne "$ARGCOUNT" ] then echo "Usage: `basename $0` filename" exit $E_WRONGARGS fi 

初歩的な真実? 直感的な構文。 :)

ただし、Pythonでは、これらの構造ははるかに単純です。 bashに何かを書くたびに、単純にif、switch、または他の何かを書く方法を覚えて、必ず検索エンジンに登ります。 私はすでに課題を記憶しています。 :) Pythonでは、すべてが異なります。 私は24時間体制でそれを書いていませんが、言語の構文はシンプルで直感的であるため、そこに登って単純なサイクルを作成する方法を見る必要はありませんでした。 さらに、Bash / Shよりもjavaやc ++などの他の主流言語にはるかに近いです。

また、標準およびその他のPythonライブラリには、コンソールユーティリティよりもはるかに便利なライブラリがあります。 json、xml、yamlを解析するとします。 これを行うために最近bashで見たコードを知っていますか? 正しく:

 python -c "import json; json.loads..." :) 

そして、それは私のコードではありませんでした。 それはbash / python中立の個人コードでした。

正規表現と同じように、sedは間違いなく便利なユーティリティですが、どのように正しく使用するのかを覚えている人はいますか? まあ、彼女を作ったリー・E・マクマホンを除いて。 はい、原則として、多くの人は、単純なことをどのように行うかを覚えています。 しかし、私の意見では、Pythonでは、reモジュールの方がはるかに便利です。

この短い記事では、 shellpyと呼ばれるPython方言を紹介し、スクリプトでBashをpythonに置き換えることを可能にします。

猫の下にようこそ。

はじめに


シェルpythonは、1つの詳細を除いて単純なPythonと変わりません。 Pythonとは異なり、重大なアクセント文字( `)内の式はevalではありませんが、シェルでのコマンドの実行を示します。 例えば

 `ls -l` 

ls -lをシェルコマンドとして実行します。 行末に `なしでこれらすべてを書くことも可能です。

 `ls -l 

それも正しい構文になります。

異なる行で複数のコマンドを一度に実行できます

 ` echo test > test.txt cat test.txt ` 

および複数の行コマンド

 `echo This is \ a very long \ line 

shellpyで各式を実行すると、クラスResultのオブジェクトが返されます

 result = `ls -l 

これは、 ResultまたはInteractiveResultのいずれかです (ドキュメントのあるgithubへのリンク。後で見ることができます:))。 簡単な結果から始めましょう。 それから、実行されたコマンドの戻りコードを簡単に取得できます

 result = `ls -l print result.returncode 

そして、stdoutとstderrからのテキスト

 result = `ls -l result_text = result.stdout result_error = result.stderr 

ループで実行されたコマンドのすべての標準出力行を調べることもできます

 result = `ls -l for line in result: print line.upper() 

などなど。

結果にはさらに多くの構文糖衣があります。 たとえば、実行中のコマンドのリターンコードがゼロであることを簡単に確認できます。

 result = `ls -l if result: print 'Return code for ls -l was 0' 

または、標準出力からテキストを取得する簡単な方法

 result = `ls -l print result 

上記はすべて構文の簡単な概要であり、主なアイデアを理解するためのものであり、すべての詳細をすべて負担するものではありません。 コマンドの実行を制御するために、実行されたコマンドとの対話型相互作用にはさらに多くのものがあります。 しかし、アイデア自体があなたにとって興味深いと思われる場合、これらはすべて詳細なドキュメントです (英語)。

これは有効なPython構文ではありませんが、どのように機能しますか?


もちろん、まだマジック:)はい、私の友人、私は前処理を使用しなければなりませんでした、私は悔い改めましたが、私は別の方法を見つけませんでした。 次のような言語構文に違反することなく、同様のことを行う他のライブラリを見ました

 from sh import ifconfig print(ifconfig("wlan0")) 

しかし、この構文は私には向いていませんでした。困難にもかかわらず、私は最高のユーザーエクスペリエンス©を手に入れたかったので、私にとってこれは可能な限りシンプルでand下に近いコマンドをシェルに書くことを意味します

トピックに精通している読者は、IPythonがあなたに合わなかった理由を尋ねるでしょう。そこでは、もう1つのアイコンを置くだけのように、多分あなたは検索エンジンを見るのが面倒なサイクリストですか? そして実際には次のようになります:

 lines = !ls -l 

私はそれを使おうとしたが、うまくいかないいくつかの深刻な問題に遭遇した。 最も重要なのは、Pythonのような単純なインポートがないことです。 つまり、ipython自体にコードを記述して、他の場所で簡単に再利用することはできません。 ipythonモジュールに書き込むことができません

 import myipythomodule 

そして、すべてがすぐにおとぎ話のように機能するように。 スクリプトを再利用する唯一の方法は、スクリプトを実行することです。 実行後、環境では、すべての関数と変数が実行可能ファイルで宣言されます。 私の意見ではコーシャではありません。

shellpyでは、通常のpythonと同様に、コードを簡単に再利用してインポートできます。 非常に便利なコードを格納する共通モジュールがあるとします。 このモジュールでディレクトリを調べてみましょう

 ls common/ common.spy __init__.spy 

したがって、ここにあるものは、まずinitですが、拡張子は.spyです。 これは、通常のスパイモジュールの特徴です。 common.spyファイルの内部も見てみましょう。

 def common_func(): return `echo 5 

ここでは、内部でshellpy構文を使用して `echo 5の実行結果を返す関数が宣言されていることがわかります。このモジュールはコードでどのように使用されますか? そして、ここに方法です

 from common.common import common_func print('Result of imported function is ' + str(common_func())) 

ほら 通常のPythonの場合と同様に、彼らはそれをピックアップしてインポートしました。

どのように機能しますか。 これはPEP 0302-新しいインポートフックで動作します。 コードに何かをインポートすると、最初にPythonがフックに何かがあるかどうかを尋ね、フックは* .spyファイルまたはshellpythonモジュールのPYTHONPATHを調べます。 何もなければ、彼は言う:「何もない、あなた自身を輸入しなさい。」 彼がそこで何かを見つけた場合、フックはそれ自体でインポートを行います。 つまり、彼は通常のpythonでファイルを準備し、これらすべてをオペレーティングシステムのtempディレクトリに入れます。 新しいPythonファイルまたはモジュールを作成した後、彼はそれをPYTHONPATHに追加し、最も一般的なインポートが行われます。

いくつかの例を見てみましょう


このスクリプトはGithubからPythonユーザーアバターをダウンロードし、tempディレクトリに配置します

  import json import os import tempfile #   curl      answer = `curl https://api.github.com/users/python #         if answer: answer_json = json.loads(answer.stdout) avatar_url = answer_json['avatar_url'] destination = os.path.join(tempfile.gettempdir(), 'python.png') #       result = `curl {avatar_url} > {destination} if result: #    ,    p`ls -l {destination} else: print('Failed to download avatar') print('Avatar downloaded') else: print('Failed to access github api') 

美しさ...

設置


Shellpythonは2つの方法でインストールできます: pip install shellpyまたはリポジトリpip install shellpy setup.py installpip install shellpy ます 。 その後、 shellpyユーティリティが表示されます。

何かを実行しましょう


インストール後、リポジトリで直接利用可能なサンプルを使用してshellpythonをテストできます。

 shellpy example/curl.spy shellpy example/git.spy 

ここにはallinoneの例もあります。これらの例は、shellpyにあるすべての機能をテストするため、このような名前が付けられています。 立ち寄って他に何があるかを調べるか、単にフォローしてください

 shellpy example/allinone/test.spy 

3番目のPythonの場合、コマンドは次のようになります

 shellpy example/allinone/test3.spy 

互換性


これはLinuxで動作し、Python 2.xおよび3.xのMacでも動作するはずです。 まだWindowsでは機能しませんが、すべてがクロスプラットフォームライブラリを使用して記述されており、コードにはプラットフォーム固有のものがないため、作業に問題はありません。 私はまだWindowsでテストするためにまだ手を伸ばしていません。 私もケシを持っていませんが、それは友人のために働くように思われました:)あなたがケシを持っていて、すべてがうまくいけば、教えてください。

問題が見つかった場合-コメントを書くか、ここに https://gitter.im/lamerman/shellpyでチャットに参加します または何とかケーブル:)

ドキュメント(英語)


Wiki

することは可能ですか


もちろん:)

本番環境で何か問題がありますか?


バージョン0.4.0では、これは安定した実稼働プロセスではないため、すべてがデバッグされるまで待機した後、スクリプトに結び付けない方が良いでしょう。 しかし、開発では、CIは完全に使用できます。 これはすべてテストと動作でカバーされます:) ビルドステータス

Ps


アイデア全体、特に実装、問題、希望、フィードバックについてのフィードバックを書いてください。誰もが聞いてうれしいです:) githubで問題を開始してください。すでにたくさんあります:)

Source: https://habr.com/ru/post/J277679/


All Articles