シェルcgiでファイルアップロード

なんか無理やり過ぎてユニケージと言って良いのかわからなくなってきた…。

ファイルアップロードを行う。
ブログの様なものを想定し、1記事に複数ファイルをアップロード出来る。
ディレクトリ構成は以下の様な感じ
posts/
┣001/
┃┣post1
┃┣post2
┃┗ files/
┣002/
┃┣post1
┃┗files/

この"files"にファイルをアップロードしていく。
今回はファイルアップ時に画面遷移したくないのでajaxで対応。
(post1が初投稿、post2は更新ファイル。数字が大きい物が最新)

流れはこんな感じ。
1.ajaxでアップロード
2.ddコマンドでファイルをコピー
3.ファイル名を変更
4.不要な行を削除 (?)

1.ajaxでアップロード

jqueryを使ってファイルをアップロード

[up.html]

<form id="frm" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
  <input type="submit" />
</form>

[up.js]

function up(){
 // formのデータを取得
  formData = new FormData($('#frm'));
  $.ajax({
    url: '/fileup.cgi/001',
    type: 'post',
    data: formData,
    processData: false,
    contentType: false
  });
  // falseを返してsubmitを中断
  return false;
}

urlの"001"はアップロード先の記事のID。
本来は可変にしたいので、mojihameとか使ってIDをはめ込めばよい。

2.ddコマンドでファイルをコピー

[fileup.cgi]

# アップロード先取得
id=$(echo $REQUEST_URI | sed "s/^\/fileup\.cgi\///g")
dir=/posts/${id}/files

# ファイルをコピー
tmp=$(mktemp)
dd bs=${CONTENT_LENGTH} of=$tmp

アップロード先取得では、urlの中から記事のIDを抽出してアップロード先のディレクトリを決めている。(IDは"001"とか"002")
ddコマンドでとりあえずまるごとコピー。

3.ファイル名を変更

ファイル名を受信データから取り出して名前を変える。
[fileup.cgi]

filename=$(awk 'NR==2' ${tmp}                |
           nkf -w -                          |
           grep -o -e "filename=\"\(.*\)\""  |
           sed 's/filename="\(.*\)"/\1/g'    )

2行目に"filename="で始まるファイル名が記載されている箇所があるのでそこから抽出。
ファイル名が日本語だと化けるのでnkfで変換。

4.不要な行を削除 (?)

ここは非常にその場しのぎ的だが、とりあえずメモ。
[fileup.cgi]

# 拡張子取得
ext=${filename##*.}
# 不要行を削除して書き出し
if [ ${ext} = "txt" ]; then
  sed -e '$d;1,4d' ${tmp} |
  sed -e '$d'             |
  nkf -w -                >${dir}/${filename}
else
  sed -e '$d;1,4d' ${tmp} >${dir}/${filename}
fi

1-4行目に"Content-Type"とか"filename="とかいった情報が入っているので削除する。
テキストファイルに関しては最終2行にも不要なものが入っていたので削除。
完全に結果論なので破綻する可能性大だが、とりあえず動けば良いのでこれでオーケー。

全体的にもっと良い書き方があるのだろうけど、シェルスクリプト初心者にはこれが限界。

textareaにformhame

formhameでtextareaに値をはめる際によく忘れること。

<textarea name="hoge"></textarea>

これだとNoneTypeオブジェクト云々と言ったエラーメッセージが出てそれ以降のhtmlが出力されない。

<textarea name="hoge">
</textarea>

改行を入れればオーケー。
理由はまだわからない。

linuxからwindowsのバッチ起動

LinuxからWindowsのバッチを起動する必要があったので調査。

結論として可能。
WindowsfreeSSHdSSHサーバを設け、Linuxからsshコマンドでコマンド送信する。

注意点
freeSSHdの設定としては、共有鍵の認証にすると1ラインで完結できないのでパスワード認証にする
Linuxにsshpassをインストールし、1ラインでパスワードを記載できるようにする

sshpass -p 'PASSWORD' ssh -l USER xxx.xxx.xxx.xxx "COMMAND"

クラシックASPでOracleにファイル登録

ASP(非.net)でOracleにファイルを登録しようと調べたメモ。

バイナリを扱うモジュールが必要なので、
下記を参考にインストール。
http://www.hi-ho.ne.jp/babaq/basp21.html

OracleでばBLOB型のフィールドを用意。
拡張子がわからないと復元できないのでファイル名も一緒に格納すると良いかも)

ASPのソースは以下

<%
set bobj = Server.CreateObject("basp21")
bytes = Request.TotalBytes
' バイト数を指定してバイナリデータ読み出し
b = Request.BinaryRead(bytes)
' FormBinaryの第二引数にinput type="file"のnameを指定してデータ取得
obj = bobj.FormBinary(b, "file")
filename = bobj.FormFileName(b, "file)

Dim conn
set conn = Server.CreateObject("ADODB.Connection")
Call conn.Open("ODBC_NAME", "SCHEMA", "PASSWORD")

sql = "INSERT INTO TABLE VALUES(?, ?)"

' Commandを使う
set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = sql
' cmd.parametersでプレースホルダーに値を配置
cmd.Parameters(0).Value = filename
cmd.Parameters(1).Value = obj
' sql実行
cmd.Execute

set cmd = Nothing
conn.Close
set conn = Nothins
%>

シェルスクリプトでWEBページ

ユニケージ開発に興味があって色々勉強中。

サーバ側でテキストファイルでごそごそしてその結果をWEB画面に表示したい。
簡単なページならOpen-usp-Tukubaiのmojihameで十分だけど、拡張性がちょっとな…といったところ。

ajaxでデータを取得してjavascriptではめ込む方法はどうかと模索中。
とりあえず

1.jsでajaxリクエスト送信
2.shでリクエストされたデータ生成&返却
3.handlebars.jsでHTMLにはめ込み

まではできた。
今後はこれが実用的かを検証していきたい。

気になったところとしては
handlebars.jsではjson形式のデータをはめ込むようなので、
データをシェルスクリプトで整形するかjavascriptで整形するかという点。

bashのプロセス置換

プロセス置換便利

Open-usp-Tukubaiのmojihameでファイルでなくて変数を文字はめしたかった。

cat $htmd/template.html |
mojihame -d_ -i_ $hensu

ではもちろんエラー。

cat $htmd/template.html |
mojihame -d_ -i_ <(echo $hensu)

として"<"を使用して"echo $hensu"をファイルとして扱ったらO.K.