Use a space in a "system" command

Discussion in 'Mac Programming' started by Ides, Dec 18, 2012.

  1. macrumors member

    Joined:
    Mar 27, 2012
    #1
    I'm trying to get into a directory from within a program, being written in C. I use the following command:

    Code:
    system("cd ~/Library/Application Support/ftblauncher");
    Except the space in "Application Support" is throwing it off, it doesn't understand it. I have tried adding a backslash before the space but then xcode says "unknown escape sequence". Does anyone know how to fix this?
     
  2. Moderator

    Nermal

    Staff Member

    Joined:
    Dec 7, 2002
    Location:
    Whakatane, New Zealand
    #2
    Does this work?

    Code:
    system("cd \"~/Library/Application Support/ftblauncher\"");
     
  3. thread starter macrumors member

    Joined:
    Mar 27, 2012
    #3
    Unfortunately, no. When it runs I get:

    sh: -c: line 0: unexpected EOF while looking for matching `"'
    sh: -c: line 1: syntax error: unexpected end of file
     
  4. macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    What happens if you make an array char by char? (Never tried it before, just a guess )
     
  5. macrumors 6502a

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #5
    Regardless of the space or not, I'm wondering what you hope to accomplish issuing a 'cd' command in system(). system() creates a child process, executes a shell, and executes that command within the shell. Then the process exits. So you changed directory within a process that then disappears.
     
  6. ytk
    macrumors regular

    Joined:
    Jul 8, 2010
    #6
    Try adding two backslashes before the space. The first one escapes the second one to make it a literal backslash, which is then passed to the cd command as an argument. However, mfram is correct. The command, as written, does essentially nothing.
     
  7. macrumors 603

    Joined:
    Aug 9, 2009
    #7
    This.


    To the OP, if you want to "get into" a directory in a C program, use the chdir() or fchdir() C functions. You won't be able to use "~", either.

    There's no way that a system() command to 'cd' anywhere can possibly affect the process calling system(). There are no workarounds or tricks that can make it work. It's fundamental to all Posix/Unix systems.

    If that's not enough clues for a solution, then please explain exactly what you're trying to accomplish, which language you're writing in, and which OS version you need to target.

    The language is important, because there are other ways to do this in Objective-C, that don't necessarily require chdir or fchdir(), and there are options for resolving "~". And depending on what you're trying to accomplish, doing it in some other language (e.g. shell script) may be simpler and more effective than C.

    The OS version is important because it helps clarify what you're trying to accomplish.
     
  8. macrumors regular

    Joined:
    Jul 21, 2010
    #8
    Code:
    system("cd ~/Library/Application\ Support/ftblauncher\");
    how about that? with the \ escape character
     
  9. Moderator

    Nermal

    Staff Member

    Joined:
    Dec 7, 2002
    Location:
    Whakatane, New Zealand
    #9
    Doh! I don't know why I didn't suggest that :)
     
  10. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #10
    Using the "system" function is dangerous. Step back from your immediate problem, do some reading on the internet, and then go back to it. You should read up about bash, and you should read up about "code injections": Code injections are a class of bugs created by naïve programmers that allow hackers to attack their systems.

    First step: Google for "bash". "bash" is the shell that will be executing the commands that "system" sends, so the first thing is you need to know what to send to bash.

    In this case, bash will try to execute the command

    Code:
    cd ~/Library/Application Support/ftblauncher
    And if you start console and enter this command, you will see that it doesn't work. You can put parts of bash commands into quotes, both single quotes or double quotes, and then bash will interpret things in a certain way. Best to read up on the exact rules, and then you will find out what to do if a filename contains a space character, for example. Or if it contains a quote character. Or if you have a file named weird\\""filename.

    Next, get a good C book that explains escape characters in string literals. Try writing a program that prints

    Code:
    "Hello, world!"
    including the quote characters. Then write a program that prints

    Code:
    "Hello, %fine% world!"
    including the quote characters and the percent characters. If you managed that, you'll get the idea.
     
  11. thread starter macrumors member

    Joined:
    Mar 27, 2012
    #11
    Hey guys, thanks for your responses. What I'm trying to do is make a program that goes into a directory and unzips a file there. In terminal I can use "cd" to go to a directory and then just use "unzip file.zip" to unzip the file. How would I do this in a C/Objective-C program?
     
  12. ytk
    macrumors regular

    Joined:
    Jul 8, 2010
    #12
    Well, you probably shouldn't be doing whatever it is you're trying to do. :p

    But if you're hell-bent on calling unzip from within a C program, there are two ways you could do so. You could call unzip with the absolute path to the zip file as an argument, then the folder containing the zip file as an option using -d, like so:

    Code:
    system("unzip /path/to/zip\\ file/myfile.zip -d /path/to/zip\\ file/");
    The other way to do it would be to chain multiple commands together in a single system call using either && or ; (preferably &&, since that will only execute subsequent statements if each statement succeeds):

    Code:
    system("cd /path/to/zip\\ file/ && unzip myfile.zip");
    Either one of those would work. You could also muck around with chdir() to change the working directory, but I wouldn't recommend it since you only really want to change the working directory of a child process, not the parent process itself.
     
  13. thread starter macrumors member

    Joined:
    Mar 27, 2012
    #13
    Thanks, I'll try that out. The reason I need to do this is to help me with launching a mod pack in minecraft (for anyone who doesn't know, minecraft is a popular online game). I downloaded a cool mod pack for minecraft but there's a small bug in the program that causes it to crash on some macs (including mine). This is due to a file being named incorrectly. At the directory ~/Library/Application Support/ftblauncher/ there is a file name "locales.zip" which should be named "locale.zip" (no 's'). This causes the program to crash while looking for it. I can unzip the folder and change its name to "locale" manually, but unfortunately the name gets changed back whenever I exit minecraft. So I'd like to create a handy "helper program" that checks to see if "locales.zip" is there instead of "locale.zip". If it is I want the program to unzip "locales.zip" and change the folder name to "locale". Finally it should launch the java program. I've had no trouble checking to see if "locales.zip" is there, I'm just having trouble unzipping it.
     
  14. macrumors 6502a

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #14
    Sounds like something that can be done by a shell script.
     
  15. ytk
    macrumors regular

    Joined:
    Jul 8, 2010
    #15
    Agreed, using C for this is absolutely overkill. If you do write that program, please send me the source code so I can submit it to The Daily WTF. :D

    What happens if you just symlink "locale" to "locales"? The command to do this, in case you don't know, is (from within the ftblauncher directory):
    Code:
    ln -s locales locale
    Try running this command (just once). From then on, any attempt to look for a file in the "locale" folder will automatically be rerouted to the "locales" folder. The cool thing is you can do this even if the "locales" folder doesn't always exist, so even if the game unpacks the zip file to the locales folder just before running, the symlink will still point to the correct folder as long as it exists.
     

Share This Page