[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
@coveops/[email protected]
@duckdb/[email protected]
@duckdb/[email protected]
@duckdb/[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Last active
September 25, 2025 05:16
-
-
Save shoveller/b89842389db9c629bb24761a10d6aadb to your computer and use it in GitHub Desktop.
npm 패키지 설치여부 체크
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # PowerShell Package Checker Script (v2 - Exact Version Matching) | |
| # Compatible with PowerShell 3.0+ and PowerShell Core | |
| # Encoding: UTF-8 with BOM | |
| # Encoding settings (prevent character encoding issues) | |
| try { | |
| [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 | |
| $OutputEncoding = [System.Text.Encoding]::UTF8 | |
| if ($Host.UI.RawUI) { | |
| $Host.UI.RawUI.OutputEncoding = [System.Text.Encoding]::UTF8 | |
| } | |
| } catch { | |
| # Ignore encoding setup failures and continue | |
| } | |
| param( | |
| [string]$InputFile = "list.md" | |
| ) | |
| # PowerShell version compatibility check | |
| $PSVersionMajor = $PSVersionTable.PSVersion.Major | |
| Write-Host "PowerShell Version: $($PSVersionTable.PSVersion)" -ForegroundColor Cyan | |
| Write-Host "Multi Package Manager Checker Script (PowerShell v2)" -ForegroundColor Cyan | |
| Write-Host "===================================================" -ForegroundColor Cyan | |
| # Determine input source | |
| $inputSource = $null | |
| $packages = @() | |
| if (Test-Path $InputFile) { | |
| Write-Host "Reading package list from $InputFile file." -ForegroundColor Green | |
| $packages = Get-Content $InputFile | |
| } | |
| elseif (-not [Console]::IsInputRedirected) { | |
| Write-Host "ERROR: Package list not found." -ForegroundColor Red | |
| Write-Host "Usage:" | |
| Write-Host " 1) Run with file: .\check_packages.ps1" | |
| Write-Host " 2) Specify file: .\check_packages.ps1 -InputFile 'mylist.txt'" | |
| Write-Host " 3) Use pipeline: gc list.md | .\check_packages.ps1" | |
| exit 1 | |
| } | |
| else { | |
| Write-Host "Reading package list from standard input." -ForegroundColor Green | |
| $packages = $input | |
| } | |
| # Detect package managers | |
| function Get-AvailablePackageManagers { | |
| $managers = @() | |
| if (Get-Command npm -ErrorAction SilentlyContinue) { | |
| $managers += "npm" | |
| } | |
| if (Get-Command pnpm -ErrorAction SilentlyContinue) { | |
| $managers += "pnpm" | |
| } | |
| if (Get-Command yarn -ErrorAction SilentlyContinue) { | |
| $managers += "yarn" | |
| } | |
| return $managers | |
| } | |
| # JSON parsing function (backward compatibility) | |
| function Parse-JsonSafely { | |
| param([string]$JsonString) | |
| if ([string]::IsNullOrWhiteSpace($JsonString)) { | |
| return $null | |
| } | |
| try { | |
| # Use ConvertFrom-Json in PowerShell 3.0+ | |
| if ($PSVersionMajor -ge 3) { | |
| # Handle differences between PowerShell 5.1 and Core | |
| if ($PSVersionMajor -eq 5) { | |
| # PowerShell 5.1 may handle arrays differently | |
| $result = $JsonString | ConvertFrom-Json -ErrorAction Stop | |
| return $result | |
| } else { | |
| return $JsonString | ConvertFrom-Json -ErrorAction Stop | |
| } | |
| } | |
| else { | |
| # PowerShell 2.0 fallback (using JavaScriptSerializer) | |
| Add-Type -AssemblyName "System.Web.Extensions" | |
| $serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer | |
| $serializer.MaxJsonLength = 4194304 # 4MB limit | |
| return $serializer.DeserializeObject($JsonString) | |
| } | |
| } | |
| catch { | |
| Write-Warning "JSON parsing failed: $($_.Exception.Message)" | |
| return $null | |
| } | |
| } | |
| # Check local packages | |
| function Test-LocalPackage { | |
| param([string]$PackageWithVersion, [string]$Manager) | |
| # Split package name and version by @ symbol (considering scoped packages) | |
| $atIndex = $PackageWithVersion.LastIndexOf('@') | |
| if ($atIndex -le 0) { | |
| Write-Warning "Invalid package format: $PackageWithVersion" | |
| return $false | |
| } | |
| $packageName = $PackageWithVersion.Substring(0, $atIndex) | |
| $expectedVersion = $PackageWithVersion.Substring($atIndex + 1) | |
| switch ($Manager) { | |
| "npm" { | |
| try { | |
| $jsonOutput = & npm ls --json 2>$null | |
| if ($jsonOutput) { | |
| # npm ls [package] --json으로 특정 패키지 확인 | |
| $specificOutput = & npm ls $packageName --json 2>$null | |
| if ($specificOutput) { | |
| $specificParsed = Parse-JsonSafely -JsonString ($specificOutput -join "`n") | |
| if ($specificParsed -and $specificParsed.dependencies -and $specificParsed.dependencies.$packageName) { | |
| # version 필드가 있으면 사용 | |
| $actualVersion = $specificParsed.dependencies.$packageName.version | |
| if ([string]::IsNullOrWhiteSpace($actualVersion) -or $actualVersion -eq "null") { | |
| # resolved URL에서 버전 추출 | |
| $resolvedUrl = $specificParsed.dependencies.$packageName.resolved | |
| if ($resolvedUrl -match '(\d+\.\d+\.\d+)') { | |
| $actualVersion = $matches[1] | |
| } | |
| } | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| else { | |
| # 전체 목록에서 확인 | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| if ($parsedJson -and $parsedJson.dependencies -and $parsedJson.dependencies.$packageName) { | |
| $actualVersion = $parsedJson.dependencies.$packageName.version | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "npm local check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| "pnpm" { | |
| try { | |
| $jsonOutput = & pnpm ls --json 2>$null | |
| if ($jsonOutput) { | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| # pnpm returns array format, so handle it safely | |
| if ($parsedJson) { | |
| $firstItem = if ($parsedJson -is [Array] -and $parsedJson.Count -gt 0) { $parsedJson[0] } else { $parsedJson } | |
| if ($firstItem -and $firstItem.dependencies -and $firstItem.dependencies.$packageName) { | |
| $actualVersion = $firstItem.dependencies.$packageName.version | |
| if (![string]::IsNullOrWhiteSpace($actualVersion) -and $actualVersion -ne "null") { | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "pnpm local check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| "yarn" { | |
| try { | |
| $jsonOutput = & yarn list --json 2>$null | |
| if ($jsonOutput) { | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| if ($parsedJson -and $parsedJson.data -and $parsedJson.data.trees) { | |
| $matchingPackage = $parsedJson.data.trees | Where-Object { $_.name -like "$packageName@*" } | |
| if ($matchingPackage) { | |
| $actualVersion = $matchingPackage.name.Split('@')[-1] | |
| if (![string]::IsNullOrWhiteSpace($actualVersion) -and $actualVersion -ne "null") { | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "yarn local check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| # Check global packages | |
| function Test-GlobalPackage { | |
| param([string]$PackageWithVersion, [string]$Manager) | |
| # Split package name and version by @ symbol (considering scoped packages) | |
| $atIndex = $PackageWithVersion.LastIndexOf('@') | |
| if ($atIndex -le 0) { | |
| Write-Warning "Invalid package format: $PackageWithVersion" | |
| return $false | |
| } | |
| $packageName = $PackageWithVersion.Substring(0, $atIndex) | |
| $expectedVersion = $PackageWithVersion.Substring($atIndex + 1) | |
| switch ($Manager) { | |
| "npm" { | |
| try { | |
| $jsonOutput = & npm ls -g --json 2>$null | |
| if ($jsonOutput) { | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| if ($parsedJson -and $parsedJson.dependencies -and $parsedJson.dependencies.$packageName) { | |
| $actualVersion = $parsedJson.dependencies.$packageName.version | |
| if (![string]::IsNullOrWhiteSpace($actualVersion) -and $actualVersion -ne "null") { | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "npm global check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| "pnpm" { | |
| try { | |
| $jsonOutput = & pnpm ls -g --json 2>$null | |
| if ($jsonOutput) { | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| # pnpm returns array format, so handle it safely | |
| if ($parsedJson) { | |
| $firstItem = if ($parsedJson -is [Array] -and $parsedJson.Count -gt 0) { $parsedJson[0] } else { $parsedJson } | |
| if ($firstItem -and $firstItem.dependencies -and $firstItem.dependencies.$packageName) { | |
| $actualVersion = $firstItem.dependencies.$packageName.version | |
| if (![string]::IsNullOrWhiteSpace($actualVersion) -and $actualVersion -ne "null") { | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "pnpm global check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| "yarn" { | |
| try { | |
| $jsonOutput = & yarn global list --json 2>$null | |
| if ($jsonOutput) { | |
| $parsedJson = Parse-JsonSafely -JsonString ($jsonOutput -join "`n") | |
| if ($parsedJson -and $parsedJson.data -and $parsedJson.data.trees) { | |
| $matchingPackage = $parsedJson.data.trees | Where-Object { $_.name -like "$packageName@*" } | |
| if ($matchingPackage) { | |
| $actualVersion = $matchingPackage.name.Split('@')[-1] | |
| if (![string]::IsNullOrWhiteSpace($actualVersion) -and $actualVersion -ne "null") { | |
| return $actualVersion -eq $expectedVersion | |
| } | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| catch { | |
| Write-Warning "yarn global check failed: $($_.Exception.Message)" | |
| return $false | |
| } | |
| } | |
| } | |
| return $false | |
| } | |
| # Check available package managers | |
| $availableManagers = Get-AvailablePackageManagers | |
| if ($availableManagers.Count -eq 0) { | |
| Write-Host "ERROR: No package managers found (npm, pnpm, yarn)." -ForegroundColor Red | |
| exit 1 | |
| } | |
| Write-Host "Detected package managers: $($availableManagers -join ', ')" -ForegroundColor Yellow | |
| Write-Host "" | |
| # Hash table for storing results (PowerShell 2.0 compatible) | |
| if ($PSVersionMajor -ge 3) { | |
| $results = @{} | |
| } else { | |
| $results = New-Object System.Collections.Hashtable | |
| } | |
| foreach ($line in $packages) { | |
| # Remove numbers, arrows, parentheses and keep package@version format | |
| # Handle arrow characters as unicode for PowerShell 5.1 compatibility | |
| if ([string]::IsNullOrWhiteSpace($line)) { | |
| continue | |
| } | |
| $package = $line -replace '^\s*\d*[).]\s*', '' -replace '^\d*[\u2192\u27A4]*\d*\.\s*', '' | |
| $package = $package.Trim() | |
| if ([string]::IsNullOrWhiteSpace($package)) { | |
| continue | |
| } | |
| $foundLocal = $false | |
| $foundGlobal = $false | |
| $localManagers = @() | |
| $globalManagers = @() | |
| # Check local/global in each package manager | |
| foreach ($manager in $availableManagers) { | |
| if (Test-LocalPackage $package $manager) { | |
| $foundLocal = $true | |
| $localManagers += $manager | |
| } | |
| if (Test-GlobalPackage $package $manager) { | |
| $foundGlobal = $true | |
| $globalManagers += $manager | |
| } | |
| } | |
| # Output results | |
| if ($foundLocal -and $foundGlobal) { | |
| $statusMsg = "local: $($localManagers -join ', '), global: $($globalManagers -join ', ')" | |
| Write-Host "FOUND: $package ($statusMsg)" -ForegroundColor Green | |
| $results[$package] = "installed" | |
| } | |
| elseif ($foundLocal) { | |
| $statusMsg = "local: $($localManagers -join ', ')" | |
| Write-Host "FOUND: $package ($statusMsg)" -ForegroundColor Green | |
| $results[$package] = "installed" | |
| } | |
| elseif ($foundGlobal) { | |
| $statusMsg = "global: $($globalManagers -join ', ')" | |
| Write-Host "FOUND: $package ($statusMsg)" -ForegroundColor Green | |
| $results[$package] = "installed" | |
| } | |
| else { | |
| Write-Host "MISSING: $package (not found in local/global)" -ForegroundColor Red | |
| $results[$package] = "not_found" | |
| } | |
| } | |
| Write-Host "" | |
| Write-Host "Summary:" -ForegroundColor Cyan | |
| # Result aggregation (considering PowerShell version compatibility) | |
| $installedCount = 0 | |
| $notFoundCount = 0 | |
| if ($PSVersionMajor -ge 3) { | |
| $installedCount = ($results.Values | Where-Object { $_ -eq "installed" }).Count | |
| $notFoundCount = ($results.Values | Where-Object { $_ -eq "not_found" }).Count | |
| } else { | |
| # PowerShell 2.0 compatibility | |
| foreach ($value in $results.Values) { | |
| if ($value -eq "installed") { | |
| $installedCount++ | |
| } elseif ($value -eq "not_found") { | |
| $notFoundCount++ | |
| } | |
| } | |
| } | |
| Write-Host "Installed: $installedCount" -ForegroundColor Green | |
| Write-Host "Not found: $notFoundCount" -ForegroundColor Red | |
| # Script exit | |
| exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| echo "다중 패키지 매니저 확인 스크립트" | |
| echo "================================" | |
| # 입력 소스 확인 (파일 또는 stdin) | |
| input_source="" | |
| if [ -f "list.md" ]; then | |
| input_source="list.md" | |
| echo "📄 list.md 파일에서 패키지 목록을 읽습니다." | |
| elif [ ! -t 0 ]; then | |
| input_source="/dev/stdin" | |
| echo "📥 표준입력에서 패키지 목록을 읽습니다." | |
| else | |
| echo "❌ 패키지 목록을 찾을 수 없습니다." | |
| echo "사용법:" | |
| echo " 1) list.md 파일과 함께 실행: ./check_packages.sh" | |
| echo " 2) 표준입력 사용: curl -s https://gist.../raw | bash < list.md" | |
| echo " 3) 리디렉션 사용: ./check_packages.sh < list.md" | |
| exit 1 | |
| fi | |
| # 패키지 매니저 감지 함수 | |
| detect_package_managers() { | |
| managers=() | |
| if command -v npm &> /dev/null; then | |
| managers+=("npm") | |
| fi | |
| if command -v pnpm &> /dev/null; then | |
| managers+=("pnpm") | |
| fi | |
| if command -v yarn &> /dev/null; then | |
| managers+=("yarn") | |
| fi | |
| echo "${managers[@]}" | |
| } | |
| # 패키지 설치 확인 함수 (로컬) | |
| check_package_local() { | |
| local package_with_version=$1 | |
| local manager=$2 | |
| local package_name=$(echo "$package_with_version" | cut -d'@' -f1) | |
| local expected_version=$(echo "$package_with_version" | cut -d'@' -f2) | |
| case $manager in | |
| "npm") | |
| local json_output=$(npm ls --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| # npm ls [package] --json으로 특정 패키지 확인 | |
| local specific_output=$(npm ls "$package_name" --json 2>/dev/null) | |
| if [ -n "$specific_output" ]; then | |
| # version 필드가 있으면 사용, 없으면 resolved URL에서 추출 | |
| local actual_version=$(echo "$specific_output" | jq -r --arg pkg "$package_name" '.dependencies[$pkg].version // empty' 2>/dev/null) | |
| if [ -z "$actual_version" ] || [ "$actual_version" = "null" ]; then | |
| # resolved URL에서 버전 추출 | |
| actual_version=$(echo "$specific_output" | jq -r --arg pkg "$package_name" '.dependencies[$pkg].resolved' 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1) | |
| fi | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| # 전체 목록에서 확인 | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" '.dependencies[$pkg].version // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| fi | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| "pnpm") | |
| local json_output=$(pnpm ls --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" '.[0].dependencies[$pkg].version // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| "yarn") | |
| local json_output=$(yarn list --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" --arg expected "$expected_version" '.data.trees[] | select(.name | startswith($pkg + "@")) | .name | split("@")[1] // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| esac | |
| } | |
| # 패키지 설치 확인 함수 (글로벌) | |
| check_package_global() { | |
| local package_with_version=$1 | |
| local manager=$2 | |
| local package_name=$(echo "$package_with_version" | cut -d'@' -f1) | |
| local expected_version=$(echo "$package_with_version" | cut -d'@' -f2) | |
| case $manager in | |
| "npm") | |
| local json_output=$(npm ls -g --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" '.dependencies[$pkg].version // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| "pnpm") | |
| local json_output=$(pnpm ls -g --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" '.[0].dependencies[$pkg].version // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| "yarn") | |
| local json_output=$(yarn global list --json 2>/dev/null) | |
| if [ -n "$json_output" ]; then | |
| local actual_version=$(echo "$json_output" | jq -r --arg pkg "$package_name" --arg expected "$expected_version" '.data.trees[] | select(.name | startswith($pkg + "@")) | .name | split("@")[1] // empty' 2>/dev/null) | |
| [ -n "$actual_version" ] && [ "$actual_version" != "null" ] && [ "$actual_version" = "$expected_version" ] | |
| else | |
| return 1 | |
| fi | |
| ;; | |
| esac | |
| } | |
| # 사용 가능한 패키지 매니저 확인 | |
| available_managers=($(detect_package_managers)) | |
| if [ ${#available_managers[@]} -eq 0 ]; then | |
| echo "❌ npm, pnpm, yarn 중 어떤 패키지 매니저도 찾을 수 없습니다." | |
| exit 1 | |
| fi | |
| echo "감지된 패키지 매니저: ${available_managers[*]}" | |
| echo "" | |
| # 결과 카운터 (연관배열 대신 사용) | |
| installed_count=0 | |
| not_found_count=0 | |
| while IFS= read -r line || [ -n "$line" ]; do | |
| # 숫자와 화살표, 괄호 제거하고 패키지명@버전 형태 유지 | |
| package=$(echo "$line" | sed 's/^[[:space:]]*[0-9]*[).]*[[:space:]]*//' | sed 's/^[0-9]*→*[0-9]*\.//' | xargs) | |
| if [ -n "$package" ] && [ "$package" != "" ]; then | |
| found_local=false | |
| found_global=false | |
| local_managers="" | |
| global_managers="" | |
| # 각 패키지 매니저에서 로컬/글로벌 확인 | |
| for manager in "${available_managers[@]}"; do | |
| if check_package_local "$package" "$manager"; then | |
| found_local=true | |
| if [ -z "$local_managers" ]; then | |
| local_managers="$manager" | |
| else | |
| local_managers="$local_managers, $manager" | |
| fi | |
| fi | |
| if check_package_global "$package" "$manager"; then | |
| found_global=true | |
| if [ -z "$global_managers" ]; then | |
| global_managers="$manager" | |
| else | |
| global_managers="$global_managers, $manager" | |
| fi | |
| fi | |
| done | |
| # 결과 출력 | |
| status_msg="" | |
| if [ "$found_local" = true ] && [ "$found_global" = true ]; then | |
| status_msg="로컬: $local_managers, 글로벌: $global_managers" | |
| echo "✅ $package ($status_msg)" | |
| installed_count=$((installed_count + 1)) | |
| elif [ "$found_local" = true ]; then | |
| status_msg="로컬: $local_managers" | |
| echo "✅ $package ($status_msg)" | |
| installed_count=$((installed_count + 1)) | |
| elif [ "$found_global" = true ]; then | |
| status_msg="글로벌: $global_managers" | |
| echo "✅ $package ($status_msg)" | |
| installed_count=$((installed_count + 1)) | |
| else | |
| echo "❌ $package (로컬/글로벌 모두에서 찾을 수 없음)" | |
| not_found_count=$((not_found_count + 1)) | |
| fi | |
| fi | |
| done < "$input_source" | |
| echo "" | |
| echo "결과 요약:" | |
| echo "설치됨: $installed_count" | |
| echo "설치되지 않음: $not_found_count" | |
| # 스크립트 종료 (추가 내용 실행 방지) | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
패키지 설치 여부를 조사하는 스크립트
list.md를 두어야 동작한다. 이것이 블랙리스트 역활을 한다.쉘 스크립트 버전 원라인 스크립트
파워쉘 버전 원라인 스크립트
파워쉘 버전 스크립트 뭉치