ゲームパッド/ジョイスティックで Raspberry Pi を操作 (2015/02/28)
動作中の Raspberry Pi (または Pi2) にゲームパッド/ジョイスティックを接続して、「コナミコマンド」 (上上下下左右左右BA) で Raspberry Pi シャットダウンできるようにするプログラム (jsCommand.lua|) を作成しました。 ネットワークもディスプレイもキーボードも不要 (ログインも不要) です。 ゲームパッドを接続すると jsCommand.lua が自動起動するようにインストールしておくと、シャットダウンの実行以外にもいろいろなシステム管理用コマンドを実行して、システムコンソールに結果を表示することができます。
Raspbiann Jessie の systemd に対応した新しいバージョンを公開しました。 (2017/04/05)
jscommand.tar.gz (3,510 byte) には次のファイルが含まれています。すべてテキストファイルです。
$ tar ztvvf jscommand.tar.gz drwxr-xr-x jun/jun 0 2015-02-28 20:39 jscommand/ -rwxr-xr-x jun/jun 67 2015-02-28 20:39 jscommand/jscom.sh -rwxr-xr-x jun/jun 9397 2015-02-28 13:45 jscommand/jsCommand.lua -rwxr-xr-x jun/jun 142 2015-02-28 13:48 jscommand/install.sh -rw-r--r-- jun/jun 82 2015-02-28 00:16 jscommand/70-jscom.rules -rw-r--r-- jun/jun 1202 2015-02-28 13:49 jscommand/README
前に GPIO にスイッチと抵抗で簡単な回路を作ってシャットダウンする方法 を試しましたが、今回の方法はもっと簡単に実現できます。 ゲームパッド/ジョイスティックは振動機能のついたアナログジョイスティックは消費電力が大きいため、 ファミコン風 や スーファミ風 の小型のものが向いていると思います。
機能
ゲームコントローラのボタンを押す順序は次の文字で表しています。 jsCommand.lua 内の記述を変更すると、ボタン操作順も実行されるコマンドも好きな様に変更できます。
文字 | 対応するボタン |
---|---|
A | [A] ボタン |
B | [B] ボタン |
X | [X] ボタン |
Y | [Y] ボタン |
L | [L] ボタン |
R | [R] ボタン |
S | [START] ボタン |
E | [SELECT] ボタン |
u | 十字キーの↑ |
d | 十字キーの↓ |
l | 十字キーの← |
r | 十字キーの→ |
ゲームコントローラから実行できるシステム管理用のコマンドです。 jsCommand.lua を編集すれば、自由にコマンドを変更、追加できます。デフォルトではボタン数の少ないファミコン用のコントローラでも操作できるようになっています。システム管理用のコマンドはシャットダウンとリブートを除いて、システム情報を表示するだけのコマンドです。安心して実行できます。
ボタンを押す間隔が1秒以上離れると押したボタンはクリアされ、また最初からになります。 押したボタンがよくわからなくなったら、1秒待てば最初から入力できます。
ボタン操作順 | 実行されるコマンド |
---|---|
BABABA | この表の表示 |
ESESESES | jsCommandを終了 |
uuddlrlrBA | /sbin/shutdown -h now シャットダウン |
uuddlrlrES | /sbin/reboot リブート |
SESE | /bin/sync |
dddd | /bin/cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 周波数表示 |
uuuu | /bin/cat /sys/class/thermal/thermal_zone0/temp CPU温度表示 |
llrr | /sbin/ifconfig -a |
rrrr | /bin/netstat -a |
lrlr | /usr/bin/uptime |
llll | /usr/bin/vmstat -s |
BBBB | /bin/date -R |
EEEE | /bin/ps aux |
SSSS | /usr/bin/pstree -A |
RRRR | /usr/bin/who -a |
rrrl | /usr/bin/who -a |
LLLL | /sbin/lsmod |
lllr | /sbin/lsmod |
uldr | /bin/uname -a |
dudu | /bin/df -kT |
Eddd | /usr/bin/env |
インストール方法
まず jscommand.tar.gz (3KB) をダウンロードして下さい。コマンドラインからは 次のコマンドでダウンロードできます。
$ curl -O https://www.mztn.org/rpi/jscommand.tar.gz
ダウンロードしたデレクトリに移動 (cd ダウンロードしたデレクトリ) した後、以下のコマンドを実行して下さい。 付属の install.sh は jsCommand.lua を /usr/local/bin にコピーし、/etc/udev/rules.d に 70-jscom.rules をコピーします。 その後、service udev reload を実行して 70-jscom.rules の設定を有効にします。 /usr/local/bin にコピーしていますが、/usr/local/ 以下はシステムの管理範囲外(aptコマンドの対象外)ですから大丈夫です。
$ tar zxf jscommand.tar.gz $ cd jscommand $ sudo ./install.sh
USBの ゲームコントローラを接続すると自動的に jsCommand.lua が実行されます。 ディスプレイが接続されている場合は、コマンドの実行結果がシステムコンソールに表示されます。何も接続されていない場合でも 「コナミコマンド」 (上上下下左右左右BA) でシャットダウンさせることができます。リブートは 上上下下左右左右 [Select] [Start] です。
使い方
上に書いたように 「sudo ./install.sh」を実行しておけば、ゲームパッド/ジョイスティックをUSBポートに接続するだけでログインもすることなく、コマンドを実行できるようになります。自動実行されている場合でも「ESESESES」と SELECTボタンとSTARTボタンを交互に4回ずつ押すと実行している jsCommand.lua は終了します。デスクトップが表示 (Xが起動) されている場合はキーボードの [Ctrl] と [Alt] と [F1] を同時に押すとシステムコンソール(黒い画面)が表示されて、jsCommand.lua の実行結果が表示されます。キーボードの [Ctrl] と [Alt] と [F7] を同時に押すとデスクトップ表示に戻ります。
ヘルプ表示
実行可能なコマンドとボタンの操作順を表示するには次のようにコマンドラインで実行して下さい。表示後すぐに終了します。
$ jsCommand.lua -h
「sudo ./install.sh」を実行して/usr/local/binにインストールしていない場合は、jscommandディレクトリに移って、ピリオドとスラッシュを前につけて実行して下さい。
$ cd jscommand $ ./jsCommand.lua -h
システムコンソールに表示
Raspberry Pi 起動時にゲームパッド/ジョイスティックが接続されている場合は、jsCommand.lua は自動で起動するようにしていません。次のコマンドで起動して下さい。コマンドの出力はシステムコンソールに表示されます。
$ sudo jsCommand.lua -c &
標準出力に表示
コマンドラインから起動すると、そのまま jsCommand.lua の出力が表示されます。sudo を付けないで実行すると、シャットダウンとリブートはできません。
$ jsCommand.lua
ボタンの入力テスト
ゲームパッドのボタンの表示と jsCommand.lua の認識するボタンとの対応をチェックするには -d オプションを付けて実行します。 押したボタンが表示されるようになります。
$ jsCommand.lua -d
ボタンを押す間隔が1秒以上離れると押したボタンはクリアされ、また最初からになりますが、そのタイムングも試してみてください。
jun@raspberrypi ~/jscommand $ jsCommand.lua -d
Name: USB,2-axis 8-button gamepad
Ver.: 131328
No. of Axes : 2
No. of Buttons : 8
help : BABABA
AA
AAA
AAAA
X
XXY
XXYY
E
ES
ESES
ESESr
ESESrd
ESESrdul
ESESrdulr
ESESrdulrd
ESESrdulrdES
ESESrdulrdES
ESESrdulrdESX
ESESrdulrdESXR
ESESrdulrdESXRL
B
ES
ESE
ESESE
ESESESE
jun@raspberrypi ~/jscommand $
最後は「ESESESES」と入力していますが、最後の「S」が表示される前に終了しています。
解説
以下は jscommand.tar.gz に含まれているファイルの解説です。jsCommand.lua をそのまま使用するだけの場合には特に必要ありません。仕組みを知りたい方はどうぞ。
install.sh
インストール用のシェルスクリプトです。jsCommand.lua と jscom.sh を /usr/local/bin にコピーし、70-jscom.rules を /etc/udev/rules.d にコピーします。sudo を付けて実行して下さい。
#!/bin/sh cp -a ./jsCommand.lua /usr/local/bin cp -a ./jscom.sh /usr/local/bin cp -a ./70-jscom.rules /etc/udev/rules.d/ service udev reload
70-jscom.rules
OS が起動している最中にゲームパッド/ジョイスティックをUSBに接続しても jsCommand.lua が自動で実行されるようにする設定ファイルです。 udevd デーモンが起動する時に読み込みます。 jsCommand.lua が動作していなくても、ゲームパッド/ジョイスティックを接続するだけでシャットダウン等のコマンドを実行できます。
ACTION=="add", SUBSYSTEMS=="usb", KERNEL=="js*",\ RUN:="/usr/local/bin/jscom.sh"
jscom.sh
jsCommand.lua をバックグラウンドで実行するシェルスクリプトです。udevd デーモンが直接 jsCommand.lua を実行すると 30秒以内に終了しないため、タイムアウトで kill されます。 そこで udevd デーモンには jscom.sh を起動させ、その中から jsCommand.lua をバックグラウンドで実行することで jscom.sh を終了させます。 udevd デーモンは jscom.sh がすぐに終了するため、 jsCommand.lua を kill することがなくなります。 結果として jsCommand.lua は実行を続けることができるようになります。jsCommand.lua がすでに起動している場合は、2重起動せず終了します。
#!/bin/sh killall jsCommand.lua /usr/local/bin/jsCommand.lua -c &
README
ほとんど内容がありませんが、英語の README です。
--------------------------------------------- jsCommand.lua 2015/02/28 Copyright (c) 2015 Jun Mizutani, released under the MIT open source license. --------------------------------------------- install: ------ tar zxf jscommand.tar.gz cd jscommand sudo ./install.sh usage: Connecting Joystick/Gamepad to USB, jsCommand.lua will run automatically. or # stdout jsCommand or # console output (/dev/console) jsCommand -c or # verbose mode jsCommand -d or # help jsCommand -h key sequence: ------------- [A] [B] [X] [Y] [L] [R] [Start] [sElect], up, down, left, right BABABA : help ESESESES : quit uuddlrlrBA : /sbin/shutdown -h now uuddlrlrES : /sbin/reboot SESE : /bin/sync dddd : /bin/cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq uuuu : /bin/cat /sys/class/thermal/thermal_zone0/temp llrr : /sbin/ifconfig -a rrrr : /bin/netstat -a lrlr : /usr/bin/uptime llll : /usr/bin/vmstat -s BBBB : /bin/date -R EEEE : /bin/ps aux SSSS : /usr/bin/pstree -A RRRR : /usr/bin/who -a rrrl : /usr/bin/who -a LLLL : /sbin/lsmod lllr : /sbin/lsmod uldr : /bin/uname -a dudu : /bin/df -kT Eddd : /usr/bin/env
jsCommand.lua
今回のゲームコントローラでコマンドを実行するための中心となるプログラムです。Lua という言語のJITコンパイラである luajit-2 用に書かれています。 luajit は Raspbian に最初から入っているため何もインストールする必要はありません。 また、jsCommand.lua は必要なすべての処理を含んでいるため、何にも依存すること無く動作します。
#!/usr/bin/luajit -- --------------------------------------------- -- jsCommand.lua 2015/02/28 -- Copyright (c) 2015 Jun Mizutani, -- released under the MIT open source license. -- --------------------------------------------- local ffi = require("ffi") local bit = require("bit") local bnot, bor, band = bit.bnot, bit.bor, bit.band ffi.cdef[[ struct js_event { unsigned int time; /* event timestamp in milliseconds */ short value; /* value */ char type; /* event type */ char number; /* axis/button number */ }; static const int F_SETFL = 4; int ioctl(int, unsigned long, ...); int open(const char* filename, int flags); int read(int fd, void *buf, unsigned int nbytes); int fcntl(int fd, int cmd, ...); int close(int fd); int poll(struct pollfd *fds, unsigned long nfds, int timeout); ]] local JS_EVENT_BUTTON = 0x1 local JS_EVENT_AXIS = 0x2 local JS_EVENT_INIT = 0x80 local JSIOCGVERSION = 0x80046a01 local JSIOCGAXES = 0x80016a11 local JSIOCGBUTTONS = 0x80016a12 local JSIOCGNAME = 0x80006a13 local EVENT_CLEAR_MSEC = 1000 local devices = {} local initialized = false function init() for i = 0, 7 do openJoystick(i) end if #devices > 0 then setDeviceInfo() initialized = true end return #devices end function open(device) local O_RDONLY = 0 local O_NONBLOCK = 0x800 local fd = ffi.C.open(device, O_RDONLY + O_NONBLOCK) return fd end function openJoystick(n) if (n >= 0) and (n <=7) then local fd = open("/dev/input/js" .. tonumber(n)) if fd >= 0 then local device = {} device.num = n device.fd = fd table.insert(devices, device) devices[n + 1].last_time = 0 devices[n + 1].event_list = {} devices[n + 1].eventStr = {} return fd else return -1 end else return -1 end end -- デバイス情報を取得して設定 function setDeviceInfo() local version = ffi.new("int[1]") local axes = ffi.new("unsigned char[1]") local buttons = ffi.new("unsigned char[1]") local name = ffi.new("char[128]") for i = 1, #devices do local fd = devices[i].fd ffi.C.ioctl(fd, JSIOCGVERSION, version) ffi.C.ioctl(fd, JSIOCGAXES, axes) ffi.C.ioctl(fd, JSIOCGBUTTONS, buttons) ffi.C.ioctl(fd, JSIOCGNAME + 128 * 0x10000, name) devices[i].version = version[0] devices[i].num_axes = axes[0] devices[i].num_buttons = buttons[0] devices[i].name = ffi.string(name) devices[i].axes = {} devices[i].buttons = {} for j = 1, axes[0] do table.insert(devices[i].axes, {type = 0, number = 0, value = 0, time = 0}) end for j = 1, buttons[0] do table.insert(devices[i].buttons, {type = 0, number = 0, value = 0, time = 0}) end end end -- 指定したデバイスのイベントを1つ取得 function readOneEvent(device) if (device < 1) or (device > #devices) then return nil -- invalid device end local fd = devices[device].fd local js = ffi.new("struct js_event[1]") local size = ffi.sizeof(js) -- イベントを1つ取得 local res = ffi.C.read(fd, js, size) -- 非ブロッキングモードの場合は何も読み出せない場合がある if res == size then local event = js[0] return event else return nil end end -- イベントを文字列として記録する function recordEventStr(device, event) local js = devices[device] local n = event.number if event.type == JS_EVENT_BUTTON then if n == 0 then table.insert(js.eventStr, "A") elseif n == 1 then table.insert(js.eventStr, "B") elseif n == 2 then table.insert(js.eventStr, "X") elseif n == 3 then table.insert(js.eventStr, "Y") elseif n == 4 then table.insert(js.eventStr, "L") elseif n == 5 then table.insert(js.eventStr, "R") elseif n == 6 then table.insert(js.eventStr, "E") elseif n == 7 then table.insert(js.eventStr, "S") end elseif event.type == JS_EVENT_AXIS then local v = event.value if n == 0 then if v > 0 then table.insert(js.eventStr, "r") elseif v < 0 then table.insert(js.eventStr, "l") end elseif n == 1 then if v > 0 then table.insert(js.eventStr, "d") elseif v < 0 then table.insert(js.eventStr, "u") end end end end function clearEventStr(device) devices[device].eventStr = {} end function getEventStr(device) return table.concat(devices[device].eventStr) end function readAllEvents(device) local event local numEvent = 0 local js = devices[device] repeat event = readOneEvent(device) if event ~= nil then numEvent = numEvent + 1 -- シーケンスは時間経過でリセットされる if (event.time - js.last_time) > EVENT_CLEAR_MSEC then clearEventStr(device) end local num = event.number + 1 if band(event.type, JS_EVENT_INIT) > 0 then -- 初期化イベントの場合は開始時間を記録 js.start = event.time; -- 初期化イベントフラグをマスク event.type = band(event.type, bnot(JS_EVENT_INIT)) -- イベントをタイプ毎に記録 if event.type == JS_EVENT_BUTTON then js.buttons[num].value = event.value js.buttons[num].time = event.time else js.axes[num].value = event.value js.axes[num].time = event.time end elseif event.type == JS_EVENT_BUTTON then local button = js.buttons[num] if event.value == 0 then -- ボタンを離したイベント button.longPush = event.time - button.time button.longRelease = 0 else -- ボタンを押したイベント button.longPush = 0 button.longRelease = event.time - button.time recordEventStr(device, event) end button.value = event.value button.time = event.time else -- 十字キーのイベント js.axes[num].value = event.value js.axes[num].time = event.time -- 十字キーを押した時にイベントを記録 if event.value ~= 0 then recordEventStr(device, event) end end -- このデバイスで最後に押した時間を記録 js.last_time = event.time end until event == nil return numEvent end function readAllDevices() for i = 1, #devices do readAllEvents(i) end end function exec(command) local f = io.popen(command .. " 2>&1", "r") if f ~= nil then local result = f:read('*a') -- read output f:close() return result else return "execute error" end end function initCommandList() commandList = { BABABA = "help" } end function addCommand(keys, command) commandList[keys] = command return #commandList end function listCommand(f) f:write("[A] [B] [X] [Y] [L] [R] [Start] [sElect], ") f:write("up, down, left, right\n") for key, command in pairs(commandList) do f:write(key .. " : " .. command .. "\n") end end function execCommand(numDevice, str, f) for key, command in pairs(commandList) do if str == key then if command == "quit" then os.exit() end if command == "help" then listCommand(f) clearEventStr(numDevice) else f:write("\nkey = ".. key .. ", command = " .. command .. "\n") local result = exec(command) if result ~= nil then f:write(result) end clearEventStr(numDevice) end end end end function checkCommand(numDevice, f) local numEvent = readAllEvents(numDevice) if numEvent > 0 then str = getEventStr(numDevice) execCommand(numDevice, str, f) return str end return nil end function getNoOfDevices() return #devices end -- device_num: 1..8 function getName(device_num) return devices[device_num].name end function getVersion(device_num) return devices[device_num].version end function getNoOfAxes(device_num) return devices[device_num].num_axes end function getNoOfButtons(device_num) return devices[device_num].num_buttons end function sleep(sec) ffi.C.poll(nil, 0, sec * 1000) end function printf(f, fmt, ...) f:write(string.format(fmt, ...)) end function deviceList(f) local num_device = getNoOfDevices() for i = 1, num_device do printf(f, "Name: %s\n", getName(i)) printf(f, "Ver.: %s\n", getVersion(i)) local num_axes = getNoOfAxes(i) printf(f, " No. of Axes : %d\n", num_axes) local num_buttons = getNoOfButtons(i) printf(f, " No. of Buttons : %d\n", num_buttons) end printf(f, "\nhelp : BABABA\n\n") end -- ------------- -- main -- ------------- local numOfDevices = init() local str local f if arg[1] == "-d" then DEBUG = true end if arg[1] == "-c" then CONSOLE = true end if CONSOLE then f = io.open("/dev/console", "w") else f = io.open("/dev/stdout", "w") end initCommandList() -- A, B, X, Y, L, R, Start, sElect, up, down, left, right addCommand("ESESESES", "quit") addCommand("uuddlrlrBA", "/sbin/shutdown -h now") addCommand("uuddlrlrES", "/sbin/reboot") addCommand("BBBB", "/bin/date -R") addCommand("SSSS", "/usr/bin/pstree -A") addCommand("SESE", "/bin/sync") addCommand("EEEE", "/bin/ps aux") addCommand("LLLL", "/sbin/lsmod") addCommand("lllr", "/sbin/lsmod") addCommand("RRRR", "/usr/bin/who -a") addCommand("rrrl", "/usr/bin/who -a") addCommand("rrrr", "/bin/netstat -a") addCommand("llrr", "/sbin/ifconfig -a") addCommand("llll", "/usr/bin/vmstat -s") addCommand("lrlr", "/usr/bin/uptime") addCommand("uuuu", "/bin/cat /sys/class/thermal/thermal_zone0/temp") addCommand("dddd", "/bin/cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq") addCommand("dudu", "/bin/df -kT") addCommand("uldr", "/bin/uname -a") addCommand("Eddd", "/usr/bin/env") -- if arg[1] == "-h" then listCommand(f) os.exit() end if numOfDevices > 0 then deviceList(f) while (true) do str = checkCommand(1, f) if DEBUG and str ~= nil then io.write(str.."\n") end sleep(0.5) end end
jsCommand.lua の解説
jsCommand.lua は起動すると、まず接続されているゲームパッド/ジョイスティックを調べます。 ゲームパッドのデバイスファイル(/dev/input/js?)は非ブロッキングモードでオープンしています。 8台までのゲームパッドを認識しますが、コマンドの入力には最初に認識したゲームパッドが使われます。
次にオプションの「-d」が指定されていたら、ゲームパッドのボタンを画面に表示するようになります。 オプションの「-c」が指定されている場合はシステムコンソールにコマンドの実行結果を表示します。 オプションは一つだけ指定できます。 「-h」が指定された場合は、実行するコマンドとゲームパッドのボタンを押す順番を表示します。
コントローラのボタンを押す順番と実行するコマンドを addCommand で登録しています。addCommand には引数として2つの文字列を渡します。最初の文字列はゲームパッドのボタンの並びです。次の文字列は実行するコマンドを渡します。ゲームパッドのボタンの並びは短く一致するものが優先されるため、例えば「A」にコマンドを割り当てると最初の 「A」で一致してしまうため、「ABAB」には一致することはなくなります。
実行の中心となるのはコードの最後尾の6行にある、メインルーチンのループです。
while (true) do str = checkCommand(1, f) if DEBUG and str ~= nil then io.write(str.."\n") end sleep(0.5) end
その中の checkCommand です。checkCommand から呼び出される readAllEvents が /dev/input/js0 からイベントを読み込み、ボタンの種類、押す/離すイベントのタイミングから入力されるコマンドを収集しています。 その後、execCommand で addCommand で登録されたコマンドをチェックして、一致したら実行しています。
実行例
$ ./jsCommand.lua Name: USB,2-axis 8-button gamepad Ver.: 131328 No. of Axes : 2 No. of Buttons : 8 help : BABABA [A] [B] [X] [Y] [L] [R] [Start] [sElect], up, down, left, right rrrr : /bin/netstat -a lrlr : /usr/bin/uptime llll : /usr/bin/vmstat -s BBBB : /bin/date -R RRRR : /usr/bin/who -a uuddlrlrES : /sbin/reboot LLLL : /sbin/lsmod EEEE : /bin/ps aux dudu : /bin/df -kT SSSS : /usr/bin/pstree -A uldr : /bin/uname -a dddd : /bin/cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq lllr : /sbin/lsmod ESESESES : quit uuuu : /bin/cat /sys/class/thermal/thermal_zone0/temp uuddlrlrBA : /sbin/shutdown -h now Eddd : /usr/bin/env rrrl : /usr/bin/who -a BABABA : help SESE : /bin/sync llrr : /sbin/ifconfig -a key = ESAB, command = /sbin/ifconfig -a eth0 Link encap:Ethernet HWaddr b8:27:eb:09:bf:1e inet addr:172.18.21.10 Bcast:172.18.21.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:54770 errors:0 dropped:0 overruns:0 frame:0 TX packets:27408 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5886361 (5.6 MiB) TX bytes:6527087 (6.2 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:62 errors:0 dropped:0 overruns:0 frame:0 TX packets:62 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3804 (3.7 KiB) TX bytes:3804 (3.7 KiB) key = uuuu, command = /bin/cat /sys/class/thermal/thermal_zone0/temp 44388 key = dddd, command = /bin/cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 600000 key = lrlr, command = /usr/bin/uptime 00:26:04 up 5:29, 1 user, load average: 0.05, 0.03, 0.05 key = BBBB, command = /bin/date -R Sat, 28 Feb 2015 00:26:12 +0900 key = dudu, command = /bin/df -kT Filesystem Type 1K-blocks Used Available Use% Mounted on rootfs rootfs 14984668 3803572 10522012 27% / /dev/root ext4 14984668 3803572 10522012 27% / devtmpfs devtmpfs 437856 0 437856 0% /dev tmpfs tmpfs 88432 916 87516 2% /run tmpfs tmpfs 5120 0 5120 0% /run/lock tmpfs tmpfs 176860 0 176860 0% /run/shm /dev/mmcblk0p1 vfat 57288 14736 42552 26% /boot key = SYSY, command = /bin/sync key = RRRR, command = /usr/bin/who -a 2015-02-27 01:14 61 id=si term=0 exit=0 system boot 2015-02-27 01:14 run-level 2 2015-02-27 01:14 last=S 2015-02-27 01:14 1782 id=l2 term=0 exit=0 LOGIN tty1 2015-02-27 01:14 2197 id=1 LOGIN tty2 2015-02-27 01:14 2198 id=2 LOGIN tty6 2015-02-27 01:14 2204 id=6 LOGIN ttyAMA0 2015-02-27 01:14 2205 id=T0 LOGIN tty4 2015-02-27 01:14 2202 id=4 LOGIN tty3 2015-02-27 01:14 2201 id=3 LOGIN tty5 2015-02-27 01:14 2203 id=5 jun + pts/0 2015-02-27 20:32 00:02 2286 (172.18.21.12) key = LLLL, command = /sbin/lsmod Module Size Used by binfmt_misc 6370 1 snd_bcm2835 18850 0 snd_pcm 75388 1 snd_bcm2835 snd_seq 53078 0 snd_seq_device 5628 1 snd_seq snd_timer 17784 2 snd_pcm,snd_seq snd 51667 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device joydev 8903 1 evdev 9950 4 uio_pdrv_genirq 2958 0 uio 8119 1 uio_pdrv_genirq key = uldr, command = /bin/uname -a Linux raspberrypi 3.18.7-v7+ #755 SMP PREEMPT Thu Feb 12 17:20:48 GMT 2015 armv7l GNU/Linux key = SSSS, command = /usr/bin/pstree -A init-+-cron |-dbus-daemon |-dhclient |-7*[getty] |-2*[ifplugd] |-nmbd |-ntpd |-rsyslogd---3*[{rsyslogd}] |-smbd---2*[smbd] |-sshd---sshd---sshd---bash---jsCommand.lua---sh---pstree |-thd `-udevd key = rrrr, command = /bin/netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:microsoft-ds *:* LISTEN tcp 0 0 *:netbios-ssn *:* LISTEN tcp 0 0 *:ssh *:* LISTEN tcp 0 0 172.18.21.10:ssh 172.18.21.12:49433 ESTABLISHED tcp 0 0 172.18.21.:microsoft-ds 172.18.21.12:49432 ESTABLISHED udp 0 0 *:bootpc *:* udp 0 0 172.18.21.10:ntp *:* udp 0 0 localhost:ntp *:* udp 0 0 *:ntp *:* udp 0 0 172.18.21.25:netbios-ns *:* udp 0 0 172.18.21.10:netbios-ns *:* udp 0 0 *:netbios-ns *:* udp 0 0 172.18.21.2:netbios-dgm *:* udp 0 0 172.18.21.1:netbios-dgm *:* udp 0 0 *:netbios-dgm *:* udp 0 0 *:55510 *:* Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node Path unix 2 [ ACC ] STREAM LISTENING 6687 /var/run/samba/unexpected unix 2 [ ACC ] SEQPACKET LISTENING 5169 /run/udev/control unix 2 [ ] DGRAM 5714 /var/run/thd.socket unix 7 [ ] DGRAM 857 /dev/log unix 2 [ ACC ] STREAM LISTENING 876 /var/run/dbus/system_bus_socket unix 2 [ ] DGRAM 6602 unix 3 [ ] STREAM CONNECTED 7482 unix 3 [ ] DGRAM 125 unix 3 [ ] STREAM CONNECTED 1005 unix 2 [ ] DGRAM 6612 unix 3 [ ] STREAM CONNECTED 7481 unix 2 [ ] DGRAM 869 unix 3 [ ] DGRAM 126 unix 2 [ ] DGRAM 988 unix 2 [ ] DGRAM 1002 unix 3 [ ] STREAM CONNECTED 1006 key = llll, command = /usr/bin/vmstat -s 884304 K total memory 88300 K used memory 47248 K active memory 17068 K inactive memory 796004 K free memory 15648 K buffer memory 38672 K swap cache 102396 K total swap 0 K used swap 102396 K free swap 2105 non-nice user cpu ticks 0 nice user cpu ticks 4406 system cpu ticks 7900162 idle cpu ticks 1272 IO-wait cpu ticks 4 IRQ cpu ticks 1135 softirq cpu ticks 0 stolen cpu ticks 51453 pages paged in 11908 pages paged out 0 pages swapped in 0 pages swapped out 17898299 interrupts 1004321 CPU context switches 1425031008 boot time 2972 forks key = EEEE, command = /bin/ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 2152 1392 ? Ss Feb27 0:02 init [2] root 2 0.0 0.0 0 0 ? S Feb27 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S Feb27 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< Feb27 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S Feb27 0:00 [kworker/u8:0] root 7 0.0 0.0 0 0 ? S Feb27 0:00 [rcu_preempt] root 8 0.0 0.0 0 0 ? S Feb27 0:00 [rcu_sched] root 9 0.0 0.0 0 0 ? S Feb27 0:00 [rcu_bh] root 10 0.0 0.0 0 0 ? S Feb27 0:00 [migration/0] root 11 0.0 0.0 0 0 ? S Feb27 0:00 [migration/1] root 12 0.0 0.0 0 0 ? S Feb27 0:00 [ksoftirqd/1] root 14 0.0 0.0 0 0 ? S< Feb27 0:00 [kworker/1:0H] root 15 0.0 0.0 0 0 ? S Feb27 0:00 [migration/2] root 16 0.0 0.0 0 0 ? S Feb27 0:00 [ksoftirqd/2] root 17 0.0 0.0 0 0 ? S Feb27 0:00 [kworker/2:0] : 略 : jun 2291 0.0 0.5 6836 4792 pts/0 Ss Feb27 0:03 -bash root 2665 0.0 0.0 0 0 ? S Feb27 0:00 [kworker/1:0] root 2720 0.0 0.0 0 0 ? S Feb27 0:00 [kworker/u8:2] root 2942 0.0 0.0 0 0 ? S 00:23 0:00 [kworker/0:1] jun 2943 0.0 0.1 2860 1628 pts/0 S+ 00:24 0:00 /usr/bin/luajit ./jsCommand.lua jun 2970 0.0 0.0 1768 364 pts/0 S+ 00:28 0:00 sh -c /bin/ps aux 2>&1 jun 2971 0.0 0.2 5016 2096 pts/0 R+ 00:28 0:00 /bin/ps aux
jsCommand.lua はRaspberry Pi専用ではなく、luajit がインストールされていれば、普通のPCで動作する Ubuntu や Debian などのLinuxマシンで使用可能です。使い方によっては危険なこともできてしまいます。 悪用厳禁ですね。