シェルスクリプトObjective-Cから結果を取得する
-
08-07-2019 - |
質問
ファイルまたはObjective-C文字列(コード内)からシェルスクリプトを実行したいと思います。また、シェルスクリプトの結果を変数に保存したいと思います。シェルスクリプトを引数に分割したくない(実行時のsetLaunchPathなど)。例:このシェルスクリプトの実行" mount_webdav idisk.mac.com/mac_username / Volumes / mac_username" " / bin / mount_webdav"の代わりに次に引数。とにかくこれを行うにはありますか?現在NSTaskを使用していますが、引数を付けようとするとエラーが発生します。提示されたコードは次のとおりです。
(。mファイルの一部)
NSString *doshellscript(NSString *cmd_launch_path, NSString *first_cmd_pt) {
NSTask *task = [[NSTask alloc] init]; // Make a new task
[task setLaunchPath: cmd_launch_path]; // Tell which command we are running
[task setArguments: [NSArray arrayWithObjects: first_cmd_pt, nil]];
[task setArguments: first_cmd_pt];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
[task launch];
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
[task release]; //Release the task into the world, thus destroying it.
return string;
}
NSString *mount_idisk(NSString *mac_username) {
doshellscript(@"/bin/mkdir", [@"/Volumes/" stringByAppendingString:mac_username]);
NSString *path_tmp = [mac_username stringByAppendingString: @"/ /Volumes/"];
NSString *idisk_path = [path_tmp stringByAppendingString:mac_username];
//NSLog(@"%@", [@" http://idisk.mac.com/" stringByAppendingString: idisk_path]);
NSString *finished_path = [@"http://idisk.mac.com/" stringByAppendingString: idisk_path];
doshellscript(@"/sbin/mount_webdav", finished_path);
}
... これが、実行に使用している行です。 <コード> mount_idisk(&quot; username&quot;);
解決
NSTaskにコマンドライン全体を渡す方法はありません。
正当な理由のため。何らかの文字列の構成が行われている場合、これを行うとセキュリティホールが発生します。文字列構成コードは、シェルコマンドラインを解析するすべてのルールを完全に認識している必要があり、任意のコマンド実行につながる可能性のあるすべての文字の組み合わせをエスケープする必要があります。
system()
C APIを使用すると、任意のコマンドを実行できますが、出力を直接キャプチャするメカニズムはありません。コマンドラインに何かを追加して、後で読み込む一時ファイルに出力を出力するのは簡単ですが、そうすると、コマンドライン全体を単一の文字列として渡すだけでなく、さらにセキュリティホールが追加されます。
待機...簡単なバグがあるようです:
[task setArguments: [NSArray arrayWithObjects: first_cmd_pt, nil]];
[task setArguments: first_cmd_pt];
タスクの引数を設定してから再設定するのはなぜですか?
mount_idisk()
関数が個々の引数を効果的に構成し、それらを1つの文字列に連結することを考えると、すべての引数を NSArray
に単純に詰め込まないでください。 doshellscript()
を変更して、2番目のパラメーターとして配列を取得します。引数の配列?
引数の配列を正しく作成していません。
名前:
NSArray *finished_path = [NSArray arrayWithObjects:@"http://idisk.mac.com/", mac_username, @"/ /Volumes/", mac_username, nil];
この行は、必要な2つの引数ではなく、 doshellscript()
関数で4つの個別の引数として扱われる4つのオブジェクトを含む配列を作成しています。
たぶん次のようなもの:
NSString *mobileMeUserURL = [@"http://idisk.mac.com/" stringByAppendingString: mac_username];
NSString *localMountPath = [ @"/ /Volumes/" stringByAppendingString: mac_username];
NSArray *arguments = [NSArray arrayWithObjects: mobileMeUserURL, localMountPath, nil];