কোকো অ্যাপ্লিকেশন থেকে টার্মিনাল কমান্ড কার্যকর করুন


204

আমি grepআমার অবজেক্টিভ-সি কোকো অ্যাপ্লিকেশন থেকে টার্মিনাল কমান্ড (লাইক ) কীভাবে কার্যকর করতে পারি ?


2
আমি কেবল স্পষ্ট করে বলছি: স্যান্ডবক্সিংয়ের সাহায্যে আপনি কেবল এমন অ্যাপ্লিকেশন শুরু করতে পারবেন না যা আপনার স্যান্ডবক্সে নেই এবং
এটির

@ দাইজ-দাজন এটি মোটেও সত্য নয়, কমপক্ষে ম্যাকোজে নেই। একটি স্যান্ডবক্সযুক্ত ম্যাকোস অ্যাপ্লিকেশন /usr/binযেখানে যেখানে grepবাস করে সেখানে কোনও বাইনারি চালাতে পারে ।
জেফ-এইচ

না। দয়া করে আমাকে ভুল প্রমাণ করুন;) ist nstask আপনার স্যান্ডবক্সে কিছু চালাতে ব্যর্থ হবে।
দাইজ-Djan

উত্তর:


282

আপনি ব্যবহার করতে পারেন NSTask। এখানে একটি উদাহরণ যা চালিত হবে ' /usr/bin/grep foo bar.txt'।

int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/grep";
task.arguments = @[@"foo", @"bar.txt"];
task.standardOutput = pipe;

[task launch];

NSData *data = [file readDataToEndOfFile];
[file closeFile];

NSString *grepOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"grep returned:\n%@", grepOutput);

NSPipe এবং NSFileHandle কার্যটির স্ট্যান্ডার্ড আউটপুট পুনর্নির্দেশের জন্য ব্যবহৃত হয়।

আপনার উদ্দেশ্য-সি প্রয়োগের মধ্যে থেকেই অপারেটিং সিস্টেমের সাথে ইন্টারঅ্যাক্ট করার আরও বিশদ তথ্যের জন্য আপনি অ্যাপল এর বিকাশ কেন্দ্রটিতে এই নথিটি দেখতে পাবেন: অপারেটিং সিস্টেমের সাথে ইন্টারঅ্যাক্টিং

সম্পাদনা: এনএসএলগ সমস্যার সমাধান অন্তর্ভুক্ত

আপনি যদি ব্যাশের মাধ্যমে কমান্ড-লাইন ইউটিলিটি চালানোর জন্য এনএসটিস্ককে ব্যবহার করছেন, তবে এনএসএলগকে কাজ করতে আপনাকে এই ম্যাজিক লাইনটি অন্তর্ভুক্ত করতে হবে:

//The magic line that keeps your log where it belongs
task.standardOutput = pipe;

একটি ব্যাখ্যা এখানে রয়েছে: https://web.archive.org/web/20141121094204/https://cocoadev.com/HowToPipeCommandsWithNSTask



14
আপনার উত্তরে একটি ছোট্ট ভুল আছে। এনএসপাইপের একটি বাফার রয়েছে (ওএস লেভেলে সেট করা হয়েছে), যা পড়লে তা ফ্লাশ হয়। যদি বাফার পূরণ করে তবে এনএসটিস্ক হ্যাং হয়ে যাবে এবং আপনার অ্যাপ্লিকেশনটিও অনির্দিষ্টকালের জন্য স্তব্ধ হয়ে যাবে। কোনও ত্রুটি বার্তা উপস্থিত হবে না। এটি ঘটতে পারে যদি এনএসটিস্ক্ক প্রচুর তথ্য ফেরত দেয়। সমাধানটি ব্যবহার করা হয় NSMutableData *data = [NSMutableData dataWithCapacity:512];। তারপরে while ([task isRunning]) { [data appendData:[file readDataToEndOfFile]]; },। এবং আমি "বিশ্বাস করি" [data appendData:[file readDataToEndOfFile]];যখন কিছুক্ষণের লুপটি প্রস্থান করার পরে আপনার আরও একটি হওয়া উচিত ।
ডেভ গ্যালাগার

2
আপনি এটি না করলে ত্রুটিগুলি উপস্থিত হবে না (তারা কেবল লগে মুদ্রিত হয়ে যায়): [টাস্ক সেটস স্ট্যান্ডার্ডেরর: পাইপ];
মাইক স্প্রেগ

1
এটিআরসি এবং ওবজে-সি অ্যারে লিটারাল সহ আপডেট করা যেতে পারে। যেমন পেস্টবিন.
com

1
ত্রুটিগুলি পাইপ করাও এটি একটি ভাল ধারণা। task.standardError = pipe;
vqdave

43

কেন্টের নিবন্ধটি আমাকে একটি নতুন ধারণা দিয়েছে। এই রানকমন্ড পদ্ধতিতে স্ক্রিপ্ট ফাইলের দরকার নেই, কেবল একটি লাইনের মাধ্যমে একটি কমান্ড চালায়:

- (NSString *)runCommand:(NSString *)commandToRun
{
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/bin/sh"];

    NSArray *arguments = [NSArray arrayWithObjects:
                          @"-c" ,
                          [NSString stringWithFormat:@"%@", commandToRun],
                          nil];
    NSLog(@"run command:%@", commandToRun);
    [task setArguments:arguments];

    NSPipe *pipe = [NSPipe pipe];
    [task setStandardOutput:pipe];

    NSFileHandle *file = [pipe fileHandleForReading];

    [task launch];

    NSData *data = [file readDataToEndOfFile];

    NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return output;
}

আপনি এই পদ্ধতিটি এভাবে ব্যবহার করতে পারেন:

NSString *output = runCommand(@"ps -A | grep mysql");

1
এটি বেশিরভাগ ক্ষেত্রে ভাল পরিচালনা করে তবে আপনি যদি এটি লুপে চালান তবে অবশেষে অনেকগুলি ওপেন ফাইল হ্যান্ডলগুলির কারণে এটি ব্যতিক্রম করে। যোগ করে স্থির করা যায়: [ফাইল ক্লোজফিল]; ReadDataToEndOfFile পরে।
ডেভিড স্টেইন

@ ডেভিডস্টাইন: আমি মনে করি রান কম্যান্ড পদ্ধতিটি মোড়ানোর জন্য অটোরিলিজপুল ব্যবহার করা তার চেয়ে মনে হচ্ছে। আসলে, উপরের কোডটি নন-এআরসিটিকেও বিবেচনা করে না।
কেনিয়াল

@ কেনিয়াল: ওহ, এটি আরও অনেক ভাল সমাধান। এটি সুযোগ ছেড়ে যাওয়ার পরে অবিলম্বে রিসোর্সগুলি প্রকাশ করে।
ডেভিড স্টেইন

/ বিন / পিএস: অপারেশন অনুমোদিত নয়, আমি কোন সাফল্য পাচ্ছি না, নেতৃত্ব?
নমন বৈষ্ণব

40

ভাগ করে নেওয়ার চেতনায় ... এটি শেল স্ক্রিপ্টগুলি চালানোর জন্য আমি প্রায়শই ব্যবহার করি। আপনি আপনার পণ্য বান্ডেলে (বিল্ডের অনুলিপি পর্যায়ে) একটি স্ক্রিপ্ট যুক্ত করতে পারেন এবং তারপরে স্ক্রিপ্টটি রানটাইম পড়তে এবং চালাতে পারেন। দ্রষ্টব্য: এই কোডটি ব্যক্তিগত ফ্রেমওয়ার্কগুলি উপ-পথে স্ক্রিপ্টটির সন্ধান করে। সতর্কতা: এটি মোতায়েন করা পণ্যগুলির জন্য একটি সুরক্ষা ঝুঁকি হতে পারে, তবে আমাদের অভ্যন্তরীণ বিকাশের জন্য অ্যাপ্লিকেশনটিকে পুনরায় সংকলন না করে সহজ জিনিসগুলি (যেমন হোস্টের কাছে রিসাইঙ্ক করা যায় ...) কাস্টমাইজ করার সহজ উপায়, তবে কেবল সম্পাদনা সম্পাদনা করা বান্ডিল শেল স্ক্রিপ্ট।

//------------------------------------------------------
-(void) runScript:(NSString*)scriptName
{
    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/sh"];

    NSArray *arguments;
    NSString* newpath = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] privateFrameworksPath], scriptName];
    NSLog(@"shell script path: %@",newpath);
    arguments = [NSArray arrayWithObjects:newpath, nil];
    [task setArguments: arguments];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *string;
    string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    NSLog (@"script returned:\n%@", string);    
}
//------------------------------------------------------

সম্পাদনা: এনএসএলগ সমস্যার সমাধান অন্তর্ভুক্ত

আপনি যদি ব্যাশের মাধ্যমে কমান্ড-লাইন ইউটিলিটি চালানোর জন্য এনএসটিস্ককে ব্যবহার করছেন, তবে এনএসএলগকে কাজ করতে আপনাকে এই ম্যাজিক লাইনটি অন্তর্ভুক্ত করতে হবে:

//The magic line that keeps your log where it belongs
[task setStandardInput:[NSPipe pipe]];

প্রেক্ষাপটে:

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
//The magic line that keeps your log where it belongs
[task setStandardInput:[NSPipe pipe]];

একটি ব্যাখ্যা এখানে: http://www.cocoadev.com/index.pl?NSTask


2
ব্যাখ্যার লিঙ্কটি মারা গেছে।
জনি

আমি এই কমান্ডটি "সিস্টেম_প্রফিটার এসপি অ্যাপ্লিকেশনস ডেটাটাইপ-এক্সএমএল" চালাতে চাই তবে আমি এই ত্রুটিটি পাচ্ছি "লঞ্চ পাথ অ্যাক্সেসযোগ্য নয়"
বিকাশ বানসাল

25

এটি সুইফটে কীভাবে করবেন তা এখানে

সুইফট 3.0 এর জন্য পরিবর্তনসমূহ:

  • NSPipe নতুন নামকরণ করা হয়েছে Pipe

  • NSTask নতুন নামকরণ করা হয়েছে Process


এটি উপরের কালিদের উদ্দেশ্য-সি উত্তরের উপর ভিত্তি করে। তিনি যেমন লিখেছেন বিভাগ উপর NSString- সুইফট জন্য, এটি একটি হয়ে এক্সটেনশন এর String

এক্সটেনশন স্ট্রিং.আরুনসকমন্ড () -> স্ট্রিং

extension String {
    func runAsCommand() -> String {
        let pipe = Pipe()
        let task = Process()
        task.launchPath = "/bin/sh"
        task.arguments = ["-c", String(format:"%@", self)]
        task.standardOutput = pipe
        let file = pipe.fileHandleForReading
        task.launch()
        if let result = NSString(data: file.readDataToEndOfFile(), encoding: String.Encoding.utf8.rawValue) {
            return result as String
        }
        else {
            return "--- Error running command - Unable to initialize string from file data ---"
        }
    }
}

ব্যবহার:

let input = "echo hello"
let output = input.runAsCommand()
print(output)                        // prints "hello"

    বা শুধু:

print("echo hello".runAsCommand())   // prints "hello" 

উদাহরণ:

@IBAction func toggleFinderShowAllFiles(_ sender: AnyObject) {

    var newSetting = ""
    let readDefaultsCommand = "defaults read com.apple.finder AppleShowAllFiles"

    let oldSetting = readDefaultsCommand.runAsCommand()

    // Note: the Command results are terminated with a newline character

    if (oldSetting == "0\n") { newSetting = "1" }
    else { newSetting = "0" }

    let writeDefaultsCommand = "defaults write com.apple.finder AppleShowAllFiles \(newSetting) ; killall Finder"

    _ = writeDefaultsCommand.runAsCommand()

}

Processফলাফলটি নোট করুন যেমনটি পড়া থেকে Pipeকোনও NSStringবস্তু। এটি একটি ত্রুটিযুক্ত স্ট্রিং হতে পারে এবং এটি একটি খালি স্ট্রিংও হতে পারে তবে এটি সর্বদা একটি হওয়া উচিত NSString

সুতরাং, যতক্ষণ না এটি শূন্য হয় না, ফলাফলটি একটি সুইফ্ট হিসাবে কাস্ট করতে পারে Stringএবং ফিরে আসতে পারে।

যদি কোনও কারণে NSStringফাইলের ডেটা থেকে শুরু করে না দেওয়া যায় তবে ফাংশনটি একটি ত্রুটি বার্তা দেয় returns Functionচ্ছিকটি ফিরিয়ে দেওয়ার জন্য ফাংশনটি রচনা করা যেতে String?পারে তবে এটি ব্যবহার করা বিশ্রী হবে এবং এটি একটি কার্যকর উদ্দেশ্যটি উপস্থাপন করবে না কারণ এটির সম্ভাবনা খুব কম।


1
সত্যিই দুর্দান্ত এবং মার্জিত উপায়! এই উত্তরের আরও উপায়ে হওয়া উচিত।
XueYu

আপনার যদি আউটপুট না লাগে। রানডম্যান্ড পদ্ধতির উপরে বা তার উপরে @ অস্বীকারযোগ্য রেজাল্ট যুক্তি যুক্ত করুন। এটি আপনাকে ভেরিয়েবলের মধ্যে না রেখেই পদ্ধতিটি কল করতে দেয়।
লয়েড কেইজ্জার

লেট রেজাল্ট = স্ট্রিং (বাইটস: ফাইলহ্যান্ডল.ড্রেড ডেটাটো এন্ডফাইফিল (), এনকোডিং: স্ট্রিং.ইনকোডিং.উইটফ 8) ঠিক আছে
ক্লিএক্সিয়াং

18

উদ্দেশ্য-সি (সুইফ্টের জন্য নীচে দেখুন)

এটিকে আরও পঠনযোগ্য, কম রিডন্ড্যান্ট করার জন্য শীর্ষের উত্তরে কোডটি পরিষ্কার করা হয়েছে, এক-লাইন পদ্ধতির সুবিধা যুক্ত করে একটি এনএসএস স্ট্রিং বিভাগে তৈরি করা হয়েছে

@interface NSString (ShellExecution)
- (NSString*)runAsCommand;
@end

বাস্তবায়ন:

@implementation NSString (ShellExecution)

- (NSString*)runAsCommand {
    NSPipe* pipe = [NSPipe pipe];

    NSTask* task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/sh"];
    [task setArguments:@[@"-c", [NSString stringWithFormat:@"%@", self]]];
    [task setStandardOutput:pipe];

    NSFileHandle* file = [pipe fileHandleForReading];
    [task launch];

    return [[NSString alloc] initWithData:[file readDataToEndOfFile] encoding:NSUTF8StringEncoding];
}

@end

ব্যবহার:

NSString* output = [@"echo hello" runAsCommand];

এবং যদি আপনার আউটপুট এনকোডিংয়ে সমস্যা হয়:

// Had problems with `lsof` output and Japanese-named files, this fixed it
NSString* output = [@"export LANG=en_US.UTF-8;echo hello" runAsCommand];

আশা করি এটি আপনার পক্ষে ততটাই দরকারী যেমন আমার ভবিষ্যতের জন্য হবে। (ওহে তুমি!)


সুইফট 4

এখানে একটি সুইফট উদাহরণ তৈরীর ব্যবহার এর Pipe, ProcessএবংString

extension String {
    func run() -> String? {
        let pipe = Pipe()
        let process = Process()
        process.launchPath = "/bin/sh"
        process.arguments = ["-c", self]
        process.standardOutput = pipe

        let fileHandle = pipe.fileHandleForReading
        process.launch()

        return String(data: fileHandle.readDataToEndOfFile(), encoding: .utf8)
    }
}

ব্যবহার:

let output = "echo hello".run()

2
আসলে, আপনার কোডটি আমার পক্ষে খুব কার্যকর ছিল! আমি এটিকে সুইফটে পরিবর্তন করেছি এবং নীচে অন্য উত্তর হিসাবে পোস্ট করেছি।
এলমারটিক

14

আপনি যদি সত্যই কোনও উদ্দেশ্য-সি নির্দিষ্ট উপায়ের সন্ধান না করেন তবে কাঁটাচামচ , এক্সিকিউট এবং অপেক্ষা করা উচিত। forkবর্তমানে চলমান প্রোগ্রামের একটি অনুলিপি তৈরি করে, execবর্তমানে চলমান প্রোগ্রামটিকে নতুন করে প্রতিস্থাপন করে এবং waitউপ-প্রসেসটি প্রস্থান করার জন্য অপেক্ষা করে। উদাহরণস্বরূপ (কোনও ত্রুটি পরীক্ষা না করে):

#include <stdlib.h>
#include <unistd.h>


pid_t p = fork();
if (p == 0) {
    /* fork returns 0 in the child process. */
    execl("/other/program/to/run", "/other/program/to/run", "foo", NULL);
} else {
    /* fork returns the child's PID in the parent. */
    int status;
    wait(&status);
    /* The child has exited, and status contains the way it exited. */
}

/* The child has run and exited by the time execution gets to here. */

এর রয়েছে সিস্টেম , যা কমান্ডটি চালায় যেন আপনি শেলের কমান্ড লাইন থেকে টাইপ করেন। এটি সহজ, তবে পরিস্থিতির উপর আপনার নিয়ন্ত্রণ কম control

আমি ধরে নিচ্ছি আপনি ম্যাক অ্যাপ্লিকেশনটিতে কাজ করছেন, সুতরাং লিঙ্কগুলি এই ফাংশনগুলির জন্য অ্যাপলের ডকুমেন্টেশনের লিঙ্কগুলি হ'ল তবে সেগুলি সবই POSIXতাই আপনার কোনও পসিএক্স-কমপ্লায়েন্ট সিস্টেমে এগুলি ব্যবহার করা উচিত।


আমি জানি এটি একটি খুব পুরানো উত্তর তবে আমার এটি বলা দরকার: এক্সেসকিউশন পরিচালনা করতে ট্রহেড ব্যবহার করার এটি একটি দুর্দান্ত উপায়। একমাত্র ক্ষতি হ'ল এটি পুরো প্রোগ্রামটির একটি অনুলিপি তৈরি করে। সুতরাং একটি কোকো অ্যাপ্লিকেশনের জন্য আমি একটি ভাল অ্যাপ্রোচের জন্য @ গর্ডন উইলসনের সাথে যাব এবং যদি আমি একটি কমান্ড লাইন অ্যাপ্লিকেশনটিতে কাজ করি তবে এটি করার সর্বোত্তম উপায়। ধন্যবাদ (দুঃখিত আমার খারাপ ইংরেজি)
নিকোস করালিস

11

এছাড়াও পুরাতন ভাল পসিক্স সিস্টেম রয়েছে ("প্রতিধ্বনিত '\ 007'");


6
এই আদেশ চালাবেন না। (যদি আপনি জানেন না এই কমান্ড আছে)
জাস্টিন

4
এটিকে কিছুটা নিরাপদ কিছুতে পরিবর্তন করা হয়েছে ... (এটি বিপস হয়)
nes1983

এটি কনসোলে কোনও ত্রুটি ফেলবে না? Incorrect NSStringEncoding value 0x0000 detected. Assuming NSStringEncodingASCII. Will stop this compatibility mapping behavior in the near future.
cwd

1
হুম। সম্ভবত আপনি ব্যাকস্ল্যাশ ডাবল পলায়ন করতে হবে।
nes1983

শুধু চালান / usr / বিন / প্রতিধ্বনি বা কিছু। আরএম-আরএফ কঠোর, এবং কনসোলে ইউনিকোড এখনও
চুষছে

8

আমি এই "সি" ফাংশনটি লিখেছি, কারণ NSTaskএটি অশোভন ..

NSString * runCommand(NSString* c) {

    NSString* outP; FILE *read_fp;  char buffer[BUFSIZ + 1];
    int chars_read; memset(buffer, '\0', sizeof(buffer));
    read_fp = popen(c.UTF8String, "r");
    if (read_fp != NULL) {
        chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
        if (chars_read > 0) outP = $UTF8(buffer);
        pclose(read_fp);
    }   
    return outP;
}

NSLog(@"%@", runCommand(@"ls -la /")); 

total 16751
drwxrwxr-x+ 60 root        wheel     2108 May 24 15:19 .
drwxrwxr-x+ 60 root        wheel     2108 May 24 15:19 ..

ওহ, এবং সম্পূর্ণ / দ্ব্যর্থহীন হওয়ার স্বার্থে ...

#define $UTF8(A) ((NSString*)[NSS stringWithUTF8String:A])

কয়েক বছর পর Cএখনও একটি বুদ্ধিভ্রংশজনক জগাখিচুড়ি আমার কাছে এসে গেছে .. এবং উপরে আমার স্থূল ভুলত্রুটি সংশোধন করার আমার ক্ষমতা একটু বিশ্বাস দিয়ে - শুধুমাত্র জলপাই শাখা আমি প্রস্তাব যে @ inket ব্যবস্থাপকের জবাবেরই একটা rezhuzhed সংস্করণ হাড় barest , আমার সহকর্মী জন্য বিশোধবাদী / শব্দচর্চা-বিদ্বেষী ...

id _system(id cmd) { 
   return !cmd ? nil : ({ NSPipe* pipe; NSTask * task;
  [task = NSTask.new setValuesForKeysWithDictionary: 
    @{ @"launchPath" : @"/bin/sh", 
        @"arguments" : @[@"-c", cmd],
   @"standardOutput" : pipe = NSPipe.pipe}]; [task launch];
  [NSString.alloc initWithData:
     pipe.fileHandleForReading.readDataToEndOfFile
                      encoding:NSUTF8StringEncoding]; });
}

1
আউটপিকে কোনও ত্রুটির উপর অপরিজ্ঞাত করা হয়েছে, যে কোনও আর্কিটেকচারে ফ্রেড () সাইজের (সাইজ_টি)! = সাইজ অফ (ইনট) এর রিটার্ন মানের জন্য অক্ষর_প্রেম খুব ছোট, যদি আমরা বুফএসআইজেড বাইটের চেয়ে বেশি আউটপুট চাই? আউটপুটটি ইউটিএফ -8 না হলে কী হবে? Pclose () যদি কোনও ত্রুটি ফেরায় তবে কী হবে? আমরা কীভাবে ফ্রেড () এর ত্রুটিটি প্রতিবেদন করব?
উদ্দেশ্য

@ অবজেক্টিভ সি-ওডার ডি'ও - আমি জানি না। দয়া করে, আমাকে বলুন (হিসাবে .. সম্পাদনা দূরে)!
অ্যালেক্স গ্রে

3

কাস্টোস মর্টেম বলেছেন:

আমি অবাক হয়েছি কেউই সত্যিই ব্লক / নন-ব্লকিং কল সম্পর্কিত সমস্যার মধ্যে পড়ে নি

NSTaskনীচের পড়া সম্পর্কিত ব্লক / অ-ব্লকিং কল সমস্যাগুলির জন্য :

asynctask.m - নমুনা কোড যা এনএসটিস্কের সাথে ডেটা প্রসেসিংয়ের জন্য অ্যাসিনক্রোনাস স্টিডিন, স্টাডআউট এবং স্টডার স্ট্রিমগুলি কীভাবে প্রয়োগ করতে পারে তা দেখায়

Asynctask.m সোর্স কোড পাওয়া যাবে GitHub


একটি অবরুদ্ধকরণ সংস্করণের জন্য আমার অবদান দেখুন
গুরুনিভার্সি

3

উপরের কয়েকটি দুর্দান্ত উত্তরের পাশাপাশি, আমি পটভূমিতে কমান্ডের আউটপুট প্রক্রিয়া করতে এবং এর অবরুদ্ধকরণ প্রক্রিয়াটি এড়াতে নিম্নলিখিত কোডটি ব্যবহার করি [file readDataToEndOfFile]

- (void)runCommand:(NSString *)commandToRun
{
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:@"/bin/sh"];

    NSArray *arguments = [NSArray arrayWithObjects:
                          @"-c" ,
                          [NSString stringWithFormat:@"%@", commandToRun],
                          nil];
    NSLog(@"run command:%@", commandToRun);
    [task setArguments:arguments];

    NSPipe *pipe = [NSPipe pipe];
    [task setStandardOutput:pipe];

    NSFileHandle *file = [pipe fileHandleForReading];

    [task launch];

    [self performSelectorInBackground:@selector(collectTaskOutput:) withObject:file];
}

- (void)collectTaskOutput:(NSFileHandle *)file
{
    NSData      *data;
    do
    {
        data = [file availableData];
        NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] );

    } while ([data length] > 0); // [file availableData] Returns empty data when the pipe was closed

    // Task has stopped
    [file closeFile];
}

আমার জন্য যে লাইনটি সমস্ত পার্থক্য তৈরি করেছিল তা হ'ল [সেল্ফ পারফর্মসিলেটরআইনব্যাকগ্রাউন্ড: @ সিলেক্টর (কালেক্টটাস্ক আউটপুট :) উইজেক্ট: ফাইল];
নিউউইনস্টন

2

বা অবজেক্টিভ সি যেহেতু উপরের কয়েকটি ওও স্তর সহ কেবল সি হয় আপনি পিক্সিক্স সংযুক্তিগুলি ব্যবহার করতে পারেন:

int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);
int execlpe(const char *file, const char *arg0, ..., const char *argn, (char *)0, char *const envp[]);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]); 

তারা unistd.h শিরোনাম ফাইল থেকে অন্তর্ভুক্ত করা হয়েছে।


2

যদি টার্মিনাল কমান্ডের জন্য প্রশাসক প্রিভিলেজ (ওরফে sudo) প্রয়োজন হয়, AuthorizationExecuteWithPrivilegesপরিবর্তে ব্যবহার করুন instead নিম্নলিখিতটি "com.stackoverflow.test" নামে একটি ফাইল তৈরি করবে মূল ডিরেক্টরি "/ সিস্টেম / গ্রন্থাগার / ক্যাশে"।

AuthorizationRef authorizationRef;
FILE *pipe = NULL;
OSStatus err = AuthorizationCreate(nil,
                                   kAuthorizationEmptyEnvironment,
                                   kAuthorizationFlagDefaults,
                                   &authorizationRef);

char *command= "/usr/bin/touch";
char *args[] = {"/System/Library/Caches/com.stackoverflow.test", nil};

err = AuthorizationExecuteWithPrivileges(authorizationRef,
                                         command,
                                         kAuthorizationFlagDefaults,
                                         args,
                                         &pipe); 

4
এটি ওএস এক্স 10.7
স্যাম ওয়াশবার্ন

2
.. তবে এটি নির্বিশেষে কাজ করে চলেছে, কারণ এটি করার একমাত্র উপায়, এবং অনেক ইনস্টলার তাদের উপর নির্ভর করে, আমি বিশ্বাস করি।
টমাস টেম্পেলম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.