ค้นหาเว็บไซต์

วิธีรอคำสั่งใน PowerShell


เมื่อคุณรันคำสั่งหรือเริ่มกระบวนการจาก PowerShell คุณมักจะต้องการรอให้คำสั่งหรือกระบวนการเสร็จสิ้นก่อนที่สคริปต์จะดำเนินต่อไป ตัวเลือกที่ง่ายที่สุดคือการใช้พารามิเตอร์ -Wait จาก Start-Process cmdlet แต่มีตัวเลือกอื่นๆ ด้วยเช่นกัน

ในบทความนี้ เราจะดูวิธีใช้พารามิเตอร์ -Wait ใช้ Wait-Process cmdlet และฉันจะแสดงตัวเลือกอื่นๆ ให้คุณดูด้วย

รอใน PowerShell

เราสามารถใช้ PowerShell สำหรับงานทุกประเภท รวมถึงการเริ่มโปรแกรมหรือการรันคำสั่งอื่น แต่ “ปัญหา” ของ PowerShell ก็คือ โดยค่าเริ่มต้นแล้วจะไม่รอให้โปรแกรมหรือคำสั่งเสร็จสิ้น

มันจะพยายามเริ่มโปรแกรมหรือรันคำสั่ง และหากสำเร็จ มันก็จะไปยังส่วนถัดไปของสคริปต์ของคุณ ในบางสถานการณ์ คุณต้องการให้ PowerShell รอก่อนที่จะดำเนินการต่อ เรามีทางเลือก 2-3 ทางในการดำเนินการนี้:

  • พารามิเตอร์ -รอ สำหรับ cmdlet Start-Process
  • Wait-Process
    Start-Sleep

Start-Process cmdlet พร้อมตัวเลือก -Wait

เมื่อคุณต้องการเรียกใช้โปรแกรมหรือคำสั่งจาก PowerShell คุณสามารถใช้ cmdlet Start-Process ได้ มาดูตัวอย่างกัน เราจะเปิดไฟล์ข้อความใน Notepad และรอให้ผู้ใช้ปิดไฟล์ ก่อนที่เราจะดำเนินการกับสคริปต์ต่อไป:

# Open File1.txt in the default editor (notepad)
Start-Process -FilePath "C:\temp\File1.txt" -Wait

# Notepad is closed, get the content of the file
Get-Content -path "C:\temp\File1.txt"

หากคุณเรียกใช้โค้ดด้านบนใน PowerShell คุณจะเห็นว่า Notepad จะเปิดขึ้น ช่วยให้คุณสามารถเขียนเนื้อหาลงในไฟล์ได้ และหลังจากที่คุณปิดแล้ว เนื้อหาของไฟล์จะแสดงในคอนโซล

รอ-ดำเนินการ cmdlet

อีกทางเลือกหนึ่งคือการใช้ cmdlet Wait-Process cmdlet นี้รอให้ปิดกระบวนการตั้งแต่หนึ่งกระบวนการขึ้นไปก่อนที่จะอนุญาตให้ PowerShell ดำเนินการต่อได้ สิ่งสำคัญที่ควรทราบคือ Wait-Process cmdlet ไม่ทำงานบน Linux หรือ macOS

เพื่อตรวจสอบว่ากระบวนการปิดอยู่หรือไม่ เราจำเป็นต้องทราบชื่อกระบวนการหรือ ID กระบวนการก่อน อีกทางเลือกหนึ่งคือการใช้วัตถุกระบวนการ ซึ่งตัวอย่างเราสามารถรับได้ด้วย Get-Process หรือ Start-Process cmdlet

หากคุณทราบชื่อกระบวนการและชื่อไม่ซ้ำกัน คุณสามารถใช้พารามิเตอร์ -name เพื่อรับและรอให้กระบวนการเสร็จสิ้น:

Wait-Process Name "Notepad"

อีกทางเลือกหนึ่งคือการค้นหากระบวนการก่อน โดยใช้ Get-Process cmdlet cmdlet นี้จะแสดงรายการกระบวนการที่ทำงานอยู่ทั้งหมด แต่เรายังสามารถกรองกระบวนการตามชื่อได้โดยใช้พารามิเตอร์ -name สิ่งที่น่ารู้คือเราสามารถใช้ไวด์การ์ดในชื่อได้:

$proc = Get-Process -Name "Notepad"
Wait-Proces -Id $proc.id

นอกจากนี้เรายังสามารถรวม Start-Process และ Wait-Process เข้าด้วยกัน ในการดำเนินการนี้ เราจะต้องใช้พารามิเตอร์ -PassThru สำหรับ Start-Process cmdlet เพื่อให้ส่งกลับวัตถุกระบวนการ

สิ่งนี้ช่วยให้เราสามารถดำเนินการได้ในขณะที่กระบวนการกำลังทำงานอยู่ แต่ให้ตรวจสอบในภายหลังในสคริปต์ว่ากระบวนการเสร็จสิ้นหรือไม่ก่อนที่เราจะดำเนินการต่อในส่วนสุดท้าย:

# Start the process
$process = Start-Process -FilePath "notepad.exe" -ArgumentList "C:\temp\File1.txt" -PassThru

# Do something in between
Write-Output "Process $($process.Id) is running."

# Wait untill process is finished
Wait-Process -Id $process.Id
Write-Output "Process has finished."

เริ่ม-สลีป cmdlet

วิธีสุดท้ายที่คุณสามารถใช้เพื่อรอหากกระบวนการเสร็จสิ้นใน PowerShell คือวิธี Start-Sleep cmdlet นี้ไม่สามารถตรวจสอบได้ว่ากระบวนการกำลังทำงานอยู่หรือไม่ แต่ให้ PowerShell รอเป็นเวลา x เท่านั้น

สิ่งนี้ยังคงมีประโยชน์อยู่บ้าง ตัวอย่างเช่น หากคุณรู้ว่ากระบวนการต้องใช้เวลาสองสามวินาทีในการเริ่มต้นและดำเนินการหรือเสร็จสิ้น

Start-Sleep cmdlet ทำงานโดยระบุระยะเวลาในหน่วยวินาทีหรือมิลลิวินาทีที่ PowerShell ควรรอ

ตัวอย่างเช่น หากต้องการให้ PowerShell รอ 5 วินาที เราสามารถใช้:

# Wait for 5 seconds before continuing
Start-Sleep -Seconds 5

รออินพุต

อีกวิธีหนึ่งที่ฉันต้องการแสดงให้คุณเห็นเช่นกันคือการรออินพุตใน PowerShell บางครั้งการปล่อยให้ PowerShell รอการกดปุ่มก่อนที่จะดำเนินการต่อก็ง่ายกว่า นี่อาจเป็นคีย์อินพุตใดก็ได้ หรือคีย์เฉพาะก็ได้หากต้องการ เรามีสองทางเลือกในการรออินพุต เราสามารถใช้วิธี ReadKey จากคลาส System.Console .Net หรือเราจะใช้วิธี Read-Host.

วิธีการ ReadKey ด้านล่างจะไม่ส่งคืนเอาต์พุตใด ๆ ในคอนโซล (ยกเว้นโฮสต์การเขียนแน่นอน) แต่ใช้ไม่ได้ใน PowerShell ISE (แต่ฉันแนะนำให้ใช้ Visual Studio Code ต่อไป..)

Write-Host "Press any key to continue..."
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | Out-Null

อย่างไรก็ตาม ด้วย Read-Host เราสามารถระบุได้ว่าผู้ใช้จะต้องกดคีย์ใด วิธีนี้ช่วยให้ควบคุมได้มากขึ้นว่าจะต้องเขียนสคริปต์เมื่อใด ในตัวอย่างด้านล่าง เรารวมวง While เข้ากับ Read-Host cmdlet ดังนั้นระบบจะขอให้กดปุ่ม Y ต่อไปก่อนที่ PowerShell จะดำเนินการต่อ

while ((Read-Host "Press 'Y' to continue") -ne 'Y') {}

ห่อขึ้น

เมื่อเริ่มกระบวนการหรือคำสั่งจาก PowerShell วิธีที่ดีที่สุดคือใช้ Start-Process cmdlet รวมกับพารามิเตอร์ -Wait หากกระบวนการกำลังทำงานอยู่แล้ว Wait-Process cmdlet คือตัวเลือกที่ดีที่สุดที่จะใช้

หวังว่าคุณจะชอบบทความนี้ หากคุณมีคำถามใด ๆ เพียงแสดงความคิดเห็นด้านล่าง