Help us understand the problem. What is going on with this article?

コマンドプロンプト・プログラミング 宴

More than 1 year has passed since last update.

目次

Lua

サクッと動いて、すぐ泥沼のコマンドプロンプト。
脳トレに良いのかも微妙なので Lua を導入する。

プログラミングを覚えても#私のおすすめ

nkf

下記 Vector より nkfwin.zip をダウンロード。

nkf.exe nkf32.dll Windows用の詳細情報 : Vector ソフトを探す!

ポータビリティ

USB メモリなどにユーティリティ群を入れて、
外出先の Win でも使えるようにしてみる。

まず、任意の作業ディレクトリを作るが、
このディレクトリは後で USB メモリにそのままコピーして
出先で使用するための環境となる。

私は今回、usb というディレクトリ(フォルダ)を作り、
usb\bin に以下のファイルをコピーした。

  • lua.exe
  • lua53.dll
  • luac.exe
  • nkf.exe:nkfwin\vc2005\win32(~)Windows-31J\nkf32.exe

コマンドプロンプト起動バッチ

USB メモリの中に boot.cmd があるとする。
これはコマンドプロンプトを起動する。
私は USB メモリから直接これで起動するかもしれないし、
出先の任意パスに環境をコピーしてから起動するかもしれない。

起動したコマンドプロンプトではこうなって欲しい。

cmd.exe
> lua -v
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio

> nkf -v
Network Kanji Filter Version 2.1.4 (2015-12-12)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2015, The nkf Project.

そのためには boot.cmd は環境変数 Path を設定する必要がある。

起動パスを得る

C:\usb に下記のバッチがあるとすると、

currents.cmd
@echo off
echo %0
echo %~n0
echo %~d0%
echo %~p0%
echo %~dp0%
echo %~dpn0%
exit /b
cmd.exe
> currents.cmd
currents.cmd
currents
C:
\usb\
C:\usb\
C:\usb\currents

欲しいものに近いのは %~dp0C:\usb\ だ。
この結果が C:\usb であればスッキリする。

pwd.cmd
@echo off
setLocal
  set pwd=%~dp0
  set pwd=%pwd:~0,-1%
  echo %pwd%
endLocal
exit /b
cmd.exe
> pwd
C:\usb

%pwd:~0,-1% の意味は「先頭の文字から最後を除いたものまで」である。
つまり「最後の一文字は不要」である。

パスを通す

boot.cmd
@echo off
setLocal
  set boot_path=%~dp0
  set boot_path=%boot_path:~0,-1%
  set path=%boot_path%\bin;%path%
  cmd.exe
endLocal
exit /b

set path=%boot_path%\bin;%path%
set path=%path%;%boot_path%\bin

%boot_path%\bin を優先的に探索してほしいなら ① で書く。

このコマンドプロンプト上で Ctrl+C を数回押した後 exit すると、

cmd_exit.png

こうなる。
そう、まだ boot.cmd は生きていた。

boot.cmd
@echo off
setLocal
  set boot_path=%~dp0
  set boot_path=%boot_path:~0,-1%
  set path=%boot_path%\bin;%path%
  start /b cmd.exe
endLocal
exit /b

start で別プロセスとして起動する。
オプション /b で新規ウィンドウを作らせないようにできる。
この後 boot.cmdexit /b で終了する。

cmd_result.png

setLocal 内の環境変数も継承されている。

Lua 版ユーティリティ

下記 conc は参考として書いた。

words

words.lua
if #arg == 0 then os.exit() end

for _, word in ipairs(arg) do
  print(word)
end
cmd.exe
> lua words.lua one=1, two=2, three=3;
one=1,
two=2,
three=3;

> lua words.lua   Hello   World!   "   yeah!"
Hello
World!
   yeah!

> lua words.lua はろー わーるど!
はろー わーるど!

なぜ日本語(CP932)を出力でき、全角空白で分割されないのか?
Lua の文字列は単なるバイト列(バイナリ)だからである。

conc

conc.lua
local buf = ""

for line in io.lines() do
  if buf == "" then
    buf = line
  else
    buf = buf.." "..line
  end
end

print(buf)
cmd.exe
> lua words.lua 1 2 3 4 5 | lua conc.lua
1 2 3 4 5

puts

puts.lua
local buf = ""

for _, param in ipairs(arg) do
  if buf == "" then
    buf = param
  else
    buf = buf.." "..param
  end
end

print(buf)
cmd.exe
> lua puts.lua   Hello   World!   "   yeah!"
Hello World!   yeah!

エイリアス

コマンドプロンプトの場合、エイリアスといえば doskey だが、
このエイリアスはパイプを受け取れないという問題がある。
パイプを考慮するならばバッチでラップするしかない。

usb\binputs.lua があるとして、そこに下記のラッパーも置く。

puts.cmd
@echo off
lua.exe %~dpn0.lua %*
exit /b
cmd.exe
> puts Hello World! "yeah!"
Hello World! yeah!

この puts.cmd はラッパーのテンプレートとして使える。
ファイル名を変えさえすればいい。

宴のあと

もうここから先は自分と Lua の能力次第である。
最も気にすべきところは Lua には UTF-8 ライブラリはあるが、
CP932 は自力で何とかしなければならないことだ。
その手抜きのために nkf を使う。

もし二次会があるとすれば Lua と nkf をどう結びつけるかになるだろう。
最も単純なのはパイプで渡す方法だ。
もう少し気張るとすると os.execute io.popen を使うだろう。
しかし io.popen は Win にはちゃんと対応していない。

なんとも面倒なのである。
それでも私は PowerShell は使わない。
あれを覚えるぐらいならばコンパイラ言語を覚えた方がマシだ。

と不平をもらし会計を済ませることとした。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした