2023年10月28日 星期六

如何僅利用 sftp 判斷對方是 unix 還是 win

如何僅利用 sftp 判斷對方是 unix 還是 win

繼前幾篇的轉換

CHG: 在BAT中如何做 Ascii 文本的變換 更換換行符號 (Linux -> Win)
CHG: 在BAT中如何做 Ascii 文本的變換 更換換行符號 (Win -> Linux)

這篇要來講如何判斷對方是不是 Unix 伺服器,從設計上來說其實 sftp 並不具備檢測對方伺服器的標準API,只能瞎猜看看了

這邊用的判斷方式是檢測對方根目錄有沒有 etc 文件的存在,雖然無法百分百完全判定
,不過在大多數情況下足夠了


判斷的代碼

測試是否為Unix

function Test-SftpIsUnix {
    param (
        $LoginInfo
    )
    # 檢視根目錄
    $output = 'ls /' | sftp -oBatchMode=yes $LoginInfo 2>&1
    # 檢查輸出中是否有特定目錄存在
    if ($LastExitCode -eq 0) {
        $dirName = '/etc'
        if (-not ($output -match $dirName)) {
            # Write-Host "$dirName 目錄不存在,可能不是 Linux 系统。"
            return $false
        } else {
            # Write-Host "$dirName 目錄存在,可能是 Linux 系统。"
            return $true
        }
    } else {
        # Write-Error "連接失敗或無法存取跟目錄" -ErrorAction Stop
        return $null
    }
}

如此一來就可以透過該函式來判定要不要做換行代碼的轉換了




2025-08-21 更新

寫了一個比較完整的判斷函式

function Get-SftpSystemType {
    param ($LoginInfo)

    # Executes SFTP commands and returns the result
    function Invoke-Sftp {
        param( [Parameter(Mandatory)] $LoginInfo, $Commands )
        $result = (@($Commands) -join "`n" | sftp -oBatchMode=yes -oStrictHostKeyChecking=accept-new $LoginInfo 2>&1) -join "`n"
        if ($LastExitCode -ne 0) { Write-Error $result } else { $result }
    }

    # Check root directory contents
    try {
        $result = Invoke-Sftp $LoginInfo "ls /etc `n ls /C:" -ErrorAction Stop
    } catch { Write-Error $_; return }

    # Check for Unix/Windows specific directories
    switch -Regex ($result) {
        '\b/?etc/passwd\b' { "Unix" }
        '/C:/Windows' { "Windows" }
        default { "Unknown" }
    }
}


有認真想了一下要不改更精確的 ssh 指令有更多選擇,最後駁回了理由是環境只有 sftp 不開放 ssh 應該蠻常見的,所以還是盡量限縮在最小工具上吧




沒有留言:

張貼留言