﻿# 如何在 Windows 透過批次檔模擬出 Linux 的 watch 指令

前陣子在做一個網管的案子時，看到客戶端的 IT 人員在 Linux 底下執行了一個 watch 指令，設定每一秒執行一次 **netstat -tna** 指令，當下眼睛為之一亮，想不到原來有這樣一個好用的工具指令，可以設定固定時間自動重新執行一次，並檢視其結果，實在太方便啦。後來我也寫了一個 Windows 批次檔的版本，雖然沒辦法跟 Linux 下的 watch 指令相比，但也是還堪用啦。

以下是 Linux 底下的 watch 指令，我下載的指令是 **watch -d -n 1 netstat -tna**，其中 **\-d** 代表顯示差異，代表顯示結果的時候會與上一次的結果做文字比對 ( diff )，並顯示出被刪掉或是被新增的部分！而 **–n 1** 代表每一秒鐘就自動重新執行一次指令。而最後的 netstat –tna 當然就是每次要執行的指令了：

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ca5269f257d69e3c8679-SNAGHTML1a31794d_thumb.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/53fee1c48da302c983d6-SNAGHTML1a31794d.png)

以下是我寫好的批次檔內容，各位可以複製貼上到一個文字檔，並存檔成 \*.bat 即可使用：

```csharp
@ECHO OFF

:: 執行的指令 ( 請注意若要使用 pipe 符號必須在之前加上一個 ^ 符號 )
SET ExecuteCommand=netstat -na -p tcp^|findstr :80

:: 單位: 秒
SET ExecutePeriod=1

SETLOCAL EnableDelayedExpansion

:loop

  cls

  echo !date! !time!
  echo 每 !ExecutePeriod! 秒執行一次，指令^: !ExecuteCommand!

  echo.

  %ExecuteCommand%
  
  timeout /t %ExecutePeriod% > nul

goto loop
```

如上指令檔，有幾點注意事項：

-   ExecuteCommand 為要定時執行的指令，請注意若要使用 pipe 導向必須在之前加上一個 ^ 符號!!

-   我這個例子是篩選出所有 Port 80 的連線!

-   ExecutePeriod 為設定每幾秒要重新跑一次該指令
-   不支援 Windows XP 以下的作業系統（含 Windows XP )

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c30e2a48ddca8f6a0a4d-SNAGHTML1a472c76.png)

不過，由於 netstat 或其他指令很有可能會列出超過一頁的內容，透過這種方式就會導致畫面一直捲動，不太容易看，這時若搭配 [GNU utilities for Win32](http://unxutils.sourceforge.net/) 裡的 head.exe 指令即可有效限制輸出的量，你可以控制在只顯示第一頁而已。如果要這麼做，請將以上的 ExecuteCommand 的內容修改成以下即可：

```
netstat -na -p tcp ^| findstr :80  ^| head -n 23
```

如果不透過 head.exe 指令，我也寫了另一版純 Batch 的版本：

**\* 只取前 9 筆**

```csharp
netstat -n -p tcp|findstr :80|findstr /n TCP|findstr "^[0-9]\: "
```

**\* 只取前 99 筆**

```csharp
netstat -n -p tcp|findstr :80|findstr /n TCP|findstr "^[0-9][0-9]\: "
```

**\* 只取前 19 筆**

```csharp
netstat -n -p tcp|findstr :80|findstr /n TCP|findstr "^[0-9]\: " && netstat -n -p tcp|findstr :80|findstr /n TCP|findstr "^[0-9][0-9]\: " | findstr "^1[0-9]\: "
```

**相關連結**

-   [如何在批次檔(Batch)中實現 sleep 命令讓任務暫停執行 n 秒](/post/2009/06/24/Sleep-command-in-Batch.aspx)
-   [GNU utilities for Win32](http://unxutils.sourceforge.net/)
