Problem setting variables using echo + sed

Discussion in 'Mac Programming' started by jayjay80, May 15, 2015.

  1. jayjay80, May 15, 2015
    Last edited by a moderator: May 20, 2015

    jayjay80 macrumors newbie

    Joined:
    May 15, 2015
    #1
    Greetings,

    I’m trying to turn an AD user profile path into a compatible OSX accepted path. I copied a script from another site and changed it a bit to get the result I wanted but due to my major lack of knowledge in mac scripting its not working properly. As you can see from below, the first few commands give me what I want but when it comes to setting the MacFormattedDirectory variable it goes wrong. Please can anyone review the below commands and let me know where I’m going wrong.

    Thanks

    Code:
    WinFormattedDirectory=`dscl /Active\ Directory/DOMAIN/All\ Domains -read /Users/$USER SMBHome | grep \\\\\\\\.* -o`
    echo $WinFormattedDirectory returns \\server\homes$\students\2010\test2010 (as expected)
    
    ShortenedWinFormattedDirectory=`echo $WinFormattedDirectory | sed s/\\\\\\\\server/\\\\/Volumes/`
    echo $ShortenedWinFormattedDirectory returns \/Volumes\homes$\students\2010\test2010 (works fine, even though i dont really want the first forward slash)
    
    MacFormattedDirectory=`echo $ShortenedWinFormattedDirectory | sed s/\\\\/\\//g`
    echo $MacFormattedDirectory returns \Volumes\homes$\students\2010\test2010 (wrong, supposed to turn all backslashes into forwardslashes)
    
    echo $ShortenedWinFormattedDirectory | sed s/\\\\/\\//g
    returns //Volumes/homes$/students/2010/test2010 (this is what i am looking for)
    My question is though its running the same command why is the result different when im setting the MacFormattedDirectory variable (which is what i need to be able to do)?

    Thanks
     
  2. cqexbesd macrumors regular

    Joined:
    Jun 4, 2009
    #2
    You need to be aware of what is processing each string. When you first hit enter you command is interpreted by the shell. It converts, e.g. \\ into \, and then calls the command you specified (in this case echo) which the processed string. echo in turn may interpret the string before printing it. In that case to get a \ to come out you need to use :

    Code:
    echo '\\\\'
    The shell reads that and calls the echo command with a string '\\'. echo reads that and prints a \.

    The problem you face here is that echo's unescaping behaviour is not portable or consistent across environments. Your shell will have a built in version of echo and it may behave differently to /bin/echo and that can be different again to the built in echo in another shell on the same machine and it all might be different to the same thing running on another platform. If you need to do anything even slightly fancy use printf. printf should work logically and consistently everywhere (that tries to be POSIX compliant).

    Also, and some people may disagree with this, don't try to do anything tricky with sed. It isn't pretty. In this case you can get away with using tr - much simpler.

    Having said all that I didn't read your post too carefully but here is some stuff that might help:

    Code:
    > FOO='\\server\path\file'
    > printf '%s\n' $FOO | tr \\ /
    //server/path/file
     
  3. dmi, May 17, 2015
    Last edited: May 17, 2015

    dmi macrumors regular

    Joined:
    Dec 21, 2010
    #3
    ShortenedWinFormattedDirectory=${WinFormattedDirectory/server/Volumes}
    echo ${ShortenedWinFormattedDirectory//\\/\/}
     
  4. jayjay80 thread starter macrumors newbie

    Joined:
    May 15, 2015
    #4
    Thanks for your answers guys

    @cqexbesd Thats the answer I needed but I need the answer turned to variable so it can be used below as part of a script to to modify the local documents folder and move it to a network location, so when the user uses the documents link in finder it automatically puts them to their network drive.

    #Create a SymLink to the network documents folder
    ln -s $MacFormattedDirectory ~/Documents

    How do I output it to a variable? I tried using -v $variablename and -v variablename but neither worked.

    Thanks
    James
     
  5. dmi macrumors regular

    Joined:
    Dec 21, 2010
    #5
    #Create a SymLink to the network documents folder
    ln -s ${ShortenedWinFormattedDirectory//\\/\/} ~/Documents

    MacFormattedDirectory=${ShortenedWinFormattedDirectory//\\/\/}
    ln -s $MacFormattedDirectory ~/Documents
     
  6. jayjay80, May 20, 2015
    Last edited by a moderator: May 20, 2015

    jayjay80 thread starter macrumors newbie

    Joined:
    May 15, 2015
    #6
    @dmi I understand now, sorry was being thick. I've got the whole thing kinda working now but im getting "syntax error near unexpected token `fi on line 81" I thought the script was fine. Any ideas?

    Code:
    #/bin/bash
    
    #Read the Windows formatted SMB path to the user's home directory
    #Stores only the URL string from \\ onwards
    #Note that four backslashes represent a single backslash here
    #ORIGINAL LINE WinFormattedDirectory=`dscl /Active\ Directory/All\ Domains -read /Users/$USER SMBHome | grep \\\\\\\\.* -o`
    WFD=`dscl /Active\ Directory/CANTELL/All\ Domains -read /Users/$USER SMBHome | grep \\\\\\\\.* -o`
    
    #If AD fails to return a path to the user space, don't proceed as we don't want to break the user's documents folder
    #This is particularly important if the user is logged in as a local user
    if [ $? -eq 0 ]
    then
        #Replace the server name \\FS0[0-9] from the start of the string with /Volumes to give us the share name and path
        #Note that eight backslashes represent a single backslash here
        #ORIGINAL LINE ShortenedWinFormattedDirectory=`echo $WinFormattedDirectory | sed s/\\\\\\\\\\\\\\\\fs0[0-9]/\\\\/Volumes/`
        SWFD=${WFD/fs01/Volumes}
    
        #Convert the double backslash at the front on volumes
        #This is because I don't really know how to get the right output from the previous line
        TWFD=${SWFD/\\\\Volumes/\\Volumes}
    
        #Replace all backslashes with forward slashes
        #Note that eight backslashes represent a single backslash here
        #ORIGINAL LINE MacFormattedDirectory=`echo $ShortenedWinFormattedDirectory | sed s/\\\\\\\\/\\\\//g`
        MSFD=${TWFD//\\/\/}
    
        #Change permissions on local documents folder so that we can delete it
        chmod -R -N ~/Documents
    
        #Remove the local Documents folder
        rm -rf ~/Documents
    
        #Create a SymLink to the network documents folder
        ln -s $MSFD ~/Documents
    
        #Create Downloads directory in network My Documents folder if it doesn't already exist
        mkdir ~/Documents/Downloads
    
        #Change permissions on local Downloads folder so that we can delete it
        chmod -R -N ~/Downloads
    
        #Remove the local Downloads folder
        rm -rf ~/Downloads
    
        #Create a SymLink to the network Downloads folder
        ln -s ~/Documents/Downloads ~/Downloads
    
        #Create My Videos directory in network My Documents folder if it doesn't already exist
        mkdir ~/Documents/My\ Videos
    
        #Change permissions on local Movies folder so that we can delete it
        chmod -R -N ~/Movies
    
        #Remove the local Movies folder
        rm -rf ~/Movies
    
        #Create a SymLink to the network My Videos folder
        ln -s ~/Documents/My\ Videos ~/Movies
    
        #Create My Music directory in network My Documents folder if it doesn't already exist
        mkdir ~/Documents/My\ Music
    
        #Change permissions on local Music folder so that we can delete it
        chmod -R -N ~/Music
    
        #Remove the local Music folder
        rm -rf ~/Music
    
        #Create a SymLink to the network My Music folder
        ln -s ~/Documents/My\ Music ~/Music
    
        #Create My Pictures directory in network My Documents folder if it doesn't already exist
        mkdir ~/Documents/My\ Pictures
    
        #Change permissions on local Pictures folder so that we can delete it
        chmod -R -N ~/Pictures
    
        #Remove the local Pictures folder
        rm -rf ~/Pictures
    
        #Create a SymLink to the network My Pictures folder
        ln -s ~/Documents/My\ Pictures ~/Pictures
    fi
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Start with just this in your shell script:
    Code:
    #/bin/bash
    
    #Read the Windows formatted SMB path to the user's home directory
    #Stores only the URL string from \\ onwards
    #Note that four backslashes represent a single backslash here
    #ORIGINAL LINE WinFormattedDirectory=`dscl /Active\ Directory/All\ Domains -read /Users/$USER SMBHome | grep \\\\\\\\.* -o`
    WFD=`dscl /Active\ Directory/CANTELL/All\ Domains -read /Users/$USER SMBHome | grep \\\\\\\\.* -o`
    
    #If AD fails to return a path to the user space, don't proceed as we don't want to break the user's documents folder
    #This is particularly important if the user is logged in as a local user
    if [ $? -eq 0 ]
    then
      echo "WFD is $WFD"
    fi
    echo "End"
    
    If this doesn't work, then post the complete output including the error message in a reply.

    If this works, then start adding in your original lines one by one. Run the script after every line is added. If it stops working, then you know that the line you just added is causing the problem. Post the entire script at that point, as a compressed zip file.

    If everything keeps working through the entire incremental line-adding, then you may have had some wacky unseen character in there somewhere, or maybe you have curly quotes intead of straight ones, or something like that. It's hard to say without an exact copy of your actual file. If you want to post that, then Compress it in Finder and upload the zip. Copying and pasting text doesn't always maintain exact fidelity.
     
  8. jayjay80 thread starter macrumors newbie

    Joined:
    May 15, 2015
    #8
    @chown33 That was spot on doing it that way, it works now, thank you! I think it was either because i had blank lines between each command set or a dodgy char somewhere. There is just one slight problem in that when the script creates a folder where one with the same name already exists, rather than refusing it, the script creates a new folder with the same name but adds a space and a full stop after the folder name. Is there any way to stop this?

    Thanks
     
  9. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #9
    Blank lines are legal. If some lines appear blank to you but are causing problems, then one simple explanation is that they aren't really blank.

    There's no rational reason why a space and a full stop (period) should be appended to a directory name. If that's what's happening, it's because there's something in the shell script that's causing it. As before, I suspect a weird invisible character, or some other garbage in the text file.

    The way to stop it from happening is to discover why it's happening at all, then fix that problem.

    Again, I suggest starting with all commands removed and working up. Stop as soon as the problem occurs, and post it (see below about 'set -x').

    You should also ask yourself why a directory isn't being removed. Your command sequence always removes a dir before making a replacement, so there's no reason to expect a dir to not be removed. If that's what happens prior to the appearance of a "DirName .", then maybe the problem is related to the dir removal as much as to the subsequent dir creation.


    You should add the following command at the start of your script, and the shell will tell you the commands it executes, in a kind of "log" style, followed by each command's output:
    Code:
    set -x
    That's the entire command. Put it on a line by itself, before the 'if' command. Then pay attention to what gets output. Each output line will typically be preceded by a '+', then the command is shown, typically with quote substitution. Post that entire output for a misbehaving run.


    You haven't said what you're editing your shell script with. Is it TextEdit.app? One of the Terminal command-line editors? Something else?

    Maybe the problem is your editor isn't showing you everything, or it's showing you an invisible char that isn't whitespace.

    Some text editors have a "Show whitespace" menu command. Try enabling that if yours has that feature.


    I also suggest getting a hex dump of the misbehaving shell script file. Here's the command for that:
    Code:
    hexdump -C PATH_TO_YOUR_SHELL_SCRIPT_GOES_HERE
    Please post the complete output, copied and pasted from the Terminal window, and surrounded by CODE tags.

    The hex output should contain only ASCII characters, i.e. none larger than 0x7E. If your editor is somehow saving in MacRoman or UTF-8, then there will be bytes in the range 0x80-0xFF in the script. Those must be eliminated, but the first thing you have to do is identify them, and their location.
     

Share This Page