New to PS and need help understanding

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Justin Justin 1 year, 12 months ago.

  • Author
    Posts
  • #21059
    Profile photo of Justin
    Justin
    Participant

    First off: I am doing this for an online class through my college, so this is for an assignment I have to do. As such, giving me answers does me no good other than the assignment would be done but I wouldn't have learned much from it. I'm really just looking to understand more about this stuff. I'm at the point in the class where there are no longer lectures available for me to watch and I have already re-watched the section on loops, I've done a bit of Google searching and I just don't really know what I am looking for to search Google properly.

    So, what I am trying to do is create a while loop that is checking changes to a file. The things to track are the length of the file and the write time of the file and then have another part of the loop write to a log about changes to either (I am confident that that part of the script will work once I figure out this other part).

    And I just can't get the length and write time checking to work.

        if( $old_len -and $curr_len -eq "" )
        {
            
            $old_len = $my_file.length
            $old_writetime = $my_file.lastwritetime
            
        }
        else
        {
            
            $curr_len = $my_file.length
            $curr_writetime = $my_file.lastwritetime
            
        }
    

    So this is where I am at right now, I devised this as (to the best of my understanding) a simple piece of code that should first look the $old_ variables and if they are null (Which outside the while loop, they are) and then update it with the length and if not it should instead put those values in the $curr_ variables. Instead what I am getting is that all cycles through the loop it is reading the files as the length has been changed, even if I don't touch said file. If I understand correctly what the assignment is asking it should write to the log for any changes and if this had worked the way I thought: I do know it would only be able to look at one change because once the $old_ variables are written to, they wouldn't change again.

    Any help, would of course, be greatly appreciated.

  • #21060
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    This conditional:

    if ($old_len -and $curr_len -eq "")
    

    Is a bit odd looking. One thing to keep in mind here is that the -eq operator is only being applied to the $curr_len variable. Your condition could be expressed like this, to make it clearer what's currently happening:

    if (([bool]$old_len) -and ($curr_len -eq ""))
    

    The $old_len part of your conditional is just evaluated as a Boolean expression on its own, and the true/false semantics will depend on what's in the variable. ($null is false, zero is false for numeric types, empty strings are false, empty arrays are false, arrays with two or more elements are true, single-element arrays depend on what the value of the single element is.) If your intention was to check whether $old_len and $curr_len are both empty strings, you'd need to express that explicitly:

    if ($old_len -eq "" -and $curr_len -eq "")
    

    While legal, though, the logic of that doesn't make much sense. I think you were meaning to test $old_len and $old_writetime rather than $old_len and $curr_len. Also, neither of those variables is going to contain a string, so comparing them to "" _may_ work (since PowerShell is pretty forgiving about converting values for you), but may not. I would prefer to initialize those variables to $null outside the loop, then explicitly check for $null inside. (Since you're setting both variables together, it's probably sufficient to only check one of them for null.)

    When you're working with loops, you need to develop the skill of keep track of the state of the code each time through the loop. Without a debugger, try stepping through the code in your head for the first time through the loop, then subsequent times, and see if the flowchart defined by your "if" statement makes sense for what you were trying to accomplish.

  • #21065
    Profile photo of Justin
    Justin
    Participant

    Ah, yes that was an error on my part that I should have caught. Fixed.

    Okay so basically:

    (Outside the loop)

    $old_len = $null
    $old_writetime = $null
    

    Is a better way of handling what I am attempting then because it tells PowerShell the value instead of PS making it up it's self? It had been my assumption that an empty string was just $var = "".

    I am kind of playing with the debugger right now in PowerShell just to see how the program is running and I think it may have built on to my confusion, I think I had been running on a notion that the loop would be read straight down until it repeated it's self and the debugger play through showed that it's read all at once.

    Might help if I just posted what I am looking at for script for helping out.

  • #21087
    Profile photo of Stephen Owen
    Stephen Owen
    Participant

    The various steps of the loop are never evaluated until the condition is $true, or $false, based on how you've arranged the logic.

    I would probably change the wording though, and compare the $LastWriteTimes

    At the start of the script, gather the LastWriteTime in a variable, maybe $Initial_LastWriteTime. Then, set a while Loop, waiting for the file to change, then do something. In my case, I'm using a file called .\Upload.txt. While the script is running, I add a character to the file then save it.

    $Initial_LastWriteTime = get-item .\upload.txt | Select -ExpandProperty LastWriteTime
    
    #Will Only exit the loop if the file changes
    While($Initial_LastWriteTime -eq ( get-item .\upload.txt | Select -ExpandProperty LastWriteTime)){"Waiting for the file to change...";start-sleep 5}
    
    "File changed!"
    #DO STUFF HERE

    The result is

  • #21158
    Profile photo of Justin
    Justin
    Participant

    I actually had the thought while trying to get this working that if it would be much easier if I could set the initial file size and write time out of the loop but no, I have to specifically have those variables set to empty string outside of the loop.

You must be logged in to reply to this topic.