autohotkeyをWSL Bashから引数でフレキシブルなコーディングを可能にする実装をしてみた

    >

プログラミングは、進む時は面白いぐらいに進むのに、詰まる時はとことん詰まる。そしてそのままフェードアウト…といったことはよく聞く話です。僕もHTMLから始めて、長いことプログラミングを続けてきましたが、どうしても自分の思い通りにいかない、実装ができない、エラーが続く、といった状況に悩まされ、うつ状態になり、もういっそプログラミングなんて辞めてしまおうか…と挫折しそうになった経験が、幾度となくあります。

プログラミングを6年続けてきて、プログラミングは自分一人で完結できるものではない、ということは痛いほど分かっています。"スタックオーバーフロー"だけではどうしようもないことも、中にはあります。 特に、新しい技術や言語に挑戦しようとする時は、難関が数多くあります。JavaとPHPは違いますし、スマホアプリが作れるからと言ってPythonができるとは限りません。多くの場合、多くの障壁に立ち塞がることでしょう。

実際、僕も多くのプログラミングをしている友人から、あらゆる相談を受けます。既存の回答や僕の知識から、最適な答えを返してあげられることもありますが、答えられないことや上手く説明できないことも多くあります。
そのような場合、僕が彼らに勧めているのが、『TechAcademy [テックアカデミー]』です。

同サービスは短期間から登録できるオンライン完結のプログラミングスクールで、他社と比較しても、そのコストパフォマンスは圧倒的です。
例えば、A社は148,000円〜のところ、同サービスは99,000円〜でコースが受講できます。( ※はじめてのプログラミングコース4週間の料金 )
また、一言に現役のプロと言っても、エンジニア歴20年以上、プログラム歴35年以上といった、まさにプロ中のプロの方たちが対応してくれるのも、『techacademy』の魅力の一つ。

国内外どこからでもチャット相談が可能で、毎日8時間、1週間あたり57時間の間、メンターが常時待機しています。
受講生限定の転職サポートで、コース受講終了後、企業やコンサルタントからスカウトが届く"TechAcademyキャリア"も、ぜひ活用したいところです。

  • オリジナルアプリをAppStoreにリリースするまで徹底サポート「iPhoneアプリコース」
  • 職業を問わず身につけたい、教養としてのプログラミングが学べる「はじめてのプログラミングコース」
  • 仮想通貨を支えるブロックチェーン技術の仕組みを学べる「ブロックチェーンコース」
  • Pythonと機械学習が学べる「Pythonコース」

『techacademy』では、上記コースをはじめとした、数多くの特化したコースが受講受付中です。プログラミングの進捗に真剣に悩んでいる方は、ぜひご活用ください。

TechAcademy [テックアカデミー]

さて、おまたせしました。

今回の記事は『autohotkeyをWSL Bashから引数でフレキシブルなコーディングを可能にする実装をしてみた』です。この記事が役に立った、と思ったらぜひ、コメントまたはTwitterやLINEでシェアしてくださいね。


https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_5ea9f51f-e3b6-496c-81af-89bb166e0c46.gif

autohotkeyでは俗に言うシェルにおいてのstdout、標準出力がないため、例えばpythonやrubyのように、bashスクリプト上での値をautohotkeyに渡してautohotkeyで処理された値を標準出力として受け取りバイプして…といったことができません。


僕もそうですが、フリーのプログラマの仕事内容は様々です。ソフトウェアを受注製作することもあれば、企業ホームページを作ることもあるでしょう。
どういったビジネスを展開するにせよ、事業を成功させるには、正しいマーケティングを行うことは必須事項です。

ミツモア』は、Googleのリスティング広告やマーケティング広告管理に煩わされることなく、狙った顧客を獲得できる、マーケティングプラットフォームです。
僕のプログラマの友人がいるのですが、彼にも『ミツモア』を紹介し、彼は現在、成功したプログラマの一人です。
どうしても疎かになってしまいがちなマーケティングですが、『ミツモア』を上手く活用し、新たな新規顧客を獲得していきたいところですね。

ミツモア

OutputDebug

OutputDebugといういかにもなメソッドがあるのですが、こちらはもちろん試しているのですが、できませんでした。
どうやら、専用のエディタ、統合開発環境ソフトウェアでないと出力されないみたいです。意味ないね。

OutputDebug – Syntax & Usage | AutoHotkey

autohotkey print – Google Search

OutputDebug – Google Search

[Resolved] Print to Console – AutoHotkey Community

ファイルを使う

で、解決策をとりあえず見つけました。

ファイル – ファイルxと呼称 – に一時的に標準出力したいデータをFileAppendで出力して、bashでファイルxをcatすれば、実質stdoutが取得できることになります。

以下はbash上からautohotkey経由で、現在のアクティブウィンドウがatom.exeであればtrueを返し、それ以外であればfalseを返すスクリプトです。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_ad669195-818f-450a-8b6a-147cc471e07f.gif


export AHKPRINT_STDOUT_FILE="/mnt/c/data/ahkprint.txt" export AHKPRINT_STDOUT_IDENTIFIER="var" ahkprint(){ : <<<' e.g. ahkprint ' # tmpdird : check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error [[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && { touch "${AHKPRINT_STDOUT_FILE}" || { printf "${red}E: Couldn't make the file." ; return 1 ; } } : make null the file > "${AHKPRINT_STDOUT_FILE}" cat << EOT > /mnt/c/_tmp/tmp.ahk WinGet, ${AHKPRINT_STDOUT_IDENTIFIER}, ProcessName, A FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" ) EOT psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk ) cat "${AHKPRINT_STDOUT_FILE}" }

stdin(標準入力)をautohotkeyに渡す

では次のステップとして、autohotkeyにbashからstdin標準入力を渡してみます。

以下スクリプトがその改良版です。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_35e715ad-4e19-445c-90e4-0810a64a7bde.gif


ahkprint(){ : <<<' e.g. ahkprint ' # tmpdird : If a argment defined use it else if stdin defined use it else make error [[ -z "${1}" ]] && stdin="$(</dev/stdin)" [[ ! -z "${1}" ]] && { value="${1}" } || { [[ ! -z "${stdin}" ]] && { value="${stdin}" } || { printf "${red}No data to store to the value. at least you'd specify argment(s) or stdin." ; return 1 ; } } : check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error [[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && { touch "${AHKPRINT_STDOUT_FILE}" || { printf "${red}E: Couldn't make the file." ; return 1 ; } } : make null the file > "${AHKPRINT_STDOUT_FILE}" cat << EOT > /mnt/c/_tmp/tmp.ahk WinGet, activeWinproc, ProcessName, A WinActivate, ahk_exe ${value} winActivateErrorLevel=%ErrorLevel% WinWaitActive, ahk_exe ${value} ${AHKPRINT_STDOUT_IDENTIFIER} = % activeWinproc . " " . winActivateErrorLevel FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" ) EOT psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk ) : パイプ処理の場合に動かない。 ahkのファイル書き込み処理が終わる前にこちらが動いてしまっているものだと思われる # cat "${AHKPRINT_STDOUT_FILE}" : 上記の対策 : 数秒間ファイル書き込みがされるかどうかを検証。ファイル書き込みがされればそれをcatしてループを終了し、数秒間が過ぎた場合は変数およびファイルが空であるとしてループを終了する tmpdate=$(date +"%s") while [[ "$( echo $(( $( date +"%s" ) - ${tmpdate} )) )" -lt 3 ]] ; do [[ ! -z "$( cat "${AHKPRINT_STDOUT_FILE}" )" ]] && { cat "${AHKPRINT_STDOUT_FILE}" ; break ; } sleep 0.1 done # echo "hogehoge" }

汎用性を高める

最後に仕上げとして、任意のautohotkeyスクリプトで簡単に実装できるようにします。

すこしコードを変えたので使い勝手が上記のそれと変わりますが、気に入らなければ自分でコードいじってみてください


ahkprint(){ : <<<' e.g. ahkprint ' # tmpdird stdin="$(</dev/stdin)" : check AHKPRINT_STDOUT_FILE file and path/dir exist then handling error [[ ! -f "${AHKPRINT_STDOUT_FILE}" ]] && { touch "${AHKPRINT_STDOUT_FILE}" || { printf "${red}E: Couldn't make the file." ; return 1 ; } } : make null the file > "${AHKPRINT_STDOUT_FILE}" cat << EOT > /mnt/c/_tmp/tmp.ahk $( eval "cat << EOT $( echo "${stdin}" ) EOT" ) FileAppend , %${AHKPRINT_STDOUT_IDENTIFIER}% , $( wslpathr "${AHKPRINT_STDOUT_FILE}" ) EOT psl ahk $( wslpathr /mnt/c/_tmp/tmp.ahk ) : パイプ処理の場合に動かない。 ahkのファイル書き込み処理が終わる前にこちらが動いてしまっているものだと思われる # cat "${AHKPRINT_STDOUT_FILE}" : 上記の対策 : 数秒間ファイル書き込みがされるかどうかを検証。ファイル書き込みがされればそれをcatしてループを終了し、数秒間が過ぎた場合は変数およびファイルが空であるとしてループを終了する tmpdate=$(date +"%s") while [[ "$( echo $(( $( date +"%s" ) - ${tmpdate} )) )" -lt 3 ]] ; do [[ ! -z "$( cat "${AHKPRINT_STDOUT_FILE}" )" ]] && { cat "${AHKPRINT_STDOUT_FILE}" ; break ; } sleep 0.1 done }

軽くまとめると、

  • AHKPRINT_STDOUT_FILE定数にはこの関数で使用するstdoutの値を一時的に置いておくファイルのパスを指定します
  • AHKPRINT_STDOUT_IDENTIFIER定数にはstdoutとして標準出力するautohotkey上の変数名を指定します。(デフォルト: var)
  • stdin、標準入力がautohotkeyのスクリプトコードそれ自体になります。それに加え、そのコードの内部にはbashの引数、変数を埋め込むことができます。(以下の様なことも可能)
  • 今言ったように変数的な意味合いでは、bash上の引数と変数をそれぞれ使うことができます。
  • stdout、標準出力したいデータは、autohotkeyスクリプト上でvar変数( またはAHKPRINT_STDOUT_IDENTIFIERの値、または${AHKPRINT_STDOUT_IDENTIFIER} )に格納します。

e.g.

[autohotkeyスクリプトを生成するコード] | ahkprint
or
ahkprint <<< "echo [autohotkeyスクリプト]"

(引数の代わりに変数を使う場合)


value=typora.exe ahkprint <<< "$(cat <<'EOT' WinGet, activeWinproc, ProcessName, A WinActivate, ahk_exe ${value} winActivateErrorLevel=%ErrorLevel% WinWaitActive, ahk_exe ${value} var = % activeWinproc . " " . winActivateErrorLevel EOT )"

さて、上記コードをもとにして、以下のようなフレキシブルなコードで上記と同様のことが実装できます。


ahkprint "typora.exe" <<< "$(cat <<'EOT' WinGet, activeWinproc, ProcessName, A WinActivate, ahk_exe ${1} winActivateErrorLevel=%ErrorLevel% WinWaitActive, ahk_exe ${1} var = % activeWinproc . " " . winActivateErrorLevel EOT )"

以下に同じ理屈で量産した実用例を置いておきます。

現在のアクティブウィンドウを取得

getActiveWindowName(){

ahkprint ${@} <<< "WinGet, var, ProcessName, A"

}

使用例

[[ ! "$( getActiveWindowName )" == atom.exe ]] && { : アクティブウィンドウがatom.exeじゃないときにしたい処理here ; }

マウス座標を取得


getMousePos(){ : e.g. getMousePos : e.g. getMousePos Relative ahkprint ${1:-Screen} ${@:2} <<< "$( cat << 'EOT' CoordMode, Mouse, ${1} MouseGetPos, posX, posY var = % posX . " " . posY EOT )" }

使用例

$  getMousePos Relative
998  510
$  getMousePos
991  923
$

ミュートならミュート解除

unmute(){

  : e.g. unmute


ahkprint ${@} <<< "$( cat << 'EOT'

;ミュートならミュート解除
SoundGet, MuteState, Master, Mute

if ErrorLevel
{
MsgBox, %ErrorLevel%
Return
}

prevMuteState = %MuteState%

if MuteState=On
{
MuteState=1
}
if MuteState=1
{
Send, {Volume_Mute}
}

SoundGet, currentMuteState, Master, Mute

var = % prevMuteState . "  " . currentMuteState

EOT
)"

}

使用例


$ unmute Off Off $ unmute On Off $

音量を取得

getVolume(){

  : e.g. getVolume

ahkprint ${@} <<< "$( cat << 'EOT'
SoundGet, var
EOT
)"

}

使用例

$ getVolume
6.999999

独自定義の関数とエイリアス

$ psl which ahk
C:\Program Files\AutoHotkey\AutoHotkeyU64.exe
$ psl which ahk^C
$ type psl wslpathr
psl is aliased to `/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe'
wslpathr is a function
wslpathr ()
{
    wslpath -w $(realpath $1)
}

まとめ

一応bashやその他プログラミング言語の外部コマンドから任意のブログラマブルなautohotkeyスクリプトを実行して結果を受け取る、というところまで実装してみました。

どこか抜けているところやもっといい方法などあればコメントなどで教えてくれたら嬉しいです。


JavaとかC#とかわかればいいんですけどね。なんかもう、ああいう言語はやりたくないw
ファイルの数が多くてね。重い開発用エディタ使わないといけないとかっていうのも好きになれない。( 64gRAMが言うなよって感じですね )

まぁ使い始めてしまえば慣れるんでしょうがね…。教えてくれる人いないしね…。まぁ、CはないとしてもJavaはそのうち機会があればやりたいとは思ってます。でもautohotkeyの手軽さはやっぱりいいですよね。
でもまぁとりあえずbash最高。

psl はじめてのBash。関数やエイリアスを読み込むまで [初心者向け]

alias psl='/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe'

ahk はじめてのPowershell。関数やエイリアスを読み込むまで [初心者向け]

Set-Alias ahk "C:\Program Files\AutoHotkey\AutoHotkeyU64.exe"

WSL WSL bash on ubuntu on windows インストール手順
WSL(Windows Subsystem for Linux)を初期から使っている僕がLinuxやプログラミングの初心者向けにWSLのメリットを解説してみる

2020年の東京五輪を間近に控え、来日外国人の数は年々増加しています。ただでさえ、あらゆる職種で"英語力"が求められる時代ですが、その中でも特筆してプログラマ、システムエンジニアには、英語力は必須であると言われています。

僕は現在、英検1級に着手し、英語力が一定水準に達した今でも、日々新しい表現や単語を学んでいます。しかし僕も最初から英語が出来たわけではありません。中学生の頃の英語の成績は、学年でほぼビリでしたし、そもそも英語なんて必要ない(若者の常套句ですね)、今後一生やることはない、と思っていたくらいです。

確かに、英語を使わずとも年収600万以上の仕事に就くことは出来ますし、生活する上で困ることもないでしょう。しかしそれは、英語を知っている世界を知らないからでしかありません。
英語に興味関心がない多くの方は、こういうことを言うと反発するのですが、プログラミング経験者の皆さんなら、そうでもないのではないでしょうか。

プログラミングをやっていて、英語が出来たらなぁと思ったこと、あるのではないでしょうか。僕が英語を始めた動機は他にありますが、一度、二度挫折した英語学習を再開する動機となったのは、紛れもなく、"プログラミング"でした。プログラミングを続けるには、英語の壁を超える必要がある、と幾度となく痛感しました。

  • エラー文章をGoogle検索せずとも理解できる
  • ソースコードに日本語が含まれる場合に起こる特有のエラーを回避できる
  • スタックオーバーフローの回答が理解できる
  • スタックオーバーフローに質問を投稿し、良質で的を射た回答を得ることができる
  • 翻訳されていないドキュメントやリファレンスを理解できる
  • 適切なメソッド名やファイル名をスムーズに定義できる
  • 需要が高く報酬の良い海外で仕事が探せる、または海外のクライアントを相手にできる

上記をはじめとした、プログラミングにおいて英語ができることのメリットは数多く存在します。
英語学習の必要性に疑問を持っていた方も、上記の一覧を見て、何か思うことがあるかもしれません。しかし、英語を学習する意義を見つけたあと、間違っていけないのが、その学習方法です。

英語学習方法には効率的、非効率的、意味がないなど、様々な方法が乱立しています。中には悪徳なものもあり、注意が必要です。
英語学習に回り道やチートはありませんが、効率的でない学習方法を避けて学習を進めていくことは、1年後、5年後の自分の英語力に取り返しのつかない差が開いてしまうことを未然に防ぎます。

そして、僕が一番信頼を置いているのが、『スタディサプリ ENGLISH』です。『スタディサプリ ENGLISH』はこれまで様々な英語に関する相談をしてきた友人への、最も勧める頻度の高かったサービスです。

留学が間近で…、ワーキングホリデーに行ってみたくて…、やっぱり英語をまた始めようと思って…、社内公用語対策で…、英会話教室に通おうと思ってて…などなど、僕への相談は様々ですが、これら全ての方に、『スタディサプリ ENGLISH』は自信を持っておすすめできます。

スタディサプリ ENGLISH

さて、最後までお読み頂きありがとうございました。この記事が役に立った、と思ったらぜひ、コメントまたはTwitterやLINEでシェアしてくださいね。

僕は個人事業として、プログラミング6年、1日14時間パソコン業務をこなしてきました。現在もウェブサイト開発やサポート、ソフトウェア制作、レビューなどライティングをはじめとしたお仕事を承っております。気になったらぜひ、メールにてご連絡ください。いつでもお待ちしております。

現在承っているお仕事の一覧
お問い合わせ

小山はるや(こやまはるや) 東京生まれ。プログラマー。現役大学生。ウェブサイト制作の傍らメディア運営を行い、2017年に開設されたITブログ『yuipro』(https://yuis-programming.com)は2019年に月間アクセス数1万を超える。 これまで80を超えるウェブサイトを制作、小山氏自ら運営するウェブサイトは8つに上り、うち2つが月当たり数万のアクティブビジターを獲得している。


Close Menu