zip ファイル作成中に Too many open files (Zip::Error)
zipruby の続き。200超のファイルをzipに追加していたら、こんなエラーが出た。(T^T)
Close archive failed: Failure to create temporary file: Too many open files (Zip::Error)
エラーが出たときのスクリプトはこんな感じ。エラーメッセージからすると、ファイルディスクリプタを開きっぱになってるのかな?
Zip::Archive.open("outdir/test.zip", Zip::CREATE) do |ar|
1000.times do |count|
entry = "target.txt" + sprintf("%04d", count)
ar.add_file(entry, "target.txt")
end
end
おんで、修正したスクリプトがこちら。ファイルを1つ追加するのに zip を open/close させるように変更してみた。Zip::CREATE オプションを指定しておくと、既存zipがあれば追加モードになってくれるから、期待通りに格納してくれる。
1000.times do |count|
Zip::Archive.open("outdir/test.zip", Zip::CREATE) do |ar|
entry = "tkuser.txt" + sprintf("%04d", count)
ar.add_file(entry, "tkuser.txt")
end
end
パフォーマンス的にもっと良い解決方法があるかもしれないけど、まずは動くのが最優先だね :-)
zipruby で zip ファイルを作る
Ruby で zip ファイルを作る方法をメモっとこ。こちらさんを参考にさせてもらいました。:-)
インストール
gem を読み込んで、rb ファイルに require 'zipruby' を追記すればOK。
>gem install zipruby
使い方
1ファイルをzip化する。
Zip::Archive.open("outdir/test.zip", Zip::CREATE) do |ar|
ar.add_file('tkuser.txt')
end
指定フォルダ以下を全部zip化する。ちなみにパス名は Shift_JIS に変換してみたよ。
Zip::Archive.open("outdir/test2.zip", Zip::CREATE) do |ar|
Find.find("target_dir") do |path|
entry = NKF.nkf('-U -s -Lw', path)
if File.directory?(path)
ar.add_dir(entry)
else
ar.add_file(entry, path)
end
end
end
test3.zip ファイルを暗号化する。test3.zip は先に作っておいてね。:-)
Zip::Archive.encrypt("outdir/test3.zip", 'pass123')
簡単だね! (^_^)v
Windows でコマンドのパスを探す方法
コマンドプロンプトで,PATH上のファイルの位置を検索する方法 (Vistaの where コマンドをXPで) 曰く、Windows 環境でコマンドパスを探す方法があるそうな。which や type(bash) の代わりになる。
知らなかった。 :-)
> for %V in (wuapp.exe) do @echo %~$PATH:V
C:\Windows\System32\wuapp.exe
確認環境
- Windows 7 SP1
sc.exe でサービスのスタートアップの種類を変更する
sc.exe の config コマンドで永続的に設定を変更できるらしい。start オプションで delayed-auto にすればよさげだね。:-)
>sc config
使用法:
sc <server> config [サービス名] <オプション1> <オプション2>...
オプション:
...
start= <boot|system|auto|demand|disabled|delayed-auto>
...サービスのスタートアップの種類として覚えておけば良いのはこんなかな。詳細はこちらを参照
| auto | 自動 |
| demand | 手動 |
| disabled | 無効 |
| delayed-auto | 自動(遅延実行) |
単純に cmd から実行するとアクセスが拒否される。そりゃそうだ :-p
>sc config wuauserv start= delayed-auto [SC] ChangeServiceConfig SUCCESS >sc config wuauserv start= delayed-auto [SC] OpenService FAILED 5: アクセスが拒否されました。
cmd を管理者権限で実行して実行する。
>sc qc wuauserv
[SC] QueryServiceConfig SUCCESS
>sc queryex wuauserv
SERVICE_NAME: wuauserv
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 2 AUTO_START (DELAYED) ★
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\system32\svchost.exe -k netsvcs
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Windows Update
DEPENDENCIES : rpcss
SERVICE_START_NAME : LocalSystemこれで OK :-)
sc.exe でサービス設定を確認してみた
Windows Update サービスが Windows7 まで「自動起動(遅延実行)」だったのが Windows8 から「手動」になった。お客さんPCでこの設定を「自動起動(遅延実行)」にしときたいとのこと。訪問するのも大変なので、とりあえず、バッチを配って変更してもらうことにした。
Windows Update に限らず、サービスに対する操作は sc.exe でできるんだね。参考にさせてもらったネタ元はこちら。:-)
- IPPro SCコマンド -- あらゆる目的に使えるサービス管理コマンド
sc の基本構文はこんな。
sc [\\<サーバー名>] <コマンド> <サービス名> [<オプション>]
稼働中のサービスを取得する場合 query コマンドを指定する。サービス名が分かってると絞り込みできるとのこと。なるほど。φ(.. )
>sc query wuauserv
SERVICE_NAME: wuauserv
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_PRESHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0ちなみに sc で指定するサービス名(SERVICE_NAME)は「コンピュータの管理」で表示されるサービス名(DISPLAY_NAME)とは別モノ。指定するサービス名を知りたい場合、getkeyname で取得できる。なるほどね。φ(.. )
>sc getkeyname "Windows Update" [SC] GetServiceKeyName SUCCESS 名前 = wuauserv
指定したサービスが他サービスに依存しているか知りたい場合、qc コマンドを使う。DEPENDENCIESで「rpcss」に依存してることが分かる。
>sc qc wuauserv
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: wuauserv
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 2 AUTO_START (DELAYED)
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\system32\svchost.exe -k netsvcs
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Windows Update
DEPENDENCIES : rpcss
SERVICE_START_NAME : LocalSystem
逆に他サービスから依存されているか知りたい場合、enumdepend コマンドを使う。wuauserv の場合、他からの依存なし。lanmanserve の場合、Browser から依存ありってことだね。
>sc enumdepend wuauserv
[SC] EnumDependentServices: entriesread = 0
>sc enumdepend lanmanserver
[SC] EnumDependentServices: entriesread = 1
SERVICE_NAME: Browser
DISPLAY_NAME: Computer Browser
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0なるほどね。:-)