Running BASH script from iPhone app? - iphone

Basically I am wondering if it is possible to run a console script (.sh) from an iPhone App. The script is written to download a program from a repository that I set up, respring, then after a set time delete the program and respring again, so it needs root privileges, and is interactive in that the user can set how long the program will be kept. I have the bash script written, and it works fine when called from mobile terminal, but is there any way to do this from within a (jailbroken) app (without using mobile terminal / SSH / Bossprefs)? Or is there an overall better way to achieve this?
Thanks

Jasarien is right here it is pretty resticted and as we all know that all apps are sandboxed. But it is not impossible since Objective-C is just build on C you can use
system("ls");
to execute a basic ls command and it works if you look in your gdb output. Altho you can also use popen to get the streams to app to work with the data.

Since you're working with a Jailbroken phone, you're pretty much unrestricted. Whether or not there's anything in the iPhone APIs that allows for script execution is another matter though. Also anything you do use will be unsupported, and is likely to change, stop working or be removed in a software update.
Also, you probably already know this, or don't care, but you won't get past Apple's review process for the App Store if you start running BASH scripts. Interpreted code is forbidden.

I would look up how to do it on OSX, chances are that'll be how it's done on the iPhone, but you probably won't find any iPhone specific documentation about it because it's not allowed on a "normal" iphone (one that is not jailbroken)

something you may consider is using NSTask if you want to get output and error messages from the shell.

Actualy
system('ls /'); gives a better result as system('ls');

Related

iOS app to run script

I would appreciate help in creating an iOS app to run a specified script at /var/mobile/script.sh. The script I have written opens a number of specified apps "all at once" on my jailbroken 6.1.2 iphone. Currently I run the script by starting MobileTerminal and manually running the script.sh file from the command line. I would like to be able to create an app that I could start via the Springboard which would run /var/mobile/script.sh directly.
I do not have a Mac and so I am unable to compile an app myself. I also do not have much experience of programming so I would appreciate any help on offer. I have seen an answer which is similar: iOS execute shell script from Activator
The answer provided above is VERY close to what I am looking for. However I have two problems with the Script.app as it stands:
1) As the script I have written opens a number of other apps which takes around two minutes to complete, the Script.app is automatically killed by iOS after about 20 seconds. I'm not sure if a flag "didFinishLaunchingWithOptions" needs to be set to allow Script.app to continue running so it can finish running my script? I have installed a package via Cydia called "Background Manager" - [which as I understand it makes all apps effectively think they are running in the foreground].
2) I have previously tested Script.app listed above on iOS 5 and the Script.app did run for around 20 seconds bringing the apps to the foreground as listed in my script.sh. On iOS 6.1.2 the Script.app runs certain commands in script.sh [e.g. killall commands] but when it comes to opening a specified app via the script it won't open any app [there is a blank black screen for 20 seconds and then the Script app closes without having opened any apps via the script.sh file]. However in iOS 6.1.2 if Script.app is started and immediately the home button is pressed to return you to the Springboard the Script.app will open apps via my script.sh for the first 20 seconds, so there appears to be a difference between the way the Script.app runs on iOS5 vs iOS6. I would like if Script.app could open apps via the script.sh without me having to immediately press the home button after Script.app starts on iOS 6
In my script file I use a command line package called "open" to specific which app to open via its CFBundleIdentifier: http://moreinfo.thebigboss.org/moreinfo/depiction.php?file=openData
Thanks for your help
Here's a technique that should work for you. It's not necessarily the way I'd solve it, but the solution is designed to work around you not having a Mac / Xcode.
One problem is that iOS expects normal "apps" to startup quickly, and begin responding to normal UI application events. If you use my original script launcher, it does not actually create a UIApplication, but simply calls system() from the main program. Assuming the call to system() completes quickly, there's no problem. But, if your script takes 20 seconds to run, that's too long, and iOS will kill the app.
You could build a normal UI application, calling UIApplicationMain(), and starting your long-running script after the app finishes startup. But really, you're not building an app. You simply want to use a SpringBoard icon to kick off a script. So, I don't think that solution makes a lot of sense.
What you probably want is a non-graphical daemon to run your long script for you. For this, you could build a Launch Daemon, and that might be how I solved the problem. But, without Xcode, that's tough. Another option is to take advantage of the privileged daemon that SBSettings has. You can use it to run your script. Then, your "app" need only fire off a notification to tell SBSettings to run that script. It can then exit, almost immediately.
Here is a pre-built binary that invokes a script named com.mycompany.script (get version 1.1). Install this app on your iPhone (it can be installed normally, in the sandbox area).
Then, you'll need to put your script at (this exact path and filename):
/var/mobile/Library/SBSettings/Commands/com.mycompany.script
For example, its contents might be:
#!/bin/sh
/usr/bin/open com.mycompany.AppOne
/usr/bin/open com.mycompany.AppTwo
/usr/bin/open com.mycompany.AppThree
exit 0;
where you're passing app bundle IDs to open. You can put whatever you want inside it. Make sure to login to your iPhone and set the right permissions on your script:
cd /var/mobile/Library/SBSettings/Commands/
chmod 755 com.mycompany.script
chown mobile.mobile com.mycompany.script
and then reboot (re-springing might be enough to get SBSettings to recognize your new script).
Note: for those who are coders, the main program of this app basically just contains this code:
#include <notify.h>
int main(int argc, char *argv[])
{
notify_post("com.mycompany.script");
return 0;
}

Launch installed app on tethered iPhone

I'm working on trying to launch an automated testing solution for some iOS applications. I'm using fruitstrap to transfer and install a compiled app over to the connected iPhone, but I'm struggling to find a way to automatically launch the application after the installation is complete.
Fruitstrap has an option to run the app in the GDB debugger, which works. Unfortunately there are some test cases which will require the app to be run without the debugger attached (special crash handling). I've spent a good amount of time muddling through the resources available on MobileDevice Library which is what Fruitstrap uses, but I haven't been able to turn anything up on launching an App.
Any ideas?
You can do what you want by using fruitstrap or Xcode to start a "bootstrap" program that causes your target application to run via a custom URL as described by Michael.
While the bootstrap program would be running under the debugger the URL-invoked program would be running normally.
Creating a bootstrap program and using URL Schemes may be an option for some people, and certainly should be considered, but it doesn't fit into my requirements.
What I ended up doing was to launch the app with the debugger through fruitstrap. I re-compiled fruitstrap to include the following prep commands (In the GDB_PREP_CMDS define):
handle all noprint pass nostop
continue
The handle will pass the signal on to the program so the custom signal handler (crash handler in this case) will handle the signal. The continue was something I needed so that the app would actually run once the debugger started.
There is one unfortunate flaw in this, which unfortunately I do not know a workaround for. The ARM7 version of GDB does not have the 'set dont_handle_bad_access' command like the darwin version does. For some reason passing EXC_BAD_ACCESS signals to the program does not work and the app hangs. This is significant since this is the signal for most crashes. But as it stands now, its the best I can do, and at least its handling uncaught exceptions.
I believe you may be looking for some sort of Custom URL Scheme.
Have a look at the following document and scroll down to: Implementing Custom URL Schemes
http://developer.apple.com/library/ios/#DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/AdvancedAppTricks/AdvancedAppTricks.html
You can also google URL Schemes in iOS to see if you come across something similar to what you are trying to do.
Let me know if this helped you out. Would be interesting to hear if you had any success.
Cheers.

Profiling a running iOS app without a computer attached

I would like to profile a running app without a computer attached. Pretty much what the sample command does on Mac OS X. Is it possible ?
I would like to do this without any computer attached because my app gets into an endless loop only at certain GPS locations. I tried reproducing the problem by faking GPS fixes but I couldn't. Yet the issue is 100% reproductible in the field…
You can try logging suspected method and loop entry/exits to a file, and recover the file later using iTunes Document sharing or Xcode.
No - I'm pretty sure it isn't, as Apple does not allow developers to use any iOS-development tools on the platform itself. You might be able to build analytical stuff into your own app (RAM monitor etc.), but not by using another app.
Anyway, your computer is much better suited to the task than a device - so sick with it.
Maybe some day Apple will let us test/write iPhone apps from iPads...

Downloading photos from a (USB-connected) iPhone programmatically

I'm wondering if it's possible to access the Camera Roll on the iPhone programmatically. Some background: I want to basically run a cron job every night that will download all the (preferably new since last time) photos from my iPhone to a folder on my computer. I'm using a Mac, and I'm not terrifically concerned with interoperability — I suspect doing this in a platform-agnostic way is probably a lot more trouble than it's worth (if it's even possible).
Basically the only requirement here is that the program/script needs to be able to be invoked from the shell, which essentially everything can, so really I don't care what language it is in. Once the photos are downloaded I intend to run a Python script of mine to do what I will with them.
I suspect the easiest way to do this may be with (deep breath) AppleScript to the Image Capture application on every Mac. But maybe others have better ideas, or any experience with using the AppleScript approach?
You can use the ImageCaptureCore framework to download photos over PTP.
I guess the easiest and most comfortable solution would be to use Automator for that, using the "Download Pictures" action in a workflow and invoking it from a shell using "automator".

NSPipe and System() - iPhone SDK Cocoa

I need to add this section into my application where the user would enter in a terminal command for example "killall SpringBoard" and when the user presses the button it would run the command. I know that if you use the System("") function you can run the terminal command. But how about from a textbox?
My next question is if it is possible to retrieve the result of the terminal command using NSPipe? If so how? Note I am using the phrase 'terminal command' since i'm not really sure what its called (If someone knows please tell me...). Basically the same thing as the commands in MobileTerminal...
Thanks,
Kevin
If you plan on submitting your app to the AppStore, it will never get approved with a feature set like that.
… how about from a textbox?
Rhetorical question: What do your views have to do with the system function?
My next question is if it is possible to retrieve the result of the terminal command using NSPipe?
Yes.
If so how?
Abandon the system function, and use fork and one of the exec functions directly. (There's no NSTask on the iPhone—not in the iPhone API documentation, anyway.)
Considering your plan is to kill the SpringBoard, I hope that you're targeting the jailbreak platform, not the App Store. Like greg, I would expect Apple to reject your app if you try any such thing. I can't even imagine why you want to do that.