ユーザ用ツール

サイト用ツール


it技術:バッチファイル

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
it技術:バッチファイル [2017/04/19 11:46] – [VBSから戻り値を取得] yajuadminit技術:バッチファイル [2021/04/09 10:23] (現在) – [UNCパスの対応方法] yajuadmin
行 5: 行 5:
 cd /d %~dp0 cd /d %~dp0
 </code> </code>
 +“%~dp0” は、“%0” で 0 番目の引数 (つまりバッチファイルのフルパス) から、“~” (チルダ) で両端を囲むダブルクオートを取り除き、“d” でドライブレターを残し、更に “p” でパスを残す、つまり、バッチファイルのあるフォルダまでのパスを示しています。
  
 +===== 32bit環境で実行 =====
 +64bitOS上では、コマンドプロンプトやCScriptは64bitで動作してしまうため、WOW64内環境内で実行させる必要がある。\\
 +[[http://www.atmarkit.co.jp/ait/articles/1007/01/news131.html|Win32アプリケーションを実行するWOW64]]
 +
 +Excelファイルのデータアクセスに「OLEDB4.0」を使う場合、32bit環境でないとエラーとなる。\\
 +IISで32bitモードで動作する際に使用するモジュールのレジストリ登録も32bit環境で実行させる。
 +==== VBSの場合 ====
 +<code bat>
 +%windir%SysWOW64\cscript.exe xxxxx.vbs
 +または
 +%windir%SysWOW64\cmd.exe xxxxx.vbs
 +</code>
 +==== レジストリ登録の場合 ====
 +「ファイル名を指定して実行」で入力する
 +<code bat>
 +%windir%SysWOW64\regsvr32 xxxxx.dll
 +</code>
 ===== 変数の値が反映されない ===== ===== 変数の値が反映されない =====
 if文、for文の中に書いた処理は「()を抜けてから」変数の値が反映される。\\ if文、for文の中に書いた処理は「()を抜けてから」変数の値が反映される。\\
行 39: 行 57:
     echo ファイルが見つかりません ^(%filePath%^)     echo ファイルが見つかりません ^(%filePath%^)
 ) )
 +</code>
 +
 +===== 日時(YYYYMMDDHHMMSS)形式のセット =====
 +現在時刻をYYYYMMDDHHMMSS形式で取得する。
 +
 +<code>
 +set time_tmp=%time: =0%
 +set now=%date:/=%%time_tmp:~0,2%%time_tmp:~3,2%%time_tmp:~6,2%
 +echo %now%
 </code> </code>
  
行 68: 行 95:
 </code> </code>
  
 +===== 2重引用符を削除 =====
 +%n変数に〜チルダ文字を追加する。
 +
 +<code bat>
 +set befPath=%~1
 +</code>
 ===== ログとリダイレクト ===== ===== ログとリダイレクト =====
 [[http://language-and-engineering.hatenablog.jp/entry/20130502/PatternsOfMSDOSorBAT|ログとリダイレクト]] [[http://language-and-engineering.hatenablog.jp/entry/20130502/PatternsOfMSDOSorBAT|ログとリダイレクト]]
行 76: 行 109:
 通常のリダイレクトは標準出力(「1」)に書き込まれるが、エラーメッセージはエラー出力(「2」)に書き込まれるためエラーメッセージをログに記録しておくことができない。その場合、「2>&1」として「2の代案を1にする」操作を追記させる。 通常のリダイレクトは標準出力(「1」)に書き込まれるが、エラーメッセージはエラー出力(「2」)に書き込まれるためエラーメッセージをログに記録しておくことができない。その場合、「2>&1」として「2の代案を1にする」操作を追記させる。
 <code bat> <code bat>
 +echp 開始 %date% %time% > log.txt 
 call sub.bat >> log.txt call sub.bat >> log.txt
  
 call sub.bat >> log.txt 2>&1 call sub.bat >> log.txt 2>&1
 </code> </code>
 +
  
 ===== 空白含む内容のパラメータ渡し ===== ===== 空白含む内容のパラメータ渡し =====
行 127: 行 162:
 exit 0 exit 0
 </code> </code>
-参照:[[http://blog.putise.com/windows%E3%81%A7%E4%B8%80%E5%AE%9A%E6%9C%9F%E9%96%93%E7%B5%8C%E9%81%8E%E3%81%97%E3%81%9F%E5%8F%A4%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%87%AA%E5%8B%95%E5%89%8A%E9%99%A4%E3%81%99/+[[http://blog.putise.com/windows%E3%81%A7%E4%B8%80%E5%AE%9A%E6%9C%9F%E9%96%93%E7%B5%8C%E9%81%8E%E3%81%97%E3%81%9F%E5%8F%A4%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%87%AA%E5%8B%95%E5%89%8A%E9%99%A4%E3%81%99/
 |Windowsで一定期間経過した古いファイルを自動削除するコマンドは?コマンドプロンプト標準コマンドがある]] |Windowsで一定期間経過した古いファイルを自動削除するコマンドは?コマンドプロンプト標準コマンドがある]]
  
 +==== UNCパスの対応方法 ====
 +forfilesでUNCパスを指定すると「unc パス ( コンピューター名 共有名) はサポートされていません。」のエラーになる。
 +
 +forfilesでUNCパスが非対応なので、前行で pushd UNCパス とする。
 +
 +<code>
 +SET NET_DIR=\\192.168.64.100\work\
 +
 +net use %NET_DIR% xxxxxxx /USER:xxxxxxx
 +
 +pushd %NET_DIR%
 +forfiles /M *.txt /C "cmd /c if @isdir==FALSE del /s @path" /D -30 >> logdel.log
 +popd
 +</code>
 ===== 常に管理者権限で実行する ===== ===== 常に管理者権限で実行する =====
 ショートカットを管理者で実行するように設定\\ ショートカットを管理者で実行するように設定\\
行 138: 行 187:
   * [[http://vbsguide.seesaa.net/article/434439007.html|VBScript を『管理者として実行する』]]   * [[http://vbsguide.seesaa.net/article/434439007.html|VBScript を『管理者として実行する』]]
  
 +===== 管理者権限か判定する =====
 +管理者権限か判定して警告メッセージを出す。
  
 +[[https://www.rootlinks.net/2014/08/28/%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E7%AE%A1%E7%90%86%E8%80%85%E6%A8%A9%E9%99%90%E3%81%A7%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B%E7%A2%BA/|バッチファイルが管理者権限で動作しているか確認]]
 +
 +<code bat>
 +@echo off
 +openfiles > NUL 2>&
 +if %ERRORLEVEL% EQU 0 goto Admin 
 +echo 管理者権限で実行してください。
 +pause
 +exit
 + 
 +:Admin 
 +echo 管理者権限で実行中
 +</code>
 +===== レジストリのコマンド編集 =====
 +regeditはコマンドラインから実行した場合、成否をerrorlevel環境変数に設定しないため、バッチファイルから使用する場合はregコマンドを使うことが望ましい。\\
 +[[http://www.atmarkit.co.jp/ait/articles/0402/21/news005.html|コマンドプロンプトでレジストリを操作する]]
 +
 +<code bat 書式>
 +reg サブコマンド キー名 ファイル名
 +</code>
 +
 +^主なサブコマンド^^
 +^query|レジストリのキーや値を画面に表示します。|
 +^import|ファイル(*.reg 形式)からレジストリの情報をインポートします。|
 +^export|レジストリの情報をファイル(*.reg 形式)に出力します。|
 +
 +<code bat エクスポート>
 +Set InstallReg=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\TrendMicro
 +call :regSub Database_Backup.reg "Database Backup"
 +
 +:regSub
 +echo %1 >> regexport.log
 +reg export "%InstallReg%\%~2" %1 >> regexport.log 2>&1
 +exit /b
 +</code>
 +
 +<code bat インポート>
 +call :regSub Database_Backup.reg
 +
 +:regSub
 +if exist %1 (
 +echo %1 >> regimport.log
 +reg import %1 >> regimport.log 2>&1
 +)
 +exit /b
 +</code>
 +
 +===== ファイルコピー =====
 +==== XCopy ====
 +ディレクトリツリーごとコピーできるところが、copy との最大の違いとなります。\\
 +[[https://www.k-tanaka.net/cmd/xcopy.php|xcopyのオプション]]
 +
 +^よく使用するオプション^^
 +^/S|ファイルが存在する場合のみディレクトリごとコピーする|
 +^/E|ファイルが存在しなくてもディレクトリごとコピーする|
 +^/I|コピー先のディレクトリが存在しない場合は新規にディレクトリを作成する|
 +^/Y|同名のファイルが存在する場合、上書きの確認を行わない|
 +^/D|コピー先に同名のファイルが存在する場合に更新日が新しいファイルのみコピーする|
 +
 +XCOPY元としてフォルダを指定する場合,フォルダ名の末尾に\を付けないこと\\
 +XCOPY先としてフォルダを指定する場合,フォルダ名の末尾に\を付けること
 +
 +=== 「ファイル名ですか、またはディレクトリ名ですか」の確認 ===
 +[[http://jehupc.exblog.jp/12286010/|xcopyでフォルダコピー時に「ファイル名ですか、またはディレクトリ名ですか」と聞いてくる]]\\
 +「複写先が既存のディレクトリを含まず、かつ、名前が円記号(\)で終わっていない場合」または「複写元の下位フォルダに同じファイルがある場合」に表示される。
 +
 +回避策としては複写先に円記号(\)を付ける。または下記のように強制的にファイルにecho F(ファイル) or D(ディレクトリ)を指定する。\\
 +※複写元の下位フォルダに同じファイルがある場合、最後に見つかったファイルがコピーされる。\\
 +その場合、XCopyをやめてCopy(複写先にフォルダの作成が必要)にするか、更新日が新しいのが確実なら「/D」を付ける。
 +<code bat>
 +Set InstallDir=D:\Program Files (x86)\Trend Micro\OfficeScan
 +echo F|XCopy "%InstallDir%\PCCSRV\Admin\ssnotify.ini" PCCSRV\Admin\ /S /Y /I /D
 +</code>
 +
 +=== デメリット ===
 +[[http://www.teppi.com/fileblog/support/004_support_robocopy.htm|robocopyコマンドでフォルダの内容を同期させる]]
 +
 +  * XCOPYは、長い(255文字を越える)ファイル名を処理できず、異常終了します。
 +  * XCOPY /d で「タイムスタンプが新しくなったファイルだけをコピー」するとき、 コピー先のファイルのタイムスタンプが、コピー元のファイルのタイムスタンプと、秒単位でずれることがあります。 そのため、XCOPY処理を日次で実行して、本来は毎日差分だけをコピーするつもりでいても、 毎日全ファイルをコピーしてしまうことがあります。
 +
 +==== Robocopy ====
 +Windows Vista 以降、Windows Server 2008 以降では標準コマンドとして用意されている。\\
 +[[http://blog.putise.com/windows%E3%81%AE%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%82%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E7%A7%BB%E8%A1%8C%E3%81%AB%E3%82%AA%E3%82%B9/|windowsのバックアップやファイルサーバー移行にオススメな標準コマンド「robocopy」の使い方、オプション説明]]
 +
 +メリット
 +  * 255文字以上のファイルパスに対応
 +  * ミラーリング(差分コピーと同じです)
 +  * コピー先のいらないファイルを削除するのみ
 +  * 古いファイルはコピーしない
 +  * コピーではなく移動する
 +  * リトライがある
 +  * フォルダ体系のみコピーし、アクセス権をコピーしたい
 +  * アクセス権が無いけどバックアップに使いたい
 +  * タイムスタンプを維持できる
 +
 +などなど
 +
 +==== FastCopy ====
 +Windows系最速(?)のファイルコピー&削除ツール [[https://ipmsg.org/tools/fastcopy.html|FastCopy]]\\
 +[[http://www.se-support.com/server/fileserver-copy.html|高速コピーツール「FastCopy」はホントに早かった!]]
 +
 +UNICODE でしか表現できないファイル名やMAX_PATH(260文字) を越えた位置のファイルもコピー(&削除)できます。\\
 +Read/Write も、OS のキャッシュを全く使わないため、他のプロセス(アプリケーション)が重くなりにくくなっています。可能な限り大きな単位で Read/Write するため、デバイスの限界に近いパフォーマンスが出ます。
 +
 +GUI版だけでなくコマンドライン版があります。
 +<code bat 書式>
 +fastcopy.exe [/オプション類] file1 file2 ... [/to=dest_dir]
 +</code>
 +
 +===== フォルダ自体をコピーする =====
 +フォルダ自体をコピーするには、コピー先にフォルダを指定する。
 +<code>
 +robocopy C:\AAA\hoge D:\BBB\hoge /E
 +echo d | xcopy C:\AAA\hoge D:\BBB\hoge /E
 +</code>
 +
 +==== フォルダの更新日時を維持してコピーする ====
 +フォルダの更新日時を維持してコピーするには、robocopyのオプション「/DCOPY:T」を使う。
 +<code>
 +robocopy C:\AAA\hoge D:\BBB\hoge /E /DCOPY:
 +</code>
 ===== 参照 ===== ===== 参照 =====
   * [[http://qiita.com/yz2cm/items/8058d503a1b84688af09|バッチファイルでの試行錯誤を回避するためのメモ]]   * [[http://qiita.com/yz2cm/items/8058d503a1b84688af09|バッチファイルでの試行錯誤を回避するためのメモ]]
   * [[http://language-and-engineering.hatenablog.jp/entry/20130502/PatternsOfMSDOSorBAT|反復して実行可能に]]   * [[http://language-and-engineering.hatenablog.jp/entry/20130502/PatternsOfMSDOSorBAT|反復して実行可能に]]
   * [[https://www.k-tanaka.net/cmd/xcopy.php|xcopyのコマンド一覧]]   * [[https://www.k-tanaka.net/cmd/xcopy.php|xcopyのコマンド一覧]]
it技術/バッチファイル.1492570010.txt.gz · 最終更新: 2017/04/19 11:46 by yajuadmin