1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

○○作ってみない?Advent Calendar 2023

Day 11

去年もやったけど「DiscordBOTでも作ってみない?」3日目

Last updated at Posted at 2023-12-10

そういえばビルドビルド言ってるけど何のビルド?

そうでしたねぇ...ちゃんと説明してませんでした...
今回は「Gitで管理されているArduinoプロジェクト」の管理としましょう。

Git?

流石に説明不要だと思いますが、プログラムとかのプロジェクトを管理するためのもので、変更履歴が全て保存され、バージョン管理が容易にできる物です。
また、コマンドひとつでソースコードを自分のパソコンにダウンロードしてくれる(Clone)ので、複数デバイス・複数人での開発でも重宝されるサービスとなっております。
よくGitとGitHubがごっちゃになっちゃいますが、Gitはバージョン管理ソフト、GitHubはGitのレポジトリを保存できるサーバーを提供しているものって感じです。

...なんか説明が適当になっちゃった気がするので気になる人はGitで調べて見てください。

Arduino?

マイコンです。
なんと、このアドベントカレンダーでも記事を書いているのでぜひご確認ください。

コマンドを実行するコマンドを作ろう(?)

Q. この男...何を言っているのかわからない...
A. そうだな...でも、そういうことなんだよ...

なお、ここからの記事ではGitの最低限の知識があり、すでにレポジトリが作成されていることを前提としています。

(シェル)コマンドを実行する(スラッシュ)コマンドを作っていこうというわけです。

どうやってPython上からシェルコマンドを実行するの?

様々な方法がありますが、今回はsubprocessを使用します。

>>> import subprocess
>>> subprocess.run(["uname"])
Linux
CompletedProcess(args=['uname'], returncode=0)

subprocessではこんな風にシェルコマンドを実行することができます。
結構簡単ですね。

じゃあ、これをスラッシュコマンドに組み込んでみよう

main.py
import subprocess
from subprocess import PIPE

...

@bot.slash_command()
async def git(interaction: nextcord.Interaction):
    pass

@git.subcommand()
async def status(interaction: nextcord.Interaction):
    process = subprocess.run(["git", "status"], stdout=PIPE)
    await interaction.response.send_message(embed=nextcord.Embed(
        title="Git Status Result",
        description=f"```sh\n{process.stdout.decode('utf-8')}```"
    ))

...

あーー!!!ちょっとまって!!!

私の前回のアドベンドカレンダーを見た人はもうわかりますよね?

そうです、subprocess.runは同期処理です。
なので、やっぱりここは非同期処理にしないといけません。

なので早速ですがsubprocessを捨ててasyncio.create_subprocess_shellを使ってみましょう。

main.py
### これらは削除かコメントアウト ###
# import subprocess
# from subprocess import PIPE

import asyncio
...

@git.subcommand()
async def status(interaction: nextcord.Interaction):
    process = await asyncio.create_subprocess_shell("git status", stdout=asyncio.subprocess.PIPE)
    stdout, stderr = await process.communicate()
    await interaction.response.send_message(embed=nextcord.Embed(
        title="Git Status Result",
        description=f"```sh\n{stdout.decode('utf-8')}```"
    ))

...

結構変わってきましたね。
まず、subprocess.runasyncio.create_subprocess_shellになりました。
それによって、渡すコマンドがリストから文字列になりました。
そして、stdoutasyncio.subprocess.PIPEになりました。
そして、process.stdout.decode('utf-8')stdout.decode('utf-8')になりました。

これで、非同期処理に対応したコマンドができました。

スクリーンショット 2023-12-02 231521.png
実際に実行するとこのようになります。

もうすぐだね...!

あとは簡単ですね、コマンドの中身を入れ替えるだけです。
...じゃあそのコマンドってどんな感じなんでしょうか。

と言うわけで次回から割り込み企画「何でもかんでもコンソールでやってみない?」を始めます。

コンソールで実行できればこんなふうな外部からの操作ができたりうんぬんかんぬん...

あとがき

まだ書き途中だったのに公開されちまった...ミスだぜ!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?