POSIX 명령을 Objective-C에서 사용하려고 시도 착오했다.
16065 단어 MacOSXPOSIXNSTaskObjective-C
개요
이번에는 예로서 POSIX 명령의 chflags
를 사용하여 아래 폴더의 파일을 숨겨진 파일로 만드는 것을 생각해 보자.
chflags 통행은 /usr/bin/chflags
이다.
명령
설명
chflags hidden <파일 이름>
숨겨진 속성 부여
chflags nohidden <파일 이름>
숨겨진 속성을 취하다
터미널에서 전화하는 방법은 다음과 같습니다. ( ~
에 자신의 환경 경로를 삽입)
터미널에서 실행 예chflags hidden ~/Downloads/instance/SampleFolder/sample.txt
구현
이것과 같은 Objective-C의 코드로, NSTask를 사용해 실행한다.
호출부NSString *sampleFilePathWithTilde = @"~/Downloads/instance/SampleFolder/sample.txt";
NSString *sampleFilePath = [sampleFilePathWithTilde stringByExpandingTildeInPath];
NSURL *chflags = [NSURL fileURLWithPath:@"/usr/bin/chflags"];
[self executeSelectCommand:chflags args:@[@"hidden", sampleFilePath]];
함수 부분/**
@brief POSIXコマンドのパスとオプションを格納した配列を渡して実行する
@param commandURL POSIXコマンドのパス args 引数
@return 正常終了でYES
*/
- (BOOL)executeSelectCommand:(NSURL *)commandURL args:(NSArray *)args {
// タスクオブジェクトを準備する
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:[commandURL path]];
[task setArguments:args];
// 読み込み元のパイプを作成する
NSPipe *outPipe = [[NSPipe alloc] init];
[task setStandardOutput:outPipe];
// プロセスを起動する
[task launch];
// タスクが正常に終了することを確認する
[task waitUntilExit];
int status = [task terminationStatus];
// ステータスを確認する
if (status != 0) {
return NO;
}
return YES;
}
실행 후, 숨겨진 속성이 되어 있는 것을 확인.
위 코드 개선
SampleFolder
내의 파일을 모두 숨겨진 속성으로 하려고 한다.
터미널에서 전화하는 방법은 다음과 같습니다. ( ~
에 자신의 환경 경로를 삽입)
터미널에서 실행 예chflags hidden ~/Downloads/instance/SampleFolder/*
그러나 같은 것을 상기의 코드로 행하려고 하면, 와일드 카드인 「*」를 전개할 수 없다고 하는 불편이 생긴다.
[self executeSelectCommand:chflags args:@[@"hidden", @"*"]];
로그chflags: *: No such file or directory
디렉토리를 찾을 수 없다는 오류.
「*」를 전개할 수 없는 것 같다.
문제에 대해 자세히 알아보기
chflags hidden ~/Downloads/instance/SampleFolder/sample.txt
이것과 같은 Objective-C의 코드로, NSTask를 사용해 실행한다.
호출부
NSString *sampleFilePathWithTilde = @"~/Downloads/instance/SampleFolder/sample.txt";
NSString *sampleFilePath = [sampleFilePathWithTilde stringByExpandingTildeInPath];
NSURL *chflags = [NSURL fileURLWithPath:@"/usr/bin/chflags"];
[self executeSelectCommand:chflags args:@[@"hidden", sampleFilePath]];
함수 부분
/**
@brief POSIXコマンドのパスとオプションを格納した配列を渡して実行する
@param commandURL POSIXコマンドのパス args 引数
@return 正常終了でYES
*/
- (BOOL)executeSelectCommand:(NSURL *)commandURL args:(NSArray *)args {
// タスクオブジェクトを準備する
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:[commandURL path]];
[task setArguments:args];
// 読み込み元のパイプを作成する
NSPipe *outPipe = [[NSPipe alloc] init];
[task setStandardOutput:outPipe];
// プロセスを起動する
[task launch];
// タスクが正常に終了することを確認する
[task waitUntilExit];
int status = [task terminationStatus];
// ステータスを確認する
if (status != 0) {
return NO;
}
return YES;
}
실행 후, 숨겨진 속성이 되어 있는 것을 확인.
위 코드 개선
SampleFolder
내의 파일을 모두 숨겨진 속성으로 하려고 한다.
터미널에서 전화하는 방법은 다음과 같습니다. ( ~
에 자신의 환경 경로를 삽입)
터미널에서 실행 예chflags hidden ~/Downloads/instance/SampleFolder/*
그러나 같은 것을 상기의 코드로 행하려고 하면, 와일드 카드인 「*」를 전개할 수 없다고 하는 불편이 생긴다.
[self executeSelectCommand:chflags args:@[@"hidden", @"*"]];
로그chflags: *: No such file or directory
디렉토리를 찾을 수 없다는 오류.
「*」를 전개할 수 없는 것 같다.
문제에 대해 자세히 알아보기
chflags hidden ~/Downloads/instance/SampleFolder/*
[self executeSelectCommand:chflags args:@[@"hidden", @"*"]];
chflags: *: No such file or directory
NSTask doesn't expand the * in your path. But if you invoke the command through the shell (i.e./bin/bash), it will:
- NSTask에서 외부 명령을 실행할 때 "/bin/sh -c"를 통과하면 행복합니다.
NSTask에서 외부 명령을 실행하는 경우 외부 명령을 전체 경로로 지정해야 한다. 머신 환경에 따라 커맨드는 머신에 의해 "/opt/local/bin"이거나 "/usr/local/bin"이기 때문에, 풀 패스로 커멘드를 지정하면 움직이지 않기 때문에, "/bin/sh -c"를 통해 명령의 실행 경로를 해결하면 행복하게 될 것 같습니다.
NSArray
에서 NSString
로 했다. cd
그리고 현재 경로를 변경하는 것과 동의어. 개선 후 구현
호출부NSString *sampleFolderPathWithTilde = @"~/Downloads/instance/SampleFolder";
NSString *sampleFolderPath = [sampleFolderPathWithTilde stringByExpandingTildeInPath];
NSURL *sampleFolderURL = [NSURL fileURLWithPath:sampleFolderPath];
[self executePosixThroughBashWithStatement:@"chflags hidden *" posixExecutingURL:sampleFolderURL];
함수 부분/**
@brief Shellを通じてPosixコマンドを実行する(*を展開するために用意)
@param statement 引数の文字列 ex.@"chflags hidden *"
@param aCurrentDirectory Posixコマンドの実行上のパス(空文字可)
@return BOOL Posix実行正常終了でYES
*/
- (BOOL)executePosixThroughBashWithStatement:(NSString *)statement posixExecutingURL:(NSURL *)aCurrentDirectory {
NSArray *args = @[@"-c", statement];
// タスクオブジェクトを準備する
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/bin/sh"; // ワイルドカードを展開するためbashを経由する
task.arguments = args;
// 読み込み元のパイプを作成する
NSPipe *pOutput = [NSPipe pipe]; // 標準出力先
NSPipe *pError = [NSPipe pipe]; // エラー出力先
task.standardOutput = pOutput;
task.standardError = pError;
if (aCurrentDirectory.path.length != 0) {
task.currentDirectoryURL = aCurrentDirectory;
}
// プロセスを起動する
[task launch];
// タスクが正常に終了することを確認する
[task waitUntilExit];
NSData *dataError = [[pError fileHandleForReading] availableData]; //エラーのデータ
if (dataError.length != 0) {
NSLog(@"error-%s", [dataError bytes]); //エラー出力
}
NSData *dataOutput = [[pOutput fileHandleForReading] availableData]; //標準出力データ
NSString *stringOutput = [[NSString alloc] initWithData:dataOutput encoding:NSShiftJISStringEncoding]; //標準出力
if (stringOutput.length != 0) {
NSLog(@"\n*** UnixOutput ***\n%@", stringOutput);
}
// ステータスを確認する
if ([task terminationStatus] != 0) {
return NO;
}
return YES;
}
모두 숨겨진 속성이 되어 있는 것을 확인.
첫 번째 인수이지만 arguments
의 요소를 소분으로 하면 잘 가지 않았으므로 NSString
로 다시 작성했다.
NSArray *args = @[@"-c", @"chflags hidden *"];
아래 코드에서 실행했는데 오류가 발생했습니다. (처음의 예에서는 잘 가고 있었지만 왜일까)
NSArray *args = @[@"-c", @"chflags", @"hidden", @"*"];
오류 로그error-usage: chflags [-fhv] [-R [-H | -L | -P]] flags file ...
G…
여담:로그에의 아웃풋등은 반환값으로 하거나 하는 편이, 디버그하기 쉬울지도 모른다고 생각한다.
Reference
이 문제에 관하여(POSIX 명령을 Objective-C에서 사용하려고 시도 착오했다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/IKEH/items/31d5344879cd945e216a
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
NSString *sampleFolderPathWithTilde = @"~/Downloads/instance/SampleFolder";
NSString *sampleFolderPath = [sampleFolderPathWithTilde stringByExpandingTildeInPath];
NSURL *sampleFolderURL = [NSURL fileURLWithPath:sampleFolderPath];
[self executePosixThroughBashWithStatement:@"chflags hidden *" posixExecutingURL:sampleFolderURL];
/**
@brief Shellを通じてPosixコマンドを実行する(*を展開するために用意)
@param statement 引数の文字列 ex.@"chflags hidden *"
@param aCurrentDirectory Posixコマンドの実行上のパス(空文字可)
@return BOOL Posix実行正常終了でYES
*/
- (BOOL)executePosixThroughBashWithStatement:(NSString *)statement posixExecutingURL:(NSURL *)aCurrentDirectory {
NSArray *args = @[@"-c", statement];
// タスクオブジェクトを準備する
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/bin/sh"; // ワイルドカードを展開するためbashを経由する
task.arguments = args;
// 読み込み元のパイプを作成する
NSPipe *pOutput = [NSPipe pipe]; // 標準出力先
NSPipe *pError = [NSPipe pipe]; // エラー出力先
task.standardOutput = pOutput;
task.standardError = pError;
if (aCurrentDirectory.path.length != 0) {
task.currentDirectoryURL = aCurrentDirectory;
}
// プロセスを起動する
[task launch];
// タスクが正常に終了することを確認する
[task waitUntilExit];
NSData *dataError = [[pError fileHandleForReading] availableData]; //エラーのデータ
if (dataError.length != 0) {
NSLog(@"error-%s", [dataError bytes]); //エラー出力
}
NSData *dataOutput = [[pOutput fileHandleForReading] availableData]; //標準出力データ
NSString *stringOutput = [[NSString alloc] initWithData:dataOutput encoding:NSShiftJISStringEncoding]; //標準出力
if (stringOutput.length != 0) {
NSLog(@"\n*** UnixOutput ***\n%@", stringOutput);
}
// ステータスを確認する
if ([task terminationStatus] != 0) {
return NO;
}
return YES;
}
NSArray *args = @[@"-c", @"chflags hidden *"];
NSArray *args = @[@"-c", @"chflags", @"hidden", @"*"];
error-usage: chflags [-fhv] [-R [-H | -L | -P]] flags file ...
G…
Reference
이 문제에 관하여(POSIX 명령을 Objective-C에서 사용하려고 시도 착오했다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/IKEH/items/31d5344879cd945e216a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)