Bagaimana saya bisa menjalankan perintah terminal (seperti grep
) dari aplikasi Kakao Objective-C saya?
objective-c
cocoa
macos
hilangInTransit
sumber
sumber
/usr/bin
tempatgrep
tinggal.Jawaban:
Anda bisa menggunakannya
NSTask
. Berikut ini contoh yang akan dijalankan '/usr/bin/grep foo bar.txt
'.NSPipe
danNSFileHandle
digunakan untuk mengarahkan output standar dari tugas tersebut.Untuk informasi lebih rinci tentang interaksi dengan sistem operasi dari dalam aplikasi Objective-C Anda, Anda dapat melihat dokumen ini di Pusat Pengembangan Apple: Berinteraksi dengan Sistem Operasi .
Sunting: Termasuk perbaikan untuk masalah NSLog
Jika Anda menggunakan NSTask untuk menjalankan utilitas baris perintah melalui bash, maka Anda perlu menyertakan jalur ajaib ini agar NSLog berfungsi:
Penjelasannya ada di sini: https://web.archive.org/web/20141121094204/https://cocoadev.com/HowToPipeCommandsWithNSTask
sumber
NSMutableData *data = [NSMutableData dataWithCapacity:512];
. Laluwhile ([task isRunning]) { [data appendData:[file readDataToEndOfFile]]; }
,. Dan saya "percaya" Anda harus memiliki satu lagi[data appendData:[file readDataToEndOfFile]];
setelah loop sementara keluar.task.standardError = pipe;
Artikel kent memberi saya ide baru. Metode runCommand ini tidak memerlukan file skrip, cukup jalankan perintah dengan satu baris:
Anda dapat menggunakan metode ini seperti ini:
sumber
dalam semangat berbagi ... ini adalah metode yang sering saya gunakan untuk menjalankan skrip shell. Anda dapat menambahkan skrip ke bundel produk Anda (dalam fase salin build) dan kemudian meminta skrip dibaca dan dijalankan pada saat runtime. catatan: kode ini mencari skrip di sub-jalur privateFrameworks. peringatan: ini bisa menjadi risiko keamanan untuk produk yang digunakan, tetapi untuk pengembangan in-house kami, ini adalah cara mudah untuk menyesuaikan hal-hal sederhana (seperti host mana untuk rsync ke ...) tanpa mengkompilasi ulang aplikasi, tetapi hanya mengedit skrip shell dalam bundel.
Sunting: Termasuk perbaikan untuk masalah NSLog
Jika Anda menggunakan NSTask untuk menjalankan utilitas baris perintah melalui bash, maka Anda perlu menyertakan jalur ajaib ini agar NSLog berfungsi:
Dalam konteks:
Penjelasannya ada di sini: http://www.cocoadev.com/index.pl?NSTask
sumber
Inilah cara melakukannya di Swift
Ini didasarkan pada jawaban Objectit-C di atas. Dia menulisnya sebagai kategori di
NSString
- Untuk Swift, itu menjadi perpanjangan dariString
.ekstensi String.runAsCommand () -> String
Pemakaian:
atau hanya:
Contoh:
Perhatikan
Process
hasil sebagai membaca dariPipe
sebuahNSString
objek. Mungkin string kesalahan dan juga bisa berupa string kosong, tetapi harus selalu berupaNSString
.Jadi, selama tidak nihil, hasilnya bisa berubah menjadi Swift
String
dan dikembalikan.Jika karena alasan tertentu tidak ada
NSString
sama sekali dapat diinisialisasi dari data file, fungsi mengembalikan pesan kesalahan. Fungsi itu bisa saja ditulis untuk mengembalikan opsionalString?
, tetapi itu akan menjadi canggung untuk digunakan dan tidak akan melayani tujuan yang bermanfaat karena sangat tidak mungkin hal ini terjadi.sumber
Objective-C (lihat di bawah untuk Swift)
Membersihkan kode di jawaban atas untuk membuatnya lebih mudah dibaca, kurang berlebihan, menambahkan manfaat dari metode satu baris dan dibuat menjadi kategori NSString
Penerapan:
Pemakaian:
Dan jika Anda mengalami masalah dengan pengkodean keluaran:
Semoga bermanfaat bagi Anda dan masa depan saya. (Hai kamu!)
Cepat 4
Berikut adalah Swift contoh pembuatan penggunaan
Pipe
,Process
danString
Pemakaian:
sumber
fork , exec , dan wait harus berfungsi, jika Anda tidak benar-benar mencari cara spesifik Objective-C.
fork
membuat salinan dari program yang sedang berjalan,exec
menggantikan program yang sedang berjalan dengan yang baru, danwait
menunggu subproses untuk keluar. Misalnya (tanpa memeriksa kesalahan):Ada juga sistem , yang menjalankan perintah seolah-olah Anda mengetiknya dari baris perintah shell. Ini lebih sederhana, tetapi Anda memiliki sedikit kendali atas situasi.
Saya berasumsi Anda sedang mengerjakan aplikasi Mac, jadi tautannya adalah ke dokumentasi Apple untuk fungsi-fungsi ini, tetapi semuanya
POSIX
, jadi Anda harus menggunakannya pada sistem yang mendukung POSIX.sumber
Ada juga sistem POSIX lama yang bagus ("echo -en '\ 007'");
sumber
Incorrect NSStringEncoding value 0x0000 detected. Assuming NSStringEncodingASCII. Will stop this compatibility mapping behavior in the near future.
Saya menulis fungsi "C" ini, karena
NSTask
menjengkelkan ..oh, dan demi menjadi lengkap / tidak ambigu ...
Bertahun-tahun kemudian,
C
masih menjadi kekacauan yang membingungkan, bagi saya .. dan dengan sedikit kepercayaan pada kemampuan saya untuk memperbaiki kekurangan kotor saya di atas - satu-satunya cabang zaitun yang saya tawarkan adalah versi rezhuzhed dari jawaban @ inket yang paling sederhana tulangnya , untuk rekan saya purists / pembenci verbositas ...sumber
Custos Mortem berkata:
Untuk masalah pemblokiran / non-pemblokiran terkait
NSTask
membaca di bawah ini:Kode sumber asynctask.m tersedia di GitHub .
sumber
Selain beberapa jawaban yang sangat baik di atas, saya menggunakan kode berikut untuk memproses output dari perintah di latar belakang dan menghindari mekanisme pemblokiran
[file readDataToEndOfFile]
.sumber
Atau karena Objective C hanya C dengan beberapa layer OO di atas Anda dapat menggunakan posix conterparts:
Mereka disertakan dari file header unistd.h.
sumber
Jika perintah Terminal membutuhkan Administrator Privilege (alias
sudo
), gunakanAuthorizationExecuteWithPrivileges
saja. Berikut ini akan membuat file bernama "com.stackoverflow.test" adalah direktori root "/ System / Library / Caches".sumber