NSLog broken after call of NSTask and setStandardError

  • Hello,
    I'm new to cocoa and obj c programming. Thanks to such great mailling lists
    like this one here, I have learned a lof during the last weeks. However here
    is something I cannot cope with:

    Code:
    --------

    I use this cocoa method to execute shell commands and shell scripts form my
    cocoa app:
    - (void)executeShellScript:(NSString*)path withArgs:(NSArray*)args {
        NSLog(@"Testing NSLog: Entry");
        NSString *fullpath = [path stringByExpandingTildeInPath];
        NSFileManager *fm = [NSFileManager defaultManager];
        if ([fm fileExistsAtPath:fullpath]) {
            NSTask *shellProcess = [[NSTask alloc] init];
            NSPipe *errorPipe = [[NSPipe alloc] init];
            [shellProcess setLaunchPath:fullpath];
            [shellProcess setArguments:args];
            [shellProcess setStandardError:errorPipe];
            [shellProcess launch];
            [shellProcess waitUntilExit];
            NSData *result = [[errorPipe fileHandleForReading]
    readDataToEndOfFile];
            if ([result length]>1) {
                NSString *error = [[NSString alloc] initWithData:result
    encoding:NSASCIIStringEncoding];
                NSLog(error); //Normally I would show an error dialog with a
    NSTextView here
                [error release];
            }
            [shellProcess release];
        }
        else {
            NSString *error = [fullpath stringByAppendingString:@": File does
    not exist"];
            NSLog(error); //Normally I would show an error dialog with a
    NSTextView here
        }
        NSLog(@"Testing NSLog: Exit");
    }

    Problem:
    -------

    At the first glance: no problems! I can call shell commands, shell scripts
    and retrieve stderr from the shell and display this stuff in cocoa.
    The probelm is:
    - When I call above method e.g. with [self
    executeShellScript:@"/Users/siemoneit/Documents/LocationManager/heim/activate.sh"
    withArgs:args];, .i.e. I try to execute a shell script, NSLog gets broken,
    only outputs in the console "Testing NSLog: Entry" + "Hello" (=some ouput of
    the shell script via echo) and nothing more. Further NSLog ouput is lost
    totally. NSLog remains broken. You have to restart the app.
    This is the shell script I call:
    #!/bin/bash
    echo Hello
    exit 0

    - When I call above method e.g. with [self executeShellScript:@"/bin/ls"
    withArgs:args]; i.e. with a shell command, everything works fine! NSLog
    doesn't get broken. Everything goes smoothly and nicely. The output is the
    console is as expected: "Testing NSLog:Entry" + the command output +
    "Testing NSLog: Exit". NSLog doesn't get broken.
    What am I missing? What am I doing wrong? This drives me nuts...
    Therefore: Any hint is highly appreciated!
    Many thanks,
    Oliver
  • Oliver,

    Not sure why there's a disparity between your script and /bin/ls, but
    they should both be writing to stdout, whereas your NSPipe is
    attempting to read from stderr. Presumably the "Hello" and the output
    of /bin/ls are being written to console without NSLog-style
    timestamps?

    Hamish

    On Jan 15, 2008 9:38 PM, Oliver Siemoneit <oliver.siemoneit...> wrote:
    > Hello,
    > I'm new to cocoa and obj c programming. Thanks to such great mailling lists
    > like this one here, I have learned a lof during the last weeks. However here
    > is something I cannot cope with:
    >
    > Code:
    > --------
    >
    > I use this cocoa method to execute shell commands and shell scripts form my
    > cocoa app:
    > - (void)executeShellScript:(NSString*)path withArgs:(NSArray*)args {
    > NSLog(@"Testing NSLog: Entry");
    > NSString *fullpath = [path stringByExpandingTildeInPath];
    > NSFileManager *fm = [NSFileManager defaultManager];
    > if ([fm fileExistsAtPath:fullpath]) {
    > NSTask *shellProcess = [[NSTask alloc] init];
    > NSPipe *errorPipe = [[NSPipe alloc] init];
    > [shellProcess setLaunchPath:fullpath];
    > [shellProcess setArguments:args];
    > [shellProcess setStandardError:errorPipe];
    > [shellProcess launch];
    > [shellProcess waitUntilExit];
    > NSData *result = [[errorPipe fileHandleForReading]
    > readDataToEndOfFile];
    > if ([result length]>1) {
    > NSString *error = [[NSString alloc] initWithData:result
    > encoding:NSASCIIStringEncoding];
    > NSLog(error); //Normally I would show an error dialog with a
    > NSTextView here
    > [error release];
    > }
    > [shellProcess release];
    > }
    > else {
    > NSString *error = [fullpath stringByAppendingString:@": File does
    > not exist"];
    > NSLog(error); //Normally I would show an error dialog with a
    > NSTextView here
    > }
    > NSLog(@"Testing NSLog: Exit");
    > }
    >
    >
    > Problem:
    > -------
    >
    > At the first glance: no problems! I can call shell commands, shell scripts
    > and retrieve stderr from the shell and display this stuff in cocoa.
    > The probelm is:
    > - When I call above method e.g. with [self
    > executeShellScript:@"/Users/siemoneit/Documents/LocationManager/heim/activate.sh"
    > withArgs:args];, .i.e. I try to execute a shell script, NSLog gets broken,
    > only outputs in the console "Testing NSLog: Entry" + "Hello" (=some ouput of
    > the shell script via echo) and nothing more. Further NSLog ouput is lost
    > totally. NSLog remains broken. You have to restart the app.
    > This is the shell script I call:
    > #!/bin/bash
    > echo Hello
    > exit 0
    >
    > - When I call above method e.g. with [self executeShellScript:@"/bin/ls"
    > withArgs:args]; i.e. with a shell command, everything works fine! NSLog
    > doesn't get broken. Everything goes smoothly and nicely. The output is the
    > console is as expected: "Testing NSLog:Entry" + the command output +
    > "Testing NSLog: Exit". NSLog doesn't get broken.
    > What am I missing? What am I doing wrong? This drives me nuts...
    > Therefore: Any hint is highly appreciated!
    > Many thanks,
    > Oliver
    >
  • Hello Hamish,

    thank you very much for your comment! Yes you are right: The output of my
    script (or a shell command like ls) should be written to stdout which also
    appears in the console window.
    But that's strange: after calling a shell script with my code, I can get no
    ouput in the console window anymore: it's broken. No logs form NSLog, no
    stdout from shell scripts. Console output is simply dead.
    But this also means: not only NSLog is broken but something else, too.
    So I did some more testing: I took out all the code with NSPipe and
    setStandardError and reran the code again. The same result! That means: the
    console window gets broken by simply calling a shell script (myscript.sh)
    instead of a shell command (e.g. ls). It has noting to do with the piping
    stuff. So the correct title of my question to this mailing list would be
    therefore: "Console output gets broken after call of a shell script (not a
    shell command!) via NSTask".

    Is there an explanation for this? Or am I doing something wrong?

    Cheers,
    Oliver

    ----- Original Message -----
    From: "Hamish Allan" <hamish...>
    To: "Oliver Siemoneit" <oliver.siemoneit...>
    Cc: <cocoa-dev...>
    Sent: Wednesday, January 16, 2008 8:03 PM
    Subject: Re: NSLog broken after call of NSTask and setStandardError

    > Oliver,
    >
    > Not sure why there's a disparity between your script and /bin/ls, but
    > they should both be writing to stdout, whereas your NSPipe is
    > attempting to read from stderr. Presumably the "Hello" and the output
    > of /bin/ls are being written to console without NSLog-style
    > timestamps?
    >
    > Hamish
    >
    > On Jan 15, 2008 9:38 PM, Oliver Siemoneit <oliver.siemoneit...> wrote:
    >> Hello,
    >> I'm new to cocoa and obj c programming. Thanks to such great mailling
    >> lists
    >> like this one here, I have learned a lof during the last weeks. However
    >> here
    >> is something I cannot cope with:
    >>
    >> Code:
    >> --------
    >>
    >> I use this cocoa method to execute shell commands and shell scripts form
    >> my
    >> cocoa app:
    >> - (void)executeShellScript:(NSString*)path withArgs:(NSArray*)args {
    >> NSLog(@"Testing NSLog: Entry");
    >> NSString *fullpath = [path stringByExpandingTildeInPath];
    >> NSFileManager *fm = [NSFileManager defaultManager];
    >> if ([fm fileExistsAtPath:fullpath]) {
    >> NSTask *shellProcess = [[NSTask alloc] init];
    >> NSPipe *errorPipe = [[NSPipe alloc] init];
    >> [shellProcess setLaunchPath:fullpath];
    >> [shellProcess setArguments:args];
    >> [shellProcess setStandardError:errorPipe];
    >> [shellProcess launch];
    >> [shellProcess waitUntilExit];
    >> NSData *result = [[errorPipe fileHandleForReading]
    >> readDataToEndOfFile];
    >> if ([result length]>1) {
    >> NSString *error = [[NSString alloc] initWithData:result
    >> encoding:NSASCIIStringEncoding];
    >> NSLog(error); //Normally I would show an error dialog with a
    >> NSTextView here
    >> [error release];
    >> }
    >> [shellProcess release];
    >> }
    >> else {
    >> NSString *error = [fullpath stringByAppendingString:@": File does
    >> not exist"];
    >> NSLog(error); //Normally I would show an error dialog with a
    >> NSTextView here
    >> }
    >> NSLog(@"Testing NSLog: Exit");
    >> }
    >>
    >>
    >> Problem:
    >> -------
    >>
    >> At the first glance: no problems! I can call shell commands, shell
    >> scripts
    >> and retrieve stderr from the shell and display this stuff in cocoa.
    >> The probelm is:
    >> - When I call above method e.g. with [self
    >> executeShellScript:@"/Users/siemoneit/Documents/LocationManager/heim/activate.sh"
    >> withArgs:args];, .i.e. I try to execute a shell script, NSLog gets
    >> broken,
    >> only outputs in the console "Testing NSLog: Entry" + "Hello" (=some ouput
    >> of
    >> the shell script via echo) and nothing more. Further NSLog ouput is lost
    >> totally. NSLog remains broken. You have to restart the app.
    >> This is the shell script I call:
    >> #!/bin/bash
    >> echo Hello
    >> exit 0
    >>
    >> - When I call above method e.g. with [self executeShellScript:@"/bin/ls"
    >> withArgs:args]; i.e. with a shell command, everything works fine! NSLog
    >> doesn't get broken. Everything goes smoothly and nicely. The output is
    >> the
    >> console is as expected: "Testing NSLog:Entry" + the command output +
    >> "Testing NSLog: Exit". NSLog doesn't get broken.
    >> What am I missing? What am I doing wrong? This drives me nuts...
    >> Therefore: Any hint is highly appreciated!
    >> Many thanks,
    >> Oliver
    >>
    >
  • On Jan 17, 2008 12:11 AM, Oliver Siemoneit <oliver.siemoneit...> wrote:

    > Is there an explanation for this? Or am I doing something wrong?

    Not sure why it's happening, but the first thing I'd try would be
    something other than bash, e.g.,

    #!/usr/bin/python -u
    print 'hello'

    Hamish
  • On 15.01.2008, at 22:38, Oliver Siemoneit wrote:

    > Hello,
    > I'm new to cocoa and obj c programming. Thanks to such great
    > mailling lists like this one here, I have learned a lof during the
    > last weeks. However here is something I cannot cope with:

    Shortcut: Retry it with the Moriarty sample code. <http://developer.apple.com/samplecode/Moriarity/>.

    I was under the impression you even could open only binaries with
    NSTask, but apparently I was wrong. As a fist attempt I'd launch bash
    via NSTask with the shell file and see if that works.

    Debug tools: The 'lsof' command might give you some hints which files
    & fd's are considered open by the OS.

    HTH,
    Tom_E
  • Hello altogether,

    thank you very much for your input! It was very helpful. As Hamish suggested
    I have tried to use another shell, tcsh instead of bash, and suprisingly the
    problem vanished! The console output remains intact with this script

    #!/bin/tcsh
    echo hello

    and breaks with this shell script

    #!/bin/bash
    echo hello

    But I don't know why... Is this worth a bug report? Or is there a way to
    keep bash from breaking the console output?
    Oliver

    ----- Original Message -----
    From: "Hamish Allan" <hamish...>
    To: "Oliver Siemoneit" <oliver.siemoneit...>
    Cc: <Cocoa-dev...>
    Sent: Thursday, January 17, 2008 2:24 AM
    Subject: Re: NSLog broken after call of NSTask and setStandardError

    > On Jan 17, 2008 12:11 AM, Oliver Siemoneit <oliver.siemoneit...>
    > wrote:
    >
    >> Is there an explanation for this? Or am I doing something wrong?
    >
    > Not sure why it's happening, but the first thing I'd try would be
    > something other than bash, e.g.,
    >
    > #!/usr/bin/python -u
    > print 'hello'
    >
    > Hamish
    >
  • On Jan 17, 2008 8:19 PM, Oliver Siemoneit <oliver.siemoneit...> wrote:

    > But I don't know why... Is this worth a bug report? Or is there a way to
    > keep bash from breaking the console output?

    I don't know why either, but for further diagnosis try "#!/bin/bash
    -i" and "#!/bin/bash -l"

    Hamish
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today