do until $false

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Marco Marco 2 years, 3 months ago.

  • Author
    Posts
  • #18292
    Profile photo of Marco
    Marco
    Participant

    Hello Folks,

    I got a question about do and until

    i'm creating a small script that checking if a file exist.
    when the file no longer exist i need to copy a file to a new location.

    for now i have.

    do{
        Test-Path d:\test\test.log}
    until($false)
    {
        Copy-Item -path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
    }
    

    for now its do not care about true of false its just running endless till i stop the script.
    can someone tell me how i need to fix this.

    Thanks for the feedback

  • #18294
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    do {} until ($false) is an infinite loop; it'll only exit if you use something like break, return or throw from inside the loop body. do { } until ($true) would execute the loop body exactly once (which would make the loop rather pointless.)

    It looks like what you intended to do was wait for a file to exist. For that, the code would look something like this:

    while (-not (Test-Path d:\test\test.log))
    {
        Start-Sleep -Milliseconds 100
    }
    
    # Do something with d:\test\test.log
    

    I used a while loop instead of a do loop here, but the idea is the same; the loop condition is the result from Test-Path. I highly recommend putting a small sleep statement inside the loop body, as I've done here, so you don't just spin needlessly. A tenth of a second isn't much time in terms of user experience, but makes a massive difference to how fast you're banging away on the disk or CPU.

  • #18295
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    Based on the information you've provided, I think a while loop would work better for what you're trying to accomplish:

    while (Test-Path -Path d:\test\test.log) {
        Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
    }
    

    With the while statement (or loop), the loop only runs if the condition evaluates to true.

    A do-until loop checks the condition at the bottom of the loop, runs at least once, and is designed to continue as long as the condition is false. A do-while loop is similar to a do-until loop but repeats as long as the condition is true.

  • #18300
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    I modified my previous code to reverse the condition but it appears that it will not work because the loop only runs once and doesn't continue to test the condition to see if the file exists or not:

    while (-not(Test-Path -Path d:\test\test.log)) {
        Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
    }
    

    I believe this will do the trick though:

    do {
        if (Test-Path -Path d:\test\test.log -OutVariable Result) {
            Start-Sleep -Milliseconds 100
        }
        else {
            Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
        }
    }
    while ($Result)
    
  • #18337
    Profile photo of Marco
    Marco
    Participant

    Thanks Dave and Mike,

    It seems i'm using the wrong condition for the loop.
    The following code is working i my case.

    while (Test-Path -Path 'D:\test\test.loc')
    {
        Start-Sleep -Milliseconds 100
    }
    Copy-Item -path 'D:\test\test.mdb' -Destination 'D:\Test\backup.mdb'
    

    it was needed to check for a access DB lock file to disappear and copy the file for backup.

You must be logged in to reply to this topic.