Multi-task rsync command within ASOC app

I want to write a small app that can start off up to 3 instances of rsync. How do I initiate 3 threads of this command? I can only seem to do one command line at a time right now (skill level!) using the ‘do shell script’ command. Can someone point me in the right direction?

Thank you!

You might be able to use NSTask to run multiple commands concurrently.

Example:


    on caffeinateSystem_(sender)
        
        -- SET UP THE NSTASK
        set pmsetTask to current application's NSTask's alloc()'s init()
        pmsetTask's setLaunchPath_("/usr/bin/pmset")
        pmsetTask's setArguments_({"noidle"})
        
        -- LAUNCH THE NSTASK
        pmsetTask's |launch|()
        
    end caffeinateSystem_

If you need to get the output of the task, you can set up NSPipe like this:


property pingTask : missing value

on runPingTest_(sender)
    
            set pingTask to current application's NSTask's alloc()'s init()
            set outputPipe to current application's NSPipe's pipe()
            pingTask's setStandardOutput_(outputPipe)
            pingTask's setStandardError_(outputPipe)
            pingTask's setLaunchPath_("/sbin/ping")
            pingTask's setArguments_({"-c", "25", "google.com"})
    
                                current application's NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "pingReadPipe:", "NSFileHandleReadCompletionNotification", pingTask's standardOutput()'s fileHandleForReading())
    
                                current application's  NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "pingEndPipe:", "NSTaskDidTerminateNotification", pingTask)
    
            pingTask's standardOutput()'s fileHandleForReading()'s readInBackgroundAndNotify()
    
            pingTask's |launch|()

end runPingTest_


 on pingReadPipe_(aNotification)
    
        set dataString to aNotification's userInfo's objectForKey_("NSFileHandleNotificationDataItem")
        set newString to ((current application's NSString's alloc()'s initWithData_encoding_(dataString, current application's NSUTF8StringEncoding)))
        -- do other stuff

 end pingReadPipe_

on pingEndPipe_(aNotification)

current application's  NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSTaskDidTerminateNotification", pingTask)
                    current application's  NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSFileHandleReadCompletionNotification", pingTask's standardOutput()'s fileHandleForReading())

end pingEndPipe_

Thank you much! I will apply this code and post back as necessary!

Best wishes,
Ryan

I must have a thick skull as I can’t seem to correctly apply your sample code to ‘rsync’.

My goal is to have to app ask the user up front for a source, and up to 3 destinations. Then, the app will note how many destinations were specified and start up to 3 instances of rsync using the same source.

I can’t get the code correct for one source, one destination. This is an exercise for me since I know how to simply do this in Terminal. I’d like to challenge myself with a GUI app. Do you happen to have a moment to customize the code above for the rsync binary?

I haven’t ever really used rsync for anything, but this worked for me:


    set aSource to posix path of (choose folder with prompt "Choose a source:")
    set aDestination to posix path of (choose folder with prompt "Choose a destination:")
    
    set rsyncTask to current application's NSTask's alloc()'s init()
    rsyncTask's setLaunchPath_("/usr/bin/rsync")
    rsyncTask's setArguments_({"-r", aSource, aDestination})
    
    rsyncTask's |launch|()

What specifically is not working for you? Are you receiving any errors or warnings?

Update:
Here’s a slightly more complicated version:


    
	property rsyncTask : missing value
    
	-- Application launches, runs task handler    
	on applicationWillFinishLaunching_(aNotification)
		my runTask_(me)
	end applicationWillFinishLaunching_


	on runTask_(sender)

		-- ask user to define source and destination
		set aSource to posix path of (choose folder with prompt "Choose a source:")
		set aDestination to posix path of (choose folder with prompt "Choose a destination:")
        
		-- set up nstask/rsync
		set rsyncTask to current application's NSTask's alloc()'s init()
		set outputPipe to current application's NSPipe's pipe()
		rsyncTask's setStandardOutput_(outputPipe)
		rsyncTask's setStandardError_(outputPipe)
		rsyncTask's setLaunchPath_("/usr/bin/rsync")
		rsyncTask's setArguments_({"-rv", aSource, aDestination})
    
		-- set up notification center observers
		current application's NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "rsyncTaskReadPipe:", "NSFileHandleReadCompletionNotification", (rsyncTask's standardOutput()'s fileHandleForReading()))

		current application's NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "rsyncEndPipe:", "NSTaskDidTerminateNotification", rsyncTask)

		rsyncTask's standardOutput()'s fileHandleForReading()'s readInBackgroundAndNotify()
        
		rsyncTask's |launch|()
        
	end runTask
    
	-- reading task output
	on rsyncTaskReadPipe_(aNotification)
        
		set dataString to aNotification's userInfo's objectForKey_("NSFileHandleNotificationDataItem")
		set newString to ((current application's NSString's alloc()'s initWithData_encoding_(dataString, current application's NSUTF8StringEncoding)))
        
		log newString
        
		aNotification's object()'s readInBackgroundAndNotify()
        
	end rsyncTaskReadPipe_
    
	-- removing observer when task completes
	on rsyncEndPipe_(aNotification)
		current application's NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSTaskDidTerminateNotification", rsyncTask)
		current application's NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSFileHandleReadCompletionNotification", rsyncTask's standardOutput()'s fileHandleForReading())
		log "complete"
	end rsyncEndPipe_

You nailed it with that script. Thank you.